w3cam-0.7.2/0040755000076400000620000000000007412662333011374 5ustar rascauserw3cam-0.7.2/configure.in0100644000076400000620000000213507366314420013702 0ustar rascauserAC_INIT() AC_ISC_POSIX LDFLAGS="$LDFLAGS -L/usr/local/lib -L/usr/local/X11/lib" CFLAGS="$CFLAGS -I/usr/local/include" AC_CHECK_LIB(m, pow) AC_CHECK_LIB(z, gzopen) AC_CHECK_LIB(png, png_create_write_struct) AC_CHECK_LIB(jpeg, jpeg_set_defaults) AC_MSG_CHECKING(--with-syslog=?) AC_ARG_WITH(syslog, [ --with-syslog use syslog [default=no]], [ac_syslog=$withval], [ac_syslog=no] ) if test "$ac_syslog" = "yes" ; then CFLAGS="$CFLAGS -DUSE_SYSLOG" else ac_syslog=no fi AC_MSG_RESULT($ac_syslog) AC_MSG_CHECKING(--with-device=?) AC_ARG_WITH(device, [ --with-device= video4linux device [default=/dev/video]], [ac_device=$withval], [ac_device=/dev/video] ) AC_MSG_RESULT($ac_device) if ! test -c $ac_device; then echo "** Warning: can't see '$ac_device'" fi AC_MSG_CHECKING(--with-ttf-inc=?) AC_ARG_WITH(ttf-inc, [ --with-ttf-inc= include directory for the freetype headers], [ac_ttf=$withval], [ac_ttf=/usr/local/X11/include] ) AC_MSG_RESULT($ac_ttf) CFLAGS="$CFLAGS -I$ac_ttf" AC_CHECK_LIB(ttf, TT_Init_FreeType) AC_SUBST(ac_device) AC_OUTPUT( Makefile w3camd/Makefile ) w3cam-0.7.2/configure0100755000076400000620000012137507366314421013311 0ustar rascauser#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.13 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help --with-syslog use syslog [default=no]" ac_help="$ac_help --with-device= video4linux device [default=/dev/video]" ac_help="$ac_help --with-ttf-inc= include directory for the freetype headers" # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= 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=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -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 ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$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" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac 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) # 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 << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --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 EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$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" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) 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) 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" ;; -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 ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.13" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi 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 "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # 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 # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set these to C if already set. These must not be set unconditionally # because not all systems understand e.g. LANG=C (notably SCO). # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file= # 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 its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. 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 if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done if test -r "$cache_file"; then echo "loading cache $cache_file" . $cache_file else echo "creating cache $cache_file" > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross ac_exeext= ac_objext=o 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 # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:534: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 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 $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:564: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" break fi done IFS="$ac_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 $# -gt 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 set dummy "$ac_dir/$ac_word" "$@" shift ac_cv_prog_CC="$@" fi fi fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then case "`uname -s`" in *win32* | *WIN32*) # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:615: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="cl" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi ;; esac fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:647: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF #line 658 "configure" #include "confdefs.h" main(){return(0);} EOF if { (eval echo configure:663: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cc_cross=no else ac_cv_prog_cc_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cc_works=no fi rm -fr conftest* ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo "configure:689: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo "configure:694: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes else GCC= fi ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo "configure:722: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_cc_g=yes else ac_cv_prog_cc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&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 $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6 echo "configure:754: checking for POSIXized ISC" >&5 if test -d /etc/conf/kconfig.d && grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 then echo "$ac_t""yes" 1>&6 ISC=yes # If later tests want to check for ISC. cat >> confdefs.h <<\EOF #define _POSIX_SOURCE 1 EOF if test "$GCC" = yes; then CC="$CC -posix" else CC="$CC -Xp" fi else echo "$ac_t""no" 1>&6 ISC= fi LDFLAGS="$LDFLAGS -L/usr/local/lib -L/usr/local/X11/lib" CFLAGS="$CFLAGS -I/usr/local/include" echo $ac_n "checking for pow in -lm""... $ac_c" 1>&6 echo "configure:779: checking for pow in -lm" >&5 ac_lib_var=`echo m'_'pow | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo m | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 fi echo $ac_n "checking for gzopen in -lz""... $ac_c" 1>&6 echo "configure:826: checking for gzopen in -lz" >&5 ac_lib_var=`echo z'_'gzopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lz $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo z | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 fi echo $ac_n "checking for png_create_write_struct in -lpng""... $ac_c" 1>&6 echo "configure:873: checking for png_create_write_struct in -lpng" >&5 ac_lib_var=`echo png'_'png_create_write_struct | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lpng $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo png | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 fi echo $ac_n "checking for jpeg_set_defaults in -ljpeg""... $ac_c" 1>&6 echo "configure:920: checking for jpeg_set_defaults in -ljpeg" >&5 ac_lib_var=`echo jpeg'_'jpeg_set_defaults | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ljpeg $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo jpeg | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 fi echo $ac_n "checking --with-syslog=?""... $ac_c" 1>&6 echo "configure:968: checking --with-syslog=?" >&5 # Check whether --with-syslog or --without-syslog was given. if test "${with_syslog+set}" = set; then withval="$with_syslog" ac_syslog=$withval else ac_syslog=no fi if test "$ac_syslog" = "yes" ; then CFLAGS="$CFLAGS -DUSE_SYSLOG" else ac_syslog=no fi echo "$ac_t""$ac_syslog" 1>&6 echo $ac_n "checking --with-device=?""... $ac_c" 1>&6 echo "configure:986: checking --with-device=?" >&5 # Check whether --with-device or --without-device was given. if test "${with_device+set}" = set; then withval="$with_device" ac_device=$withval else ac_device=/dev/video fi echo "$ac_t""$ac_device" 1>&6 if ! test -c $ac_device; then echo "** Warning: can't see '$ac_device'" fi echo $ac_n "checking --with-ttf-inc=?""... $ac_c" 1>&6 echo "configure:1002: checking --with-ttf-inc=?" >&5 # Check whether --with-ttf-inc or --without-ttf-inc was given. if test "${with_ttf_inc+set}" = set; then withval="$with_ttf_inc" ac_ttf=$withval else ac_ttf=/usr/local/X11/include fi echo "$ac_t""$ac_ttf" 1>&6 CFLAGS="$CFLAGS -I$ac_ttf" echo $ac_n "checking for TT_Init_FreeType in -lttf""... $ac_c" 1>&6 echo "configure:1015: checking for TT_Init_FreeType in -lttf" >&5 ac_lib_var=`echo ttf'_'TT_Init_FreeType | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lttf $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo ttf | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 fi 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 trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. cat > conftest.defs <<\EOF s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g s%\[%\\&%g s%\]%\\&%g s%\$%$$%g EOF DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` rm -f conftest.defs # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS </dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.13" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir trap 'rm -fr `echo "Makefile w3camd/Makefile " | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@SHELL@%$SHELL%g s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@FFLAGS@%$FFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@CC@%$CC%g s%@ac_device@%$ac_device%g CEOF EOF cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 w3cam-0.7.2/Makefile.in0100644000076400000620000000234507366755012013447 0ustar rascauserCC = @CC@ prefix=@prefix@ exec_prefix=@exec_prefix@ sbindir=@sbindir@ cgibindir=$(prefix)/cgi-bin bindir=@bindir@ VERSION=0.7.2 CFLAGS = @CFLAGS@ @DEFS@ -DVIDEO_DEV=\"@ac_device@\" -DVERSION=\"$(VERSION)\" LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ OBJ = w3cam.o cgi.o v4l.o default: w3cam.cgi vidcat vidcat.1 README ppmtoascii w3camd/w3camd w3cam.cgi: $(OBJ) $(CC) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) vidcat: vidcat.o v4l.o $(CC) $(LDFLAGS) -o $@ vidcat.o v4l.o $(LIBS) ppmtoascii: ppmtoascii.o $(CC) $(LDFLAGS) -o $@ ppmtoascii.o w3camd/w3camd: cd w3camd && make install: w3cam.cgi install w3cam.cgi $(cgibindir)/ test -f $(cgibindir)/w3cam.cgi.scf || \ install w3cam.cgi.scf $(cgibindir)/ install vidcat $(bindir)/ install vidcat.1 $(prefix)/man/man1/ vidcat.1: vidcat.man sed "s/VERSION/$(VERSION)/" < vidcat.man > vidcat.1 clean: rm -f *.o w3cam.cgi vidcat ppmtoascii cd w3camd && make clean && rm -f w3camd msproper: clean rm -f config.status config.log config.cache Makefile index.html: index.in sed "s/@VERSION@/$(VERSION)/" < $< > $@ README: index.html lynx -dump http://www/~rasca/w3cam/index.html | \ sed "s%/www/%/home.pages.de/%g" > README tarball: msproper cd .. && tar -czvf w3cam-$(VERSION).tar.gz w3cam-$(VERSION)/ w3cam-0.7.2/w3cam.c0100644000076400000620000006176107412656673012574 0ustar rascauser/* * w3cam.c * * Copyright (C) 1998 - 2001 Rasca, Berlin * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #ifdef USE_SYSLOG #include #endif #if defined __GLIBC__ && __GLIBC__ >= 2 #include /* basename */ #endif #include #include #include #include #include #include #include #include #ifdef HAVE_LIBZ #include #endif #ifdef HAVE_LIBPNG #include #endif #ifdef HAVE_LIBJPEG #include #endif #ifdef HAVE_LIBTTF #include #endif #include "w3cam.h" #include "cgi.h" #include "v4l.h" /* * some default values, change these to fit your needs * most of these could be changed at runtime with config file */ #define FMT_DEFAULT FMT_JPEG /* FMT_PPM, FMT_JPEG, FMT_PNG */ #define QUALITY_DEFAULT 65 /* JPEG default quality */ #define WIDTH_DEFAULT 240 /* default width and height of the image */ #define HEIGHT_DEFAULT 180 #define MODE_DEFAULT MODE_PLAIN /* MODE_GUI or MODE_PLAIN */ #define USEC_DEFAULT 20000 /* wait microseconds before capturing */ #define REFRESH_DEFAULT OFF /* don't use refreshing */ #define MIN_REFRESH 0.0 /* min refresh time, compile time option */ #define FREQLIST_DEFAULT "878;9076;9844;9460" /* default frequenzies */ #define MAX_TRY_OPEN 20 /* may be the device is locked, so try max*/ /* end of default values * ********************* */ /* */ void usage (char *pname, int width, int height, int color, int quality, int usec) { cgi_response (http_bad_request, "text/html"); printf ( "w3cam - help
W3Cam, Version %s\n\n"
	"Usage: %s\n"
	"CGI parameters (GET or POST):\n"
	" help                                    show this page\n"
	" size=#x#                                geometry of picture "
		"[default = %dx%d]\n"
	" color={0|1}                             color or grey mode "
		"[default = %d]\n"
	" input={tv|composite|composite2|s-video} define input source\n"
	" quality={1-100}                         jpeg quality "
		"[default = %d]\n"
	" format={ppm|png|jpeg}                   output format\n"
	" freq=#                                  define frequenzy for TV\n"
	" usleep=#                                sleep # micro secs before cap. "
		"[default = %d]\n"
	" mode=[gui|html]                         build a page with panel or plain html\n"
	" refresh=#.#                             time in sec to refresh gui\n"
	" norm={pal|ntsc|secam}                   tv norm\n"
	" bgr={1|0}                               swap RGB to BGR (default: no)\n",
	VERSION, basename(pname), width, height, color, quality, usec);
	printf (
	"\nCompiled in features:\n");
#ifdef HAVE_LIBPNG
	printf (" PNG file format\n");
#endif
#ifdef HAVE_LIBJPEG
	printf (" JPEG file format\n");
#endif
#ifdef HAVE_LIBTTF
	printf ( " TTF/TimeStamp\n");
#endif
#ifdef USE_SYSLOG
	printf ( " SYSLOG support\n");
#endif
	exit (0);
}

/*
 */
void
log (char *info)
{
#ifdef USE_SYSLOG
	syslog (LOG_USER, "%s\n", info);
#else
	fprintf (stderr, "%s\n", info);
#endif
}

/*
 */
void
log2 (char *s1, char *s2)
{
#ifdef USE_SYSLOG
	syslog (LOG_USER, "%s %s\n", s1, s2);
#else
	fprintf (stderr, "%s %s\n", s1, s2);
#endif
}

/*
 * parse comma seperated frequency list
 */
char **
parse_list (char *freqs)
{
	char **flist = NULL;
	char *p = freqs, *end = NULL;
	int num = 0, i, len;

	if (!freqs)
		return (NULL);
	while ((p = strchr(p, ';')) != NULL) {
		p++;
		num++;
	}
	num++;
	flist = malloc ((num + 1) * sizeof (char *));
	flist[num] = NULL;
	p = freqs;
	for (i = 0; i < num; i++) {
		if (i == (num-1)) {
			/* last element */
			len = strlen (p);
		} else {
			end = strchr(p, ';');
			len = end - p;
		}
		flist[i] = malloc (len+1);
		strncpy (flist[i], p, len);
		p = end+1;
	}
	return (flist);
}

/*
 * read rgb image from v4l device
 * return: new allocated buffer
 */
unsigned char *
get_image (int dev, int width, int height, int input, int usec,
			unsigned long freq, int palette)
{
	struct video_mbuf vid_buf;
	struct video_mmap vid_mmap;
	char *map;
	unsigned char *buff;
	int size, len, bpp;
	register int i;

	if (input == IN_TV) {
		if (freq > 0) {
			if (ioctl (dev, VIDIOCSFREQ, &freq) == -1)
				log2 ("ioctl (VIDIOCSREQ):", strerror(errno));
		}
	}

	/* it seems some cards need a little bit time to come in
		sync with the new settings */
	if (usec)
		usleep (usec);

	if (palette != VIDEO_PALETTE_GREY) {
		/* RGB or YUV */
		size = width * height * 3;
		bpp = 3;
	} else {
		size = width * height * 1;
		bpp = 1;
	}
	vid_mmap.format = palette;

	if (ioctl (dev, VIDIOCGMBUF, &vid_buf) == -1) {
		/* do a normal read()
		 */
		struct video_window vid_win;

		if (ioctl (dev, VIDIOCGWIN, &vid_win) != -1) {
			vid_win.width  = width;
			vid_win.height = height;
			if (ioctl (dev, VIDIOCSWIN, &vid_win) == -1) {
				log2 ("ioctl(VIDIOCSWIN):", strerror(errno));
				return (NULL);
			}
		}
		map = malloc (size);
		if (!map)
			return (NULL);
		
		len = read (dev, map, size);
		if (len <= 0) {
			free (map);
			return NULL;
		}
		if (palette == VIDEO_PALETTE_YUV420P) {
			char *convmap;
            convmap = malloc ( width * height * bpp );
            v4l_yuv420p2rgb (convmap, map, width, height, bpp * 8);
            memcpy (map, convmap, (size_t) width * height * bpp);
            free (convmap);
        } else if (palette == VIDEO_PALETTE_YUV422P) {
			char *convmap;
            convmap = malloc ( width * height * bpp );
            v4l_yuv422p2rgb (convmap, map, width, height, bpp * 8);
            memcpy (map, convmap, (size_t) width * height * bpp);
            free (convmap);
		}
		return (map);
	}

	map = mmap (0, vid_buf.size, PROT_READ|PROT_WRITE,MAP_SHARED,dev,0);
	if ((unsigned char *)-1 == (unsigned char *)map) {
		log2 ("mmap():", strerror(errno));
		return (NULL);
	}
	vid_mmap.frame = 0;
	vid_mmap.width = width;
	vid_mmap.height =height;
	if (ioctl (dev, VIDIOCMCAPTURE, &vid_mmap) == -1) {
		log2 ("ioctl(VIDIOCMCAPTURE):", strerror(errno));
		munmap (map, vid_buf.size);
		return (NULL);
	}
	if (ioctl (dev, VIDIOCSYNC, &vid_mmap.frame) == -1) {
		log2 ("ioctl(VIDIOCSYNC):", strerror(errno));
		munmap (map, vid_buf.size);
		return (NULL);
	}
	buff = (unsigned char *) malloc (size);
	if (buff) {
		if (palette == VIDEO_PALETTE_YUV420P) {
			v4l_yuv420p2rgb (buff, map, width, height, 24);
        } else if (palette == VIDEO_PALETTE_YUV422P) {
            v4l_yuv422p2rgb (buff, map, width, height, 24);
		} else {
			for (i = 0; i < size; i++)
				buff[i] = map[i];
		}
	} else {
		perror ("malloc()");
	}
	munmap (map, vid_buf.size);
	return (buff);
}

/*
 */
void
put_image_jpeg (char *image, int width, int height, int quality, int color)
{
#ifdef HAVE_LIBJPEG
	register int x, y, line_width;
	JSAMPROW row_ptr[1];
	struct jpeg_compress_struct cjpeg;
	struct jpeg_error_mgr jerr;
	char *line = NULL;

	if (color) {
		line_width = width * 3;
		line = malloc (line_width);
		if (!line)
			return;
	} else {
		line_width = width;
	}
	cjpeg.err = jpeg_std_error(&jerr);
	jpeg_create_compress (&cjpeg);
	cjpeg.image_width = width;
	cjpeg.image_height= height;
	if (color) {
		cjpeg.input_components = 3;
		cjpeg.in_color_space = JCS_RGB;
	} else {
		cjpeg.input_components = 1;
		cjpeg.in_color_space = JCS_GRAYSCALE;
	}
	jpeg_set_defaults (&cjpeg);

	jpeg_simple_progression (&cjpeg);
	jpeg_set_quality (&cjpeg, quality, TRUE);
	cjpeg.dct_method = JDCT_FASTEST;
	jpeg_stdio_dest (&cjpeg, stdout);

	jpeg_start_compress (&cjpeg, TRUE);

	if (color) {
		row_ptr[0] = line;
		for ( y = 0; y < height; y++) {
			for (x = 0; x < line_width; x += 3) {
				line[x]   = image[x+2];
				line[x+1] = image[x+1];
				line[x+2] = image[x];
			}
			image += line_width;
			jpeg_write_scanlines (&cjpeg, row_ptr, 1);
		}
		free (line);
	} else {
		for ( y = 0; y < height; y++) {
			row_ptr[0] = image;
			jpeg_write_scanlines (&cjpeg, row_ptr, 1);
			image += line_width;
		}
	}
	jpeg_finish_compress (&cjpeg);
	jpeg_destroy_compress (&cjpeg);
#endif
}

/*
 * write png image to stdout
 */
void
put_image_png (char *image, int width, int height, int color)
{
#ifdef HAVE_LIBPNG
	register int y;
	register char *p;
	png_infop info_ptr;
	png_structp png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING,
						NULL, NULL, NULL);
	if (!png_ptr)
		return;
	info_ptr = png_create_info_struct (png_ptr);
	if (!info_ptr)
		return;

	png_init_io (png_ptr, stdout);
	if (color) {
		png_set_IHDR (png_ptr, info_ptr, width, height,
					8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
					PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
		png_set_bgr (png_ptr);
	} else {
		png_set_IHDR (png_ptr, info_ptr, width, height,
					8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE,
					PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
	}
	png_write_info (png_ptr, info_ptr);
	p = image;
	if (color) {
		width *= 3;
		for (y = 0; y < height; y++) {
			png_write_row (png_ptr, p);
			p += width;
		}
	} else {
		for (y = 0; y < height; y++) {
			png_write_row (png_ptr, p);
			p += width;
		}
	}
	png_write_end (png_ptr, info_ptr);
	png_destroy_write_struct (&png_ptr, &info_ptr);
#endif
}

/*
 * write ppm image to stdout
 */
void
put_image_ppm (char *image, int width, int height)
{
	int x, y, ls=0;
	unsigned char *p = (unsigned char *)image;
	printf ("P3\n%d %d\n%d\n", width, height, 255);
	for (x = 0; x < width; x++) {
		for (y = 0; y < height; y++) {
			printf ("%03d %03d %03d  ", p[2], p[1], p[0]);
			p += 3;
			if (ls++ > 4) {
				printf ("\n");
				ls = 0;
			}
		}
	}
}

/*
 */
const char *
palette2string (int palette) {
	if (palette == VIDEO_PALETTE_RGB24)
		return "rgb24";
	if (palette == VIDEO_PALETTE_YUV420P)
		return "yuv420p";
	if (palette == VIDEO_PALETTE_YUV422P)
		return "yuv422p";
	if (palette == VIDEO_PALETTE_GREY)
		return "grey";
	return "color";
}

/*
 * create a plain html page
 */
void
make_html (int width, int height, int color, int input, int fmt, int quality,
			float refresh, int us, int norm, int freq, char **freqs, int pal,
			int swapRGB)
{
	cgi_response (http_ok, "text/html");
	/* cgi_refresh (refresh, NULL); */
	cgi_html_start ("W3Cam");
	printf ("
\n"); } /* * create a html page with panel */ void make_gui (int width, int height, int color, int input, int fmt, int quality, float refresh, int us, int norm, int freq, char **freqs, int pal, int swapRGB) { make_html (width, height, color, input, fmt, quality, refresh, us, norm, freq, freqs, pal, swapRGB); printf ("

\n"); printf ("", width); printf ("\n", height); printf (""); printf ("\n", quality); printf ("\n", us); printf ("Input:\n", input == IN_SVIDEO? " selected":""); if ((norm != OFF) && (input == IN_TV)) { printf ("Norm:\n"); } if (freqs && (input == IN_TV)) { int f; printf ("Freq:\n"); } printf ("Format:\n", fmt == FMT_JPEG? " selected":""); printf ("Size:\n", width == 768 ? " selected": ""); printf ("Refresh (sec.):\n", refresh); else printf ("\n"); printf ("

\n"); cgi_html_end ("


"); } /* */ void on_signal (int signum) { exit (0); } #ifdef HAVE_LIBTTF #include "font.c" #endif /* * main() */ int main (int argc, char *argv[]) { int width = WIDTH_DEFAULT, height = HEIGHT_DEFAULT, dev = -1; char *val = NULL, **form = NULL, *image; char *boundary = "--w3cam-ns-boundary--may-not-work-with-ie--"; char *freqlist = FREQLIST_DEFAULT; char **freqs = NULL; char *device = VIDEO_DEV; int max_try = MAX_TRY_OPEN; /* we try 20 times (5 sec) to open the device */ int quality = QUALITY_DEFAULT; /* default jpeg quality setting */ int input = INPUT_DEFAULT; int norm = NORM_DEFAULT; int mode = MODE_DEFAULT; int color = TRUE; int swapRGB = FALSE; int palette = VIDEO_PALETTE_RGB24; float refresh = REFRESH_DEFAULT; float min_refresh = MIN_REFRESH; int format = FMT_DEFAULT; int usec = USEC_DEFAULT; int freq = 0; int protected = 0; char *mime = NULL; #ifdef HAVE_LIBTTF char *font = NULL; char *timestamp = NULL; int font_size = 12; #define TS_MAX 128 /* timestamp string */ char ts_buff[TS_MAX+1]; int ts_len; int border = 2; int blend = 60; int align = 1; time_t t; struct tm *tm; TT_Engine engine; TT_Face face; TT_Face_Properties properties; TT_Instance instance; TT_Glyph *glyphs = NULL; TT_Raster_Map bit; TT_Raster_Map sbit; #endif #ifdef USE_SYSLOG openlog (argv[0], LOG_PID, LOG_USER); #endif cgi_init (argv[0]); if (signal (SIGTERM, on_signal) == SIG_ERR) { log ("couldn't register handler for SIGTERM"); } if (signal (SIGPIPE, on_signal) == SIG_ERR) { log ("couldn't register handler for SIGPIPE"); } /* check some values from the config file */ val = cgi_cfg_value ("width"); if (val) width = atoi (val); val = cgi_cfg_value ("height"); if (val) height = atoi (val); val = cgi_cfg_value ("color"); if (val) { if (strcasecmp (val, "yuv420p") == 0) { color = 1; palette = VIDEO_PALETTE_YUV420P; } else if (strcasecmp (val, "yuv422p") == 0) { color = 1; palette = VIDEO_PALETTE_YUV422P; } else if (*val == '0' || *val == 'g') { color = 0; palette = VIDEO_PALETTE_GREY; } else { color = 1; } } val = cgi_cfg_value ("refresh"); if (val) refresh = atof (val); val = cgi_cfg_value ("norm"); if (val) norm = atoi (val); val = cgi_cfg_value ("input"); if (val) input = atoi (val); val = cgi_cfg_value ("format"); if (val) format = atoi (val); val = cgi_cfg_value ("quality"); if (val) quality = atoi (val); val = cgi_cfg_value ("mode"); if (val) mode = atoi (val); val = cgi_cfg_value ("usleep"); if (val) usec = atoi (val); val = cgi_cfg_value ("freq"); if (val) freq = atoi (val); val = cgi_cfg_value ("freqlist"); if (val) freqlist = val; val = cgi_cfg_value ("protected"); if (val) protected = atoi (val); val = cgi_cfg_value ("device"); if (val) device = val; val = cgi_cfg_value ("bgr"); if (val) swapRGB = atoi (val); #ifdef HAVE_LIBTTF val = cgi_cfg_value ("font"); if (val) font = val; val = cgi_cfg_value ("font_size"); if (val) font_size = atoi (val); val = cgi_cfg_value ("timestamp"); if (val) timestamp = val; val = cgi_cfg_value ("timestamp_border"); if (val) border = atoi (val); val = cgi_cfg_value ("timestamp_blend"); if (val) blend = atoi (val); val = cgi_cfg_value ("timestamp_align"); if (val) align = atoi (val); #endif /* parse the form, if there is any */ if (!protected) form = cgi_parse_form (); if (form && !protected) { val = cgi_form_value ("help"); if (val) { usage (argv[0], width, height, color, quality, usec); } val = cgi_form_value ("size"); if (val) { sscanf (val, "%dx%d", &width, &height); } val = cgi_form_value ("color"); if (val) { if (strcasecmp (val, "yuv420p") == 0) { color = 1; palette = VIDEO_PALETTE_YUV420P; } else if (strcasecmp (val, "yuv422p") == 0) { color = 1; palette = VIDEO_PALETTE_YUV422P; } else if (*val == '0' || *val == 'g') { color = 0; palette = VIDEO_PALETTE_GREY; } else { color = 1; palette = VIDEO_PALETTE_RGB24; } } val = cgi_form_value ("format"); if (val) { if ((strcasecmp ("ppm", val) == 0) && color) { format = FMT_PPM; } else if (strcasecmp ("png", val) == 0) { format = FMT_PNG; } else if (strcasecmp ("jpeg", val) == 0) { format = FMT_JPEG; } } val = cgi_form_value ("refresh"); if (val) refresh = atof (val); val = cgi_form_value ("quality"); if (val) quality = atoi (val); val = cgi_form_value ("usleep"); if (val) usec = atoi (val); val = cgi_form_value ("freq"); if (val) freq = atoi (val); val = cgi_form_value ("mode"); if (val) { if (strcmp ("gui", val) == 0) mode = MODE_GUI; else if (strcmp ("html", val) == 0) mode = MODE_HTML; else mode = MODE_PLAIN; } val = cgi_form_value ("input"); if (val) { if (strcasecmp ("tv", val) == 0) { input = IN_TV; } else if (strcasecmp ("composite", val) == 0) { input = IN_COMP1; } else if (strcasecmp ("composite2", val) ==0) { input = IN_COMP2; } else if (strcasecmp ("s-video", val) == 0) { input = IN_SVIDEO; } else { input = INPUT_DEFAULT; } } val = cgi_form_value ("norm"); if (val) { if (strcasecmp ("pal", val) == 0) { norm = NORM_PAL; } else if (strcasecmp ("ntsc", val) == 0) { norm = NORM_NTSC; } else if (strcasecmp ("secam", val) == 0) { norm = NORM_SECAM; } else { norm = OFF; } } val = cgi_form_value ("bgr"); if (val) { /* check for yes,true,1 */ if ((*val == '1') || (*val == 't') || (*val == 'y')) { swapRGB = 1; } else { swapRGB = 0; } } } if ((refresh > OFF) && (refresh < min_refresh)) refresh = min_refresh; if (!*freqlist) freqlist = NULL; if (mode == MODE_GUI) { freqs = parse_list (freqlist); make_gui (width, height, color, input, format, quality, refresh, usec, norm,freq, freqs, palette, swapRGB); return (0); } if (mode == MODE_HTML) { freqs = parse_list (freqlist); make_html (width, height, color, input, format, quality, refresh, usec, norm,freq, freqs, palette, swapRGB); return (0); } switch (format) { case FMT_PPM: mime = "image/ppm"; break; case FMT_JPEG: mime = "image/jpeg"; break; case FMT_PNG: mime = "image/png"; break; default: log ("unknown image format..!?"); break; } #ifdef HAVE_LIBTTF if (font && timestamp) { if (TT_Init_FreeType (&engine)) { font = NULL; goto no_time_stamp; } if (Face_Open (font, engine, &face, &properties, &instance, font_size)){ TT_Done_FreeType (engine); font = NULL; goto no_time_stamp; } } no_time_stamp: #endif if (!color) { palette = VIDEO_PALETTE_GREY; } /* open the video4linux device */ again: while (max_try) { dev = open (device, O_RDWR); if (dev == -1) { log2 (device, strerror(errno)); if (!--max_try) { cgi_response (http_ok, "text/plain"); printf ("Can't open device %s: %s\n",device,strerror(errno)); exit (0); } /* sleep 1/4 second */ usleep (250000); } else { max_try = MAX_TRY_OPEN; /* we may need it in a loop later .. */ break; } } if (v4l_mute_sound (dev) == -1) { perror ("mute sound"); } if (v4l_set_input (dev, input, norm) == -1) { return 1; } if (v4l_check_size (dev, &width, &height) == -1) { return 1; } /* if (v4l_check_palette (dev, &palette) == -1) { return 1; } */ again_without_open: image = get_image (dev, width, height, input, usec,freq, palette); if (image) { if (swapRGB && (palette == VIDEO_PALETTE_RGB24)) { int x,y; unsigned char *p, pt; p = image; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { pt = *p; *p = *(p+2); *(p+2) = pt; p += 3; } } } if (refresh != 0.0) { close (dev); } if (refresh != OFF) { cgi_multipart (boundary); printf ("Content-Type: %s\n\n", mime); } else { cgi_response (http_ok, mime); } #ifdef HAVE_LIBTTF if (font && timestamp) { time (&t); tm = localtime (&t); ts_buff[TS_MAX] = '\0'; strftime (ts_buff, TS_MAX, timestamp, tm); ts_len = strlen (ts_buff); glyphs = Glyphs_Load (face, &properties, instance, ts_buff, ts_len); Raster_Init(face, &properties,instance,ts_buff,ts_len, border, glyphs, &bit); Raster_Small_Init (&sbit, &instance); Render_String (glyphs, ts_buff, ts_len, &bit, &sbit, border); if (bit.bitmap) { int x, y, psize, i, x_off, y_off; unsigned char *p; if (color) psize = 3; else psize = 1; switch (align) { case 1: x_off = (width - bit.width) * psize; y_off = 0; break; case 2: x_off = 0; y_off = height - bit.rows; break; case 3: x_off = (width - bit.width) * psize; y_off = height - bit.rows; break; default: x_off = y_off = 0; break; } for (y = 0; y < bit.rows; y++) { p = image + (y + y_off) * (width * psize) + x_off; for (x = 0; x < bit.width; x++) { switch (((unsigned char *)bit.bitmap) [((bit.rows-y-1)*bit.cols)+x]) { case 0: for (i = 0; i < psize; i++) { *p = (255 * blend + *p * (100 - blend))/100; p++; } break; case 1: for (i = 0; i < psize; i++) { *p = (220 * blend + *p * (100 - blend))/100; p++; } break; case 2: for (i = 0; i < psize; i++) { *p = (162 * blend + *p * (100 - blend))/100; p++; } break; case 3: for (i = 0; i < psize; i++) { *p = (64 * blend + *p * (100 - blend))/100; p++; } break; default: for (i = 0; i < psize; i++) { *p = (0 * blend + *p * (100 - blend))/100; p++; } break; } } } } Raster_Done (&sbit); Raster_Done (&bit); Glyphs_Done (glyphs); glyphs = NULL; } #endif switch (format) { case FMT_PPM: put_image_ppm (image, width, height); printf ("\n%s\n", boundary); break; case FMT_PNG: put_image_png (image, width, height, color); printf ("\n%s\n", boundary); break; case FMT_JPEG: put_image_jpeg (image, width, height, quality, color); printf ("\n%s\n", boundary); break; default: /* should never be reached */ printf ("Unknown format (%d)\n", format); printf ("\n%s\n", boundary); break; } free (image); if (refresh == 0.0) { fflush (stdout); /* wait ? */ goto again_without_open; } if (refresh != OFF) { fflush (stdout); usleep ((int)(refresh * 1000000)); goto again; } } else { cgi_response (http_ok, "text/plain"); printf ("Error: Can't get image\n"); close (dev); } #ifdef HAVE_LIBTTF if (font && timestamp) { Face_Done (instance, face); TT_Done_FreeType (engine); } #endif return (0); } w3cam-0.7.2/vidcat.c0100644000076400000620000003750007373452150013014 0ustar rascauser/* * vidcat.c * * Copyright (C) 1998 - 2001 Rasca, Berlin * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #include /* gettimeofday() */ #include #include #include #include #ifdef HAVE_LIBZ #include #endif #ifdef HAVE_LIBPNG #include #endif #ifdef HAVE_LIBJPEG #include #endif #include "v4l.h" #define DEF_WIDTH 320 /* default width */ #define DEF_HEIGHT 240 /* default height */ #define FMT_UNKNOWN 0 #define FMT_PPM 1 #define FMT_PGM 2 #define FMT_PNG 3 #define FMT_JPEG 4 #define FMT_YUV4MPEG 5 #define IN_TV 0 #define IN_COMPOSITE 1 #define IN_COMPOSITE2 2 #define IN_SVIDEO 3 #define NORM_PAL 0 #define NORM_NTSC 1 #define NORM_SECAM 2 #define QUAL_DEFAULT 80 char *basename (const char *s); /* globals */ static int verbose = 0; /* */ void usage (char *pname) { fprintf (stderr, "VidCat, Version %s\n" "Usage: %s \n" " -b make a raw PPM instead of an ASCII one\n" " -d video device (default: "VIDEO_DEV")\n" " -f {ppm|jpeg|png|yuv4mpeg} output format of the image\n" " -g greayscale instead of color\n" " -i {tv|comp1|comp2|s-video} which input channel to use\n" " -l loop on, doesn't make sense in most cases\n" " -n {pal|ntsc|secam} select video norm\n" " -o write output to file instead of stdout\n" " -p c|g|y|Y videopalette to use\n" " -q only for jpeg: quality setting (1-100," " default: %d)\n" " -s NxN define size of the output image (default:" " %dx%d)\n" "Example: vidcat | xsetbg stdin\n", VERSION, (char*)basename(pname), QUAL_DEFAULT, DEF_WIDTH, DEF_HEIGHT); exit (1); } /* */ double ms_time (void) { static struct timeval tod; gettimeofday (&tod, NULL); return ((double)tod.tv_sec * 1000.0 + (double)tod.tv_usec / 1000.0); } /* * read rgb image from v4l device * return: mmap'ed buffer and size */ char * get_image (int dev, int width, int height, int palette ,int *size) { struct video_mbuf vid_buf; struct video_mmap vid_mmap; char *map, *convmap; int len; int bytes = 3; if (palette == VIDEO_PALETTE_GREY) bytes = 1; /* bytes per pixel */ if (ioctl (dev, VIDIOCGMBUF, &vid_buf) == -1) { /* to do a normal read() */ struct video_window vid_win; if (verbose) { fprintf (stderr, "using read()\n"); } if (ioctl (dev, VIDIOCGWIN, &vid_win) != -1) { vid_win.width = width; vid_win.height = height; if (ioctl (dev, VIDIOCSWIN, &vid_win) == -1) { perror ("ioctl(VIDIOCSWIN)"); return (NULL); } } map = malloc (width * height * bytes); len = read (dev, map, width * height * bytes); if (len <= 0) { free (map); return (NULL); } *size = 0; if (palette == VIDEO_PALETTE_YUV420P) { convmap = malloc ( width * height * bytes ); v4l_yuv420p2rgb (convmap, map, width, height, bytes * 8); memcpy (map, convmap, (size_t) width * height * bytes); free (convmap); } else if (palette == VIDEO_PALETTE_YUV422P) { convmap = malloc ( width * height * bytes ); v4l_yuv422p2rgb (convmap, map, width, height, bytes * 8); memcpy (map, convmap, (size_t) width * height * bytes); free (convmap); } return (map); } map = mmap (0, vid_buf.size, PROT_READ|PROT_WRITE,MAP_SHARED,dev,0); if ((unsigned char *)-1 == (unsigned char *)map) { perror ("mmap()"); return (NULL); } vid_mmap.format = palette; vid_mmap.frame = 0; vid_mmap.width = width; vid_mmap.height = height; if (ioctl (dev, VIDIOCMCAPTURE, &vid_mmap) == -1) { perror ("VIDIOCMCAPTURE"); fprintf (stderr, "args: width=%d height=%d palette=%d\n", vid_mmap.width, vid_mmap.height, vid_mmap.format); munmap (map, vid_buf.size); return (NULL); } if (ioctl (dev, VIDIOCSYNC, &vid_mmap.frame) == -1) { perror ("VIDIOCSYNC"); munmap (map, vid_buf.size); return (NULL); } *size = vid_buf.size; if (palette == VIDEO_PALETTE_YUV420P) { if (verbose) fprintf (stderr, "converting from YUV to RGB\n"); convmap = malloc ( width * height * bytes ); v4l_yuv420p2rgb (convmap, map, width, height, bytes * 8); memcpy (map, convmap, (size_t) width * height * bytes); free (convmap); } else if (palette == VIDEO_PALETTE_YUV422P) { if (verbose) fprintf (stderr, "converting from YUV to RGB\n"); convmap = malloc ( width * height * bytes ); v4l_yuv422p2rgb (convmap, map, width, height, bytes * 8); memcpy (map, convmap, (size_t) width * height * bytes); free (convmap); } return (map); if (verbose) fprintf (stderr, "got picture\n"); } /* */ void put_image_jpeg (FILE *out, char *image, int width, int height, int quality, int palette) { #ifdef HAVE_LIBJPEG int y, x, line_width; JSAMPROW row_ptr[1]; struct jpeg_compress_struct cjpeg; struct jpeg_error_mgr jerr; char *line; line = malloc (width * 3); if (!line) return; if (verbose) fprintf (stderr, "writing JPEG data\n"); cjpeg.err = jpeg_std_error(&jerr); jpeg_create_compress (&cjpeg); cjpeg.image_width = width; cjpeg.image_height= height; if (palette == VIDEO_PALETTE_GREY) { cjpeg.input_components = 1; cjpeg.in_color_space = JCS_GRAYSCALE; // jpeg_set_colorspace (&cjpeg, JCS_GRAYSCALE); } else { cjpeg.input_components = 3; cjpeg.in_color_space = JCS_RGB; } jpeg_set_defaults (&cjpeg); jpeg_set_quality (&cjpeg, quality, TRUE); cjpeg.dct_method = JDCT_FASTEST; jpeg_stdio_dest (&cjpeg, out); jpeg_start_compress (&cjpeg, TRUE); row_ptr[0] = line; if (palette == VIDEO_PALETTE_GREY) { line_width = width; for ( y = 0; y < height; y++) { row_ptr[0] = image; jpeg_write_scanlines (&cjpeg, row_ptr, 1); image += line_width; } } else { line_width = width * 3; for ( y = 0; y < height; y++) { for (x = 0; x < line_width; x+=3) { line[x] = image[x+2]; line[x+1] = image[x+1]; line[x+2] = image[x]; } jpeg_write_scanlines (&cjpeg, row_ptr, 1); image += line_width; } } jpeg_finish_compress (&cjpeg); jpeg_destroy_compress (&cjpeg); free (line); #endif } /* * write png image to stdout */ void put_image_png (FILE *out, char *image, int width, int height, int palette) { #ifdef HAVE_LIBPNG int y, bpp; char *p; png_infop info_ptr; png_structp png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) return; info_ptr = png_create_info_struct (png_ptr); if (!info_ptr) return; png_init_io (png_ptr, out); if (palette == VIDEO_PALETTE_GREY) { png_set_IHDR (png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); bpp = 1; } else { png_set_IHDR (png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); bpp = 3; } png_set_bgr (png_ptr); png_write_info (png_ptr, info_ptr); p = image; for (y = 0; y < height; y++) { png_write_row (png_ptr, p); p += width * bpp; } png_write_end (png_ptr, info_ptr); #endif } /* * write ppm image to stdout / file */ void put_image_ppm (FILE *out, char *image, int width, int height, int binary) { int x, y, ls=0; unsigned char *p = (unsigned char *)image; if (!binary) { fprintf (out, "P3\n%d %d\n%d\n", width, height, 255); for (x = 0; x < width; x++) { for (y = 0; y < height; y++) { fprintf (out, "%03d %03d %03d ", p[2], p[1], p[0]); p += 3; if (ls++ > 4) { fprintf (out, "\n"); ls = 0; } } } fprintf (out, "\n"); } else { unsigned char buff[3]; fprintf (out, "P6\n%d %d\n%d\n", width, height, 255); for (x = 0; x < width * height; x++) { buff[0] = p[2]; buff[1] = p[1]; buff[2] = p[0]; fwrite (buff, 1, 3, out); p += 3; } } fflush (out); } /* * write pgm image to stdout / file */ void put_image_pgm (FILE *out, char *image, int width, int height, int binary) { int x, y, ls=0; unsigned char *p = (unsigned char *)image; if (!binary) { fprintf (out, "P2\n%d %d\n%d\n", width, height, 255); for (x = 0; x < width; x++) { for (y = 0; y < height; y++) { fprintf (out, "%03d ", p[0]); p++; if (ls++ > 4) { fprintf (out, "\n"); ls = 0; } } } fprintf (out, "\n"); } else { fprintf (out, "P5\n%d %d\n%d\n", width, height, 255); for (x = 0; x < width * height; x++) { fwrite (p, 1, 1, out); p++; } } fflush (out); } /* * write YUV4MPEG stream which is nice for mpeg2enc */ int to_yuv (FILE *out, int fd, int width, int height) { struct video_mbuf vid_buf; struct video_mmap vid_mmap; int do_read = 0; int done = 0; char *map; int size; int num = 0; double ms_time0, ms_time1; int tpf = 40; /* 40 ms time per frame (= 25 fps) */ if (ioctl (fd, VIDIOCGMBUF, &vid_buf) == -1) { do_read = 1; } else { fprintf (stderr, "buffsize=%d frames=%d\n",vid_buf.size,vid_buf.frames); } if (!do_read) { map = mmap (0, vid_buf.size, PROT_READ|PROT_WRITE,MAP_SHARED, fd, 0); if ((unsigned char *)-1 == (unsigned char *)map) { perror ("mmap()"); return -1; } vid_mmap.format = VIDEO_PALETTE_YUV420P; vid_mmap.frame = 0; vid_mmap.width = width; vid_mmap.height =height; size = (width * height) + (width * height / 2); fprintf (stderr, "%dx%d bufsize=%d size=%d\n", width, height, vid_buf.size, size); printf ("YUV4MPEG%d %d %d\n", width, height, 3); if (ioctl (fd, VIDIOCMCAPTURE, &vid_mmap) == -1) { perror ("ioctl VIDIOCMCAPTURE"); munmap (map, vid_buf.size); return -1; } vid_mmap.frame = 1; if (ioctl (fd, VIDIOCMCAPTURE, &vid_mmap) == -1) { perror ("ioctl VIDIOCMCAPTURE"); munmap (map, vid_buf.size); return -1; } while (!done) { ms_time0 = ms_time(); /* milli seconds */ vid_mmap.frame = vid_mmap.frame > 0 ? 0 : 1; if (ioctl (fd, VIDIOCSYNC, &vid_mmap.frame) == -1) { perror ("ioctl VIDIOCSYNC"); munmap (map, vid_buf.size); return -1; } printf ("FRAME\n"); fwrite (map + vid_buf.offsets[vid_mmap.frame], 1, size, stdout); if (ioctl (fd, VIDIOCMCAPTURE, &vid_mmap) == -1) { perror ("ioctl VIDIOCMCAPTURE"); munmap (map, vid_buf.size); return -1; } num++; ms_time1 = ms_time () - ms_time0; if (ms_time1 < (double)tpf) { usleep (tpf - (int)ms_time1); } else { fprintf (stderr, "delayed: dt=%f\n",ms_time1 - (double)tpf); } } munmap (map, vid_buf.size); } else { fprintf (stderr, "still not implemented\n"); } return 0; } /* * main() */ int main (int argc, char *argv[]) { int width = DEF_WIDTH, height = DEF_HEIGHT, size, dev = -1, c; char *image, *device = VIDEO_DEV, *file = NULL; int max_try = 5; /* we try 5 seconds/times to open the device */ int quality = QUAL_DEFAULT; /* default jpeg quality setting */ int input = INPUT_DEFAULT; /* this means take over current device settings*/ int norm = NORM_DEFAULT; int loop =0 ; int binary = 0; int palette = VIDEO_PALETTE_RGB24; //int palette = VIDEO_PALETTE_YUV420; int num = 0; FILE *out = stdout; #ifdef HAVE_LIBJPEG int format = FMT_JPEG; #else # ifdef HAVE_LIBPNG int format = FMT_PNG; # else int format = FMT_PPM; # endif #endif while ((c = getopt (argc, argv, "bd:f:gi:ln:o:p:q:s:vV")) != EOF) { switch (c) { case 'b': /* PPM as binary file */ binary = 1; break; case 'd': /* change default device */ device = optarg; break; case 'f': if (strcasecmp ("yuv4mpeg", optarg) == 0) format = FMT_YUV4MPEG; else if (strcasecmp ("png", optarg) == 0) format = FMT_PNG; else if (strcasecmp ("ppm", optarg) == 0) format = FMT_PPM; else if (strcasecmp ("pgm", optarg) == 0) { format = FMT_PGM; palette = VIDEO_PALETTE_GREY; } else if (strcasecmp ("jpeg", optarg) == 0) format = FMT_JPEG; else format = FMT_UNKNOWN; break; case 'g': palette = VIDEO_PALETTE_GREY; break; case 'i': if (strcasecmp ("tv", optarg) == 0) { input = IN_TV; } else if (strcasecmp ("comp1", optarg) == 0) { input = IN_COMPOSITE; } else if (strcasecmp ("comp2", optarg) ==0) { input = IN_COMPOSITE2; } else if (strcasecmp ("s-video", optarg) == 0) { input = IN_SVIDEO; } else { usage (argv[0]); } break; case 'l': loop = 1; break; case 'n': if (strcasecmp ("pal", optarg) == 0) norm = NORM_PAL; else if (strcasecmp ("ntsc", optarg) == 0) norm = NORM_NTSC; else if (strcasecmp ("secam", optarg) == 0) norm = NORM_SECAM; else usage (argv[0]); break; case 'o': file = optarg; break; case 'p': switch (*optarg) { case 'R': case 'c': palette = VIDEO_PALETTE_RGB24; break; case 'y': palette = VIDEO_PALETTE_YUV420P; break; case 'Y': palette = VIDEO_PALETTE_YUV422P; break; case 'g': palette = VIDEO_PALETTE_GREY; break; default: usage (argv[0]); break; } break; case 'q': sscanf (optarg, "%d", &quality); break; case 's': sscanf (optarg, "%dx%d", &width, &height); break; case 'v': verbose++; break; case 'V': printf ("Vidcat, Version %s\n", VERSION); exit (0); break; default: usage (argv[0]); break; } } if (verbose) { fprintf (stderr, "input palette: %s\n", palette == VIDEO_PALETTE_GREY ? "grey" : palette == VIDEO_PALETTE_RGB24 ? "rgb" : palette == VIDEO_PALETTE_YUV420P ? "yuv420" : "yuv422"); fprintf (stderr, "size: %dx%d\n", width, height); } if (file) { out = fopen (file, "wb"); if (!out) { perror (file); return 1; } } again: /* open the video4linux device */ while (max_try) { dev = open (device, O_RDWR); if (dev == -1) { if (!--max_try) { fprintf (stderr, "Can't open device %s\n", device); return (1); } sleep (1); } else { break; } } if (!num) { /* if we loop we have to do this only once. so * check frame number and execute only for the * frame number "0". */ if (v4l_set_input (dev, input, norm) == -1) { return (1); } if (v4l_check_size (dev, &width, &height) == -1) { return (1); } /*if (v4l_check_palette (dev, &palette) == -1) { return (1); }*/ } switch (format) { case FMT_YUV4MPEG: if (palette == VIDEO_PALETTE_YUV420P) return to_yuv (out, dev, width, height); break; } image = get_image (dev, width, height, palette, &size); if (!size) close (dev); if (image) { switch (format) { case FMT_PPM: if (palette == VIDEO_PALETTE_GREY) put_image_pgm (out, image, width, height, binary); else put_image_ppm (out, image, width, height, binary); break; case FMT_PGM: put_image_pgm (out, image, width, height, binary); break; case FMT_PNG: put_image_png (out, image, width, height, palette); break; case FMT_JPEG: put_image_jpeg (out, image, width, height, quality, palette); break; default: fprintf (stderr, "Unknown format (%d)\n", format); break; } if (size) { munmap (image, size); close (dev); } else if (image) { free (image); } if (loop) { num++; goto again; } } else { fprintf (stderr, "Error: Can't get image\n"); } return (0); } w3cam-0.7.2/w3camd/0040755000076400000620000000000007412662332012551 5ustar rascauserw3cam-0.7.2/w3camd/w3camd.c0100644000076400000620000002650407150315403014070 0ustar rascauser/* * w3camd.c * * Copyright (C) 1998 - 2000 Rasca, Berlin * EMail: thron@gmx.de * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #include "w3socket.h" #include "w3http.h" #include "w3v4l.h" #include "w3jpeg.h" #include "w3log.h" #ifndef CAM_PORT #define CAM_PORT 8999 #endif #define forever() while(1) #define MAX_WIDTH 768 #define MAX_HEIGHT 576 #define SERVER_NAME "w3camd/0.3" #define SLEEP(n) usleep((int)(n * 1000000)) #define OFF -1 enum { ST_NONE, ST_ERROR, ST_BUSY, ST_READY, ST_EXIT, }; typedef struct { int childs; pthread_mutex_t childs_lock; pthread_cond_t childs_cond; int state; int width; /* image width */ int height; /* image height */ int input; unsigned char *img; /* image data for the childs */ pthread_mutex_t img_lock; pthread_cond_t img_cond; } image_t; typedef struct { int fd; /* fd for the incoming connection */ int verbose; char *url; char *image; int image_size; image_t *img; pthread_t thread; /* */ float refresh; int quality; } conn_t; typedef struct { char *dev; image_t *img; } camera_t; /* * show possible parameters */ void usage (char *pname) { fprintf (stderr, "Usage: %s [-v] [-p #] [-h host] [-s #x#] [-m #] [-i #] [-d device] \n", pname); exit (1); } /* * write jpeg file to filedescriptor fd */ int write_jpeg (image_t *img, int fd, int quality) { JSAMPROW row_ptr[1]; struct jpeg_compress_struct jpeg; struct jpeg_error_mgr jerr; char *line, *image; int y, x, line_width; #ifdef DEBUG fprintf (stderr, "%s: write_jpeg() width=%d height=%d\n", __FILE__, img->width, img->height); #endif line = malloc (img->width * 3); if (!line) return 0; jpeg.err = jpeg_std_error (&jerr); jpeg_create_compress (&jpeg); jpeg.image_width = img->width; jpeg.image_height= img->height; jpeg.input_components = 3; jpeg.in_color_space = JCS_RGB; jpeg_set_defaults (&jpeg); jpeg_set_quality (&jpeg, quality, TRUE); jpeg.dct_method = JDCT_FASTEST; jpeg_io_dest (&jpeg, fd); /* this is in w3jpeg.c */ jpeg_start_compress (&jpeg, TRUE); row_ptr[0] = line; line_width = img->width * 3; image = img->img; for (y = 0; y < img->height; y++) { for (x = 0; x < line_width; x+=3) { line[x] = image[x+2]; line[x+1] = image[x+1]; line[x+2] = image[x]; } if (!jpeg_write_scanlines (&jpeg, row_ptr, 1)) { jpeg_destroy_compress (&jpeg); free (line); return 0; } image += line_width; } jpeg_finish_compress (&jpeg); jpeg_destroy_compress (&jpeg); free (line); return 1; } /* * capture images continously */ void * image_thread (void *data) { camera_t *cam = (camera_t *) data; image_t *img = cam->img; video_t *vid; #ifdef DEBUG printf ("%s: image_thread() img->childs=%d\n", __FILE__, img->childs); printf ("%s: pid = %d\n", __FILE__, getpid()); #endif WAIT: img->state = ST_NONE; pthread_mutex_lock (&img->childs_lock); forever () { pthread_cond_wait (&img->childs_cond, &img->childs_lock); log_print ("%s: no. of childs changed: childs=%d\n", __FILE__, img->childs); if (img->childs > 0) break; } pthread_mutex_unlock (&img->childs_lock); if (!(vid = v4l_init(cam->dev, img->input, img->width, img->height))) { img->state = ST_ERROR; /* pthread_cond_broadcast (&img->img_cond); */ log_print("%s: can't init v4l\n", __FILE__); goto WAIT; } vid->width = img->width; vid->height= img->height; while (img->childs > 0) { if (!v4l_image(vid)) { img->state = ST_ERROR; log_print ("image_thread() error\n"); } else { img->state = ST_BUSY; pthread_mutex_lock (&img->img_lock); printf ("0x%X 0x%X %dx%d\n", img, vid->mem,vid->width, vid->height); memcpy (img->img, vid->mem, vid->width * vid->height * 3); printf ("done ..\n"); #ifdef DEBUG printf ("%s: unlocking img..\n", __FILE__); #endif pthread_mutex_unlock (&img->img_lock); img->state = ST_READY; pthread_cond_broadcast (&img->img_cond); SLEEP(0.005); } } v4l_fini (vid); goto WAIT; return (NULL); } /* */ void e_help (conn_t *cn) { char buf[16]; char *e = "Usage:\n" " /image[?quality=<#>[&stream]] - retrieve an image\n" " /help - see these lines\n"; sprintf (buf, "%d", strlen (e)); http_status (cn->fd, HTTP_OK); http_header (cn->fd, HTTP_SERVER, SERVER_NAME); http_header (cn->fd, HTTP_CONTENT_TYPE, "text/plain"); http_header (cn->fd, HTTP_CONTENT_LENGTH, buf); http_header (cn->fd, HTTP_HEADER_END, NULL); write (cn->fd, e, strlen(e)); } /* */ void e_wrong_url (conn_t *cn) { char buf[16]; char *e = "wrong url!\n try \"/help\"\n"; sprintf (buf, "%d", strlen (e)); http_status (cn->fd, HTTP_BAD_REQUEST); http_header (cn->fd, HTTP_SERVER, SERVER_NAME); http_header (cn->fd, HTTP_CONTENT_TYPE, "text/plain"); http_header (cn->fd, HTTP_CONTENT_LENGTH, buf); http_header (cn->fd, HTTP_HEADER_END, NULL); write (cn->fd, e, strlen(e)); } /* */ void e_error (conn_t *cn) { char buf[64]; http_status (cn->fd, HTTP_BAD_REQUEST); http_header (cn->fd, HTTP_SERVER, SERVER_NAME); http_header (cn->fd, HTTP_CONTENT_TYPE, "text/plain"); http_header (cn->fd, HTTP_HEADER_END, NULL); sprintf (buf, "can't read image! device busy?!\n"); write (cn->fd, buf, strlen(buf)); } /* * process the requested url */ void process_url (conn_t *cn) { char rfc1123[64]; time_t gmt; int stream = 0; char buf[128]; # define BOUNDARY "--w3camd-ns-boundary--may-not-work-with-ie--" gmt = time (NULL); strftime (rfc1123, 64, "%a, %d %b %Y %H:%M:%S GMT", gmtime (&gmt)); if (!cn->url) { e_wrong_url (cn); return; } if (strncmp (cn->url, "/image", 6) != 0) { if (strncmp (cn->url, "/help", 5) == 0) e_help (cn); else e_wrong_url (cn); return; } if (strstr (cn->url, "stream")) { stream = 1; } if (cn->img->state == ST_ERROR) { e_error (cn); return; } http_status (cn->fd, HTTP_OK); http_header (cn->fd, HTTP_SERVER, SERVER_NAME); if (stream) { http_header (cn->fd, HTTP_CONTENT_TYPE, "multipart/x-mixed-replace;boundary="BOUNDARY); } else { http_header (cn->fd, HTTP_CONTENT_TYPE, "image/jpeg"); } http_header (cn->fd, HTTP_EXPIRES, rfc1123); http_header (cn->fd, HTTP_HEADER_END, NULL); forever () { pthread_cond_wait (&cn->img->img_cond, &cn->img->img_lock); log_print ("process_url() state=%d\n", cn->img->state); if (cn->img->state == ST_READY) { /* pthread_mutex_lock (&cn->img->img_lock); */ if (stream) { sprintf (buf, "\n%s\n", BOUNDARY); write (cn->fd, buf, strlen(buf)); sprintf (buf, "Content-Type: image/jpeg\n\n"); write (cn->fd, buf, strlen(buf)); } if (!write_jpeg (cn->img, cn->fd, cn->quality)) return; /* pthread_mutex_unlock (&cn->img->img_lock); */ if (!stream) break; } } } /* * child which handles an incoming connection */ void * server_thread (void *data) { #define MAX_BUF 1024 #define MAX_ALL 4096 conn_t *cn = (conn_t *) data; int len, inlen = 0; char buf [MAX_BUF+1]; char inbuf[MAX_ALL+1]; char **args, *val; buf [MAX_BUF] = '\0'; inbuf[MAX_BUF] = '\0'; if (cn->verbose) printf ("server_thread() state=%d\n", cn->img->state); forever () { len = read (cn->fd, buf, MAX_BUF); if (len <= 0) { /* client closed connection */ goto CLIENT_END; return (NULL); } buf[len] = '\0'; if (inlen + len > MAX_ALL) { log_print ("input overrun\n"); break; } memcpy (inbuf+inlen, buf, len); inlen += len; if (strstr (inbuf, "\n\n") || strstr (inbuf, "\r\n\r\n") || strstr (inbuf, "\r\r") ) break; } inbuf[inlen] = '\0'; cn->url = http_parse (inbuf, &args); if (cn->verbose > 1) log_print ("getting url=%s\n", cn->url); if (args) { val = http_arg_val (args, "refresh"); if (val) /* not used until now */ cn->refresh = atof (val); val = http_arg_val (args, "quality"); if (val) cn->quality = atoi (val); } if (cn->verbose > 2) { printf (" quality=%d\n", cn->quality); printf (" refresh=%f\n", cn->refresh); } process_url (cn); close (cn->fd); cn->img->childs--; if (args) { http_free_args (args); } free (cn->url); if (cn->verbose) { printf ("connection closed\n"); } CLIENT_END: pthread_detach (cn->thread); free (cn); return (NULL); } /* */ static void on_sig_pipe (int signum) { log_print ("** signal pipe received\n"); } static void on_signal (int signum) { log_print ("%d received signal %d\n", getpid(), signum); exit (1); } /* * let's start up */ int main (int argc, char *argv[]) { int c, sd, cd, fps = 25, input = -1; int verbose = 0, max_connections = 10; int width = 240, height = 180; int port = CAM_PORT; char *host = "localhost"; /* default host to run on */ conn_t *cn; image_t *img; pthread_t ithread; camera_t cam; cam.dev = "/dev/video0"; /* parse arguments */ while ((c = getopt (argc, argv, "vp:h:i:s:f:m:d:")) != EOF) { switch (c) { case 'd': cam.dev = optarg; break; case 'f': fps = atoi(optarg); break; case 'h': host = optarg; break; case 'i': input = atoi(optarg); break; case 'm': max_connections = atoi(optarg); break; case 'p': port = atoi (optarg); break; case 's': sscanf (optarg, "%dx%d", &width, &height); break; case 'v': verbose++; break; default: usage (argv[0]); break; } } if (verbose) log_print ("main thread pid = %d\n", getpid()); img = malloc (sizeof (image_t) + 3 * MAX_WIDTH * MAX_HEIGHT); if (!img) exit (1); img->img = (unsigned char *)(img + 1); img->childs = 0; img->width = width; img->height= height; img->state = ST_NONE; img->input = input; cam.img = img; signal (SIGPIPE, on_sig_pipe); signal (SIGSEGV, on_signal); pthread_mutex_init (&img->childs_lock, NULL); pthread_mutex_init (&img->img_lock, NULL); pthread_cond_init (&img->childs_cond, NULL); pthread_cond_init (&img->img_cond, NULL); sd = bind_port (host, port); if (verbose) printf ("bind %s:%d to file descriptor %d\n", host, port, sd); if (sd < 0) { return (-1); } pthread_create (&ithread, NULL, image_thread, (void *)&cam); forever () { cd = accept_con (sd); if (cd < 0) { printf ("oops!? accept_con() returned < 0\n"); continue; } if (verbose) printf ("incoming connection..\n"); if ((img->childs+1) > max_connections) { if (verbose) printf ("too much connections!\n"); continue; } pthread_mutex_lock (&img->childs_lock); img->childs++; pthread_cond_broadcast (&img->childs_cond); pthread_mutex_unlock (&img->childs_lock); cn = malloc (sizeof (conn_t)); if (!cn) exit (2); cn->fd = cd; cn->img = img; cn->verbose = verbose; cn->quality = 75; if (verbose) printf ("serving connection, (childs=%d)\n", cn->img->childs); /* child */ pthread_create (&cn->thread, NULL, server_thread, cn); } return (0); } w3cam-0.7.2/w3camd/Makefile0100644000076400000620000000107507412643155014213 0ustar rascauser# Generated automatically from Makefile.in by configure. # # makefile for w3camd # prefix=/usr/local sbindir=/usr/local/sbin CFLAGS = -O2 -Wall -I/usr/local/include -I/usr/local/X11/include -I.. -I. -I/usr/local/include -g -DDEBUG -DCAM_PORT=8999 -D_REENTRANT CC = gcc default: w3camd OBJ = w3camd.o w3socket.o w3v4l.o w3http.o w3jpeg.o %.o: %.c $(CC) $(CFLAGS) -c $< w3camd: $(OBJ) $(CC) -o $@ $(OBJ) -lpthread -ljpeg install: install w3camd $(sbindir)/ clean: rm -f *.o w3camd README: index.html lynx -dump http://www/~rasca/w3cam/w3camd/index.html >README w3cam-0.7.2/w3camd/w3socket.c0100644000076400000620000000516707103321564014461 0ustar rascauser/* * w3socket.c * * Copyright (C) 1998 - 2000 Rasca, Berlin * EMail: thron@gmx.de * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include "w3socket.h" #define EMPTY '\0' #define INIT_ADDR(addr) (memset((char *)&addr, '\0', sizeof (addr))) /* * convert host name or number into the binary version, * returns "-1" on error. */ unsigned long host_addr (char *host) { unsigned long bhost = 0; struct hostent *hostp; if ((host == NULL) || (*host == EMPTY)) { return (INADDR_ANY); } if ((bhost = inet_addr (host)) > -1) { return (bhost); } if ((hostp = gethostbyname(host)) == NULL) { errno = EINVAL; return (-1); } if (hostp->h_addrtype != AF_INET) { errno = EINVAL; return (-1); } return (*((unsigned long *)hostp->h_addr)); } /* * return the file descriptor */ int bind_port (char *host, int port) { int sd=0; struct sockaddr_in addr; int one = 1; INIT_ADDR(addr); addr.sin_family = AF_INET; addr.sin_addr.s_addr = host_addr(host); if (errno == EINVAL) { perror (host); return (-1); } if (sizeof (addr.sin_port) == sizeof(short)) { addr.sin_port = htons(port); } else { addr.sin_port = htonl(port); } if ((sd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { perror (host); return (-1); } #ifdef DEBUG printf ("%s, sd=%d host_addr()=%d\n", __FILE__, sd, addr.sin_addr.s_addr); #endif setsockopt (sd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)); if (bind (sd, (struct sockaddr *) &addr, sizeof (addr)) < 0) { close (sd); perror ("bind()"); return (-1); } while (listen (sd, 3) == -1) { if (errno != EINTR) { return (-1); } } return (sd); } /* * block until next incoming connection */ int accept_con (int sd) { int nd = -1; int len; struct sockaddr raddr; do { nd = accept (sd, &raddr, &len); } while ((nd < 1) && (errno == EINTR)); if (nd < 0) { return (-1); } return (nd); } w3cam-0.7.2/w3camd/w3socket.h0100644000076400000620000000157106627542307014473 0ustar rascauser/* * w3socket.h * * Copyright (C) 1998 Rasca, Berlin * EMail: thron@gmx.de * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __W3SOCKET_H__ #define __W3SOCKET_H__ int bind_port (char *, int); int accept_con(int); #endif w3cam-0.7.2/w3camd/w3v4l.c0100644000076400000620000000636007150316203013666 0ustar rascauser/* * w3v4l.c * * Copyright (C) 1998 - 2000 Rasca, Berlin * EMail: thron@gmx.de * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #include #include #include "w3v4l.h" /* */ video_t * v4l_init (char *dev, int input, int width, int height) { int fd; struct video_capability vid_caps; struct video_mbuf vid_mbuf; struct video_channel vid_chnl; video_t *vid; fd = open (dev, O_RDWR); if (fd == -1) { perror (dev); return (NULL); } if (ioctl (fd, VIDIOCGCAP, &vid_caps) == -1) { perror ("ioctl (VIDIOCGCAP)"); return (NULL); } vid = malloc (sizeof (video_t)); vid->fd = fd; if (ioctl (fd, VIDIOCGMBUF, &vid_mbuf) == -1) { struct video_window vid_win; vid->map_size = 0; if (ioctl(fd, VIDIOCGWIN, &vid_win) != -1) { vid_win.width = width; vid_win.height= height; ioctl (fd, VIDIOCSWIN, &vid_win); } } else { vid->map_size = vid_mbuf.size; } #ifdef DEBUG printf ("%s: mbuf.size=%d\n", __FILE__, vid_mbuf.size); #endif if (input > -1) { vid_chnl.channel = input; if (ioctl (fd, VIDIOCGCHAN, &vid_chnl) == -1) { perror ("ioctl (VIDIOCGCHAN)"); } else { vid_chnl.channel = input; if (ioctl (fd, VIDIOCSCHAN, &vid_chnl) == -1) { perror ("ioctl (VIDIOCSCHAN)"); } } } if (vid->map_size > 0) { vid->mem = mmap (0,vid->map_size, PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if ((unsigned char *) -1 == (unsigned char *)vid->mem) { perror ("mmap()"); close (fd); free (vid); return (NULL); } } else { vid->mem = malloc (width * height * 3); } vid->width = width; vid->height= height; return (vid); } /* */ void v4l_fini (video_t *vid) { if (vid->fd >= 0) { if (vid->map_size == 0) free (vid->mem); else munmap (vid->mem, vid->map_size); close (vid->fd); } free (vid); } /* * return a new image */ int v4l_image (video_t *vid) { struct video_mmap vid_mmap; if (vid->map_size == 0) { printf ("%s: reading image .. \n", __FILE__); if (read (vid->fd, vid->mem, vid->width * vid->height * 3) <= 0) { free (vid->mem); return (0); } } else { vid_mmap.format = VIDEO_PALETTE_RGB24; vid_mmap.frame = 0; vid_mmap.width = vid->width; vid_mmap.height= vid->height; if (ioctl (vid->fd, VIDIOCMCAPTURE, &vid_mmap) == -1) { perror ("ioctl (VIDIOCMCAPTURE)"); return (0); } if (ioctl (vid->fd, VIDIOCSYNC, &vid_mmap) == -1) { perror ("ioctl (VIDIOCSYNC)"); return (0); } } printf ("%s: done\n", __FILE__); return (1); } w3cam-0.7.2/w3camd/w3v4l.h0100644000076400000620000000203507150312755013676 0ustar rascauser/* * w3v4l.h * * Copyright (C) 1998 - 2000 Rasca, Berlin * EMail: thron@gmx.de * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __W3V4L_H__ #define __W3V4L_H__ typedef struct { int fd; int map_size; char *mem; /* memory for the image */ int width, height; } video_t; video_t *v4l_init (char *, int, int, int); void v4l_fini (video_t *); int v4l_image (video_t *); #endif w3cam-0.7.2/w3camd/w3http.c0100644000076400000620000001140507113426054014141 0ustar rascauser/* * w3http.c * * Copyright (C) 1998 - 2000 Rasca, Berlin * EMail: thron@gmx.de * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include "w3http.h" static http_code _http_status[] = { {100, "Continue", sizeof("Continue")}, {101, "Switching Protocols", sizeof("Switching Protocols")}, {200, "Ok", sizeof("Ok")}, {201, "Created", sizeof("Created")}, {202, "Accepted", sizeof("Accepted")}, {204, "No Content", sizeof("No Content")}, {400, "Bad Request", sizeof("Bad Request")}, {500, "Internal Server Error", sizeof("Internal Server Error")}, }; static http_code _http_header[] = { {HTTP_SERVER, "Server: ", sizeof ("Server: ")}, {HTTP_CONTENT_TYPE, "Content-Type: ", sizeof ("Content-type: ")}, {HTTP_CONTENT_LENGTH,"Content-Length: ",sizeof ("Content-length: ")}, {HTTP_MIME_VERSION, "MIME-Version: ", sizeof ("MIME-Version: ")}, {HTTP_EXPIRES, "Expires: ", sizeof ("Expires: ")}, {HTTP_HEADER_END, "\r\n", sizeof ("\r\n")}, }; #define HTTP_PROTOCOL "HTTP/1.1" #define STATUS_CHECK(n) if (n <0 || n>=HTTP_STATUS_END) no = HTTP_SERVER_ERROR; #define STATUS_ASSIGN(n,c) c = &_http_status[no]; #define HEADER_CHECK(n) if (n <0 || n> HTTP_HEADER_END) no = HTTP_CONTENT_TYPE; #define HEADER_ASSIGN(n,c) c = &_http_header[no]; /* */ int http_status (int fd, int no) { http_code *c; char buf[128]; int rc; STATUS_CHECK(no); STATUS_ASSIGN(no,c); sprintf (buf, HTTP_PROTOCOL" %d %s\r\n", c->num, c->str); rc = write (fd, buf, strlen(buf)); return (rc); } /* */ int http_header (int fd, int no, char *value) { #define MAX_HEADER 2048 http_code *c; char buf[MAX_HEADER+3]; int rc, len; HEADER_CHECK(no); HEADER_ASSIGN(no,c); sprintf (buf, "%s", c->str); rc = write (fd, buf, strlen(buf)); if (value) { len = strlen (value); if (len > MAX_HEADER) value = "--buffer too short!--"; sprintf (buf, "%s\r\n", value); rc += write (fd, buf, strlen(buf)); } return (rc); } /* */ static char * hex_to_asc (const char *str, int len) { char *p, *s; char buff[4]; int chr; if (!str) return (NULL); s = (char *) malloc (len + 1); p = s; buff[2] = '\0'; while (*str && len) { if (*str == '%') { strncpy (buff, str+1, 2); sscanf (buff, "%02X", &chr); *p = (unsigned char) chr; str += 3; len -= 3; } else { if (*str == '+') *p = ' '; else *p = *str; str++; len--; } p++; } *p = '\0'; return (s); } /* */ static char ** parse_string (const char *str) { char **kv = NULL; const char *p, *end; int num = 1, i; int len; if (!str) return (NULL); p = str; while ((p = strchr (p, '&')) != NULL) { num++; p++; } kv = (char **) calloc ((num * 2 +1), sizeof (char **)); p = str; i = 0; do { len = 0; if (*p == '&') { p++; } end = p; while ((*end != '=') && (*end != '\0') && (*end != '&')) { len++; end++; } kv[i] = hex_to_asc (p, len); if (*end == '&') { /* variable has no value .. */ p += len; i++; continue; } p += len+1; end = p; i++; len = 0; while ((*end != '&') && (*end != '\0')) { len++; end++; } kv[i] = hex_to_asc (p, len); if (len > 0) p++; i++; } while ((p = strchr (p, '&')) != NULL); return (kv); } /* */ char * http_parse (char *buf, char ***args) { char *url, *ep; int len; if (strncasecmp (buf, "GET ", 4)) return (NULL); ep = strstr (buf, " HTTP/"); if (!ep) ep = strstr (buf, " http/"); if (!ep) return (NULL); len = ep - buf - 4; url = malloc (len+1); if (!url) return (NULL); strncpy (url, buf+4, len); url[len] = '\0'; if (args) { char *p; if ((p = strchr (url, '?')) != NULL) { *args = parse_string (p+1); } } #ifdef DEBUG2 printf ("%s: get_url() buf=%s\n", __FILE__, buf); #endif return (url); } /* */ char * http_arg_val (char **args, char *key) { char *val = NULL; if (!args) return (NULL); if (!key) return (NULL); while (*args) { if (strcmp (key, *args) == 0) return (*(args+1)); args += 2; } return (val); } /* */ void http_free_args (char **args) { char **p; if (args) { p = args; while (*p) { free (*p++); } free (args); } } w3cam-0.7.2/w3camd/w3http.h0100644000076400000620000000256307101674177014163 0ustar rascauser/* * w3http.h * * Copyright (C) 1998 Rasca, Berlin * EMail: thron@gmx.de * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __W3HTTP_H__ #define __W3HTTP_H__ typedef struct { int num; char *str; int len; } http_code ; /* status types */ enum { HTTP_CONTINUE, HTTP_SWITCHING_PROTOCOLS, HTTP_OK, HTTP_CREATED, HTTP_ACCEPTED, HTTP_NO_CONTENT, HTTP_BAD_REQUEST, HTTP_SERVER_ERROR, HTTP_STATUS_END, }; /* header types */ enum { HTTP_SERVER, HTTP_CONTENT_TYPE, HTTP_CONTENT_LENGTH, HTTP_MIME_VERSION, HTTP_EXPIRES, HTTP_HEADER_END, }; int http_status (int, int); int http_header (int, int, char *); char *http_parse (char *, char ***); char *http_arg_val (char **, char *); void http_free_args (char **); #endif w3cam-0.7.2/w3camd/Makefile.in0100644000076400000620000000072007103315710014602 0ustar rascauser# # makefile for w3camd # prefix=@prefix@ sbindir=@prefix@/sbin CFLAGS = @CFLAGS@ -I.. -I. -I@prefix@/include -g -DDEBUG -DCAM_PORT=8999 -D_REENTRANT CC = @CC@ default: w3camd OBJ = w3camd.o w3socket.o w3v4l.o w3http.o w3jpeg.o %.o: %.c $(CC) $(CFLAGS) -c $< w3camd: $(OBJ) $(CC) -o $@ $(OBJ) -lpthread -ljpeg install: install w3camd $(sbindir)/ clean: rm -f *.o w3camd README: index.html lynx -dump http://www/~rasca/w3cam/w3camd/index.html >README w3cam-0.7.2/w3camd/w3jpeg.c0100644000076400000620000000551207111545323014110 0ustar rascauser/* * w3jpeg.c * plain io destination manager (write()) * * Copyright (C) 1998 - 2000 Rasca, Berlin * EMail: thron@gmx.de * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include "w3jpeg.h" typedef struct { struct jpeg_destination_mgr pub; int fd; JOCTET *buffer; } my_destination_mgr; typedef my_destination_mgr *my_dest_ptr; #define OUTPUT_BUF_SIZE 2048 /* * initialize buffer */ METHODDEF(void) init_destination (j_compress_ptr cinfo) { my_dest_ptr dest = (my_dest_ptr) cinfo->dest; dest->buffer = (JOCTET *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, OUTPUT_BUF_SIZE * sizeof(JOCTET)); dest->pub.next_output_byte = dest->buffer; dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; } /* * flush buffer to filedescriptor */ METHODDEF(boolean) empty_output_buffer (j_compress_ptr cinfo) { my_dest_ptr dest = (my_dest_ptr) cinfo->dest; if (write (dest->fd, dest->buffer, OUTPUT_BUF_SIZE) != OUTPUT_BUF_SIZE) { #ifdef DEBUG_JPEG fprintf (stderr, "%s: empty_output_buffer()\n", __FILE__); #endif return (FALSE); ERREXIT(cinfo, JERR_FILE_WRITE); } dest->pub.next_output_byte = dest->buffer; dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; return (TRUE); } /* */ METHODDEF(void) term_destination(j_compress_ptr cinfo) { my_dest_ptr dest = (my_dest_ptr) cinfo->dest; size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; if (datacount > 0) { if (write (dest->fd, dest->buffer, datacount) != datacount) { #ifdef DEBUG_JPEG fprintf (stderr, "%s: term_destination()\n", __FILE__); #endif return; ERREXIT(cinfo, JERR_FILE_WRITE); } } } /* */ GLOBAL(void) jpeg_io_dest (j_compress_ptr cinfo, int fd) { my_dest_ptr dest; if (cinfo->dest == NULL) { cinfo->dest = (struct jpeg_destination_mgr *) (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_PERMANENT, sizeof(my_destination_mgr)); } #ifdef DEBUG_JPEG fprintf (stderr, "%s: jpeg_io_dest()\n", __FILE__); #endif dest = (my_dest_ptr) cinfo->dest; dest->pub.init_destination = init_destination; dest->pub.empty_output_buffer = empty_output_buffer; dest->pub.term_destination = term_destination; dest->fd = fd; } w3cam-0.7.2/w3camd/w3jpeg.h0100644000076400000620000000155106630546105014120 0ustar rascauser/* * w3jpeg.h * * Copyright (C) 1998 Rasca, Berlin * EMail: thron@gmx.de * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __W3JPEG_H__ #define __W3JPEG_H__ void jpeg_io_dest (j_compress_ptr, int); #endif w3cam-0.7.2/w3camd/test.html0100644000076400000620000000015606630620324014411 0ustar rascauser /image?.. w3cam-0.7.2/w3camd/index.html0100644000076400000620000000144407101676774014560 0ustar rascauser w3camd

w3camd 0.2, simple webcam daemon

w3camd is part of the w3cam-package and is distributed under the GNU GPL. (c) Rasca, Berlin 1998

w3camd needs the jpeg library. Warning: w3camd is still in early alpha state, this code is distributed only for developers!

Options:

	-v       verbose mode
	-p #     port number (default: 8999)
	-h host  host name to bind to (default: localhost)
	-m #     max connections to serve (default: 10)
	-s #x#	 size of image
	-i input 0=TV, 1=comp1, 2=comp2, 3=s-video
	-d dev   camera device, default: /dev/video0

Test-link: /image?quality=55


rasca, 27. Apr 2000 - 01:38
w3cam-0.7.2/w3camd/README0100644000076400000620000000146207101677000013422 0ustar rascauser w3camd 0.2, simple webcam daemon w3camd is part of the w3cam-package and is distributed under the GNU GPL. (c) Rasca, Berlin 1998 w3camd needs the jpeg library. Warning: w3camd is still in early alpha state, this code is distributed only for developers! Options: -v verbose mode -p # port number (default: 8999) -h host host name to bind to (default: localhost) -m # max connections to serve (default: 10) -s #x# size of image -i input 0=TV, 1=comp1, 2=comp2, 3=s-video -d dev camera device, default: /dev/video0 Test-link: [1]/image?quality=55 _________________________________________________________________ rasca, 27. Apr 2000 - 01:38 References 1. http://localhost:8999/image?quality=55 w3cam-0.7.2/w3camd/w3log.h0100644000076400000620000000152707103315673013757 0ustar rascauser/* * w3log.h * * Copyright (C) 2000 Rasca, Berlin * EMail: thron@gmx.de * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __W3LOG_H__ #define __W3LOG_H__ #define log_print printf #endif w3cam-0.7.2/w3camd/w3camd.fig0100644000076400000620000000064307112331517014411 0ustar rascauser#FIG 3.2 Landscape Center Metric A4 100.00 Single -2 1200 2 2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5 1350 4050 2700 4050 2700 4950 1350 4950 1350 4050 2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5 3600 4050 4950 4050 4950 4950 3600 4950 3600 4050 2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5 5850 4050 7200 4050 7200 4950 5850 4950 5850 4050 2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 2700 4500 3600 4500 w3cam-0.7.2/cgi.c0100644000076400000620000004463407373452116012314 0ustar rascauser/* * CGI C-library, v1.1.1 * * Copyright (C) '97,'98,'.. Rasca, Berlin * * 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 Mass Ave, Cambridge, MA 02139, USA. */ #include /* getenv() */ #include /* printf() */ #include /* strcat() */ #include /* PATH_MAX */ #include /* getpid() */ #include /* stat() */ #include /* uname() */ #include /* time() */ #include "cgi.h" #define MAX_LINE 1024 #define EMPTY '\0' static char *cgi_background = NULL; static char *cgi_foreground = NULL; static char *cgi_stylesheet = NULL; static char *cgi_source_url = NULL; static char *cgi_loggingdir = NULL; static char *cgi_defaultmta = NULL; static char *cgi_bottomline = NULL; static char *cgi_meta_desc = NULL; static char *cgi_meta_keyw = NULL; static char **cgi_form = NULL; static char **cgi_cfg = NULL; static char *program = NULL; static const char *prog_wp = NULL; static int run_as_nph = 0; static int cgi_refresh_time = 0; static char *cgi_refresh_url = 0; /* http 1.0 status codes */ static http_code http[] = { /* status code, reason-phrase */ { 100, "Continue" }, /* 1.1 */ { 200, "Ok" }, { 201, "Created" }, { 202, "Accepted" }, { 203, "Non-Authoritative Information"}, /* 1.1 */ { 204, "No Content" }, { 205, "Reset Content" }, /* 1.1 */ { 301, "Moved Permanently" }, { 302, "Moved Temporarily" }, { 304, "Not Modified" }, { 305, "Use Proxy" }, /* 1.1 */ { 400, "Bad Request" }, { 401, "Unauthorized" }, { 403, "Forbidden" }, { 404, "Not Found" }, { 410, "Gone" }, /* 1.1 */ { 500, "Internal Server Error" }, { 501, "Not Implemented" }, { 502, "Bad Gateway" }, { 503, "Service Unavailable" }, { 000, NULL }, }; /* * return RFC 822, 1123 date string * next call will override previous value! */ char * cgi_gmt_str (long date) { char *day[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; char *mon[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; static char str[48]; /* should be enough */ struct tm *s; s = gmtime (&date); sprintf (str, "%s, %02d %s %d %02d:%02d:%02d GMT", day[s->tm_wday], s->tm_mday, mon[s->tm_mon], s->tm_year + 1900, s->tm_hour, s->tm_min, s->tm_sec); return (str); } /* * returns the url, where the cgi is included/started */ const char * cgi_url_ref () { char *url; static char urlb[URL_MAX+1]; url = getenv ("HTTP_REFERER"); if (!url) { /* not CGI conform, but try .. */ url = getenv ("REFERER_URL"); } if (!url) { url = getenv ("DOCUMENT_URI"); if (url) { urlb[0] = '\0'; strcat (urlb, "http://"); strcat (urlb, cgi_server_name()); strcat (urlb, ":"); strcat (urlb, getenv("SERVER_PORT")); strcat (urlb, url); url = urlb; } else { const char *server; /* may be lynx is starting local CGIs ..? */ server = cgi_server_software(); if (server && prog_wp) { if (strstr (server, "Lynx")) { if ((strlen (prog_wp) + 8) < URL_MAX) { sprintf (urlb, "lynxcgi:%s", prog_wp); url = urlb; } } } } } if (url) { if (*url == '\0') { url = NULL; } } return (url); } /* * returns the name of the server software */ const char * cgi_server_software (void) { return (getenv ("SERVER_SOFTWARE")); } /* * returns the name of the server */ const char * cgi_server_name (void) { const char *sn; struct utsname un; sn = getenv ("SERVER_NAME"); if (!sn) { sn = getenv ("HOSTNAME"); if (!sn) { uname (&un); sn = un.nodename; } } return (sn); } /* * returns the name of the script */ const char * cgi_script_name (void) { const char *sn = NULL; const char *server; static char url[URL_MAX+1]; sn = getenv ("SCRIPT_NAME"); if (!sn) { /* lynx cgi ? */ server = cgi_server_software(); if (server && prog_wp) { if (strstr (server, "Lynx")) { if ((strlen (prog_wp) + 8) < URL_MAX) { sprintf (url, "lynxcgi:%s", prog_wp); sn = url; } } } } return (sn); } /* * returns the name of the browser software */ const char * cgi_client_software (void) { return (getenv ("HTTP_USER_AGENT")); } /* */ const char * cgi_remote_host (void) { const char *host; host = getenv ("REMOTE_HOST"); if (!host) return ( getenv ("REMOTE_ADDR") ); return ( host ); } /* * print a http status line */ void cgi_status (int num) { printf ("HTTP/1.0 %d %s\r\n", http[num].num, http[num].str); } /* * send the content type given in "ct", if "name" is not * NULL it is added in the following way, e.g. * Content-Type: text/html; name="foo.gif" */ void cgi_content_type (const char *ct, const char *name) { if (run_as_nph) { cgi_status (http_ok); printf ("Server: %s/libcgi/%s\r\n", program, VER); printf ("Date: %s\r\n", cgi_gmt_str (time(NULL))); } if (name) { printf ("Content-Type: %s; name=\"%s\"\r\n\r\n", ct, name); } else { printf ("Content-Type: %s\r\n\r\n", ct); } } /* */ void cgi_multipart (const char *boundary) { if (run_as_nph) { cgi_status (http_ok); printf ("Server: %s/libcgi/%s\r\n", program, VER); printf ("Date: %s\r\n", cgi_gmt_str (time(NULL))); } printf ("Content-Type: multipart/x-mixed-replace;boundary=%s\n", boundary); printf ("\n%s\n", boundary); } /* * send a status line and content type if 'content_t' is not NULL, * e.g. cgi_response (http_ok, "text/html"); */ void cgi_response (int num, char *content_t) { if (run_as_nph) { cgi_status (num); printf ("Server: %s/libcgi/%s\r\n", program, VER); printf ("Date: %s\r\n", cgi_gmt_str (time(NULL))); } if (content_t) { printf ("Content-Type: %s\r\n", content_t); } printf ("\r\n"); } /* * return the base url */ const char * cgi_base (void) { static char base[URL_MAX+1]; const char *url_ref, *p; int i, len; url_ref = cgi_url_ref(); if (url_ref) { len = strlen (url_ref); if (url_ref[len-1] == '/') { strcpy (base, url_ref); } else { p = strrchr (url_ref, '/'); if (p) { i = 0; while (url_ref < (p+1)) { base[i] = *url_ref; url_ref++; i++; } base[i] = '\0'; } else { /* should never be reached ..! */ return (NULL); } } return (base); } return (NULL); } /* * redirect to the given url, which could be a relative or an * absolute url. note: relative urls could be a problem with * some browsers, cause sometimes there is no way to find out * the "REFERER".. */ void cgi_redirect (const char *url) { const char *p, *s, *hash; char buff[URL_MAX+1]; if (run_as_nph) { cgi_status (http_moved_permanently); printf ("Server: %s/libcgi/%s\r\n", program, VER); printf ("Date: %s\r\n", cgi_gmt_str (time(NULL))); } if (strstr (url, "://") > url) { /* its an absolute URL .. */ printf ("Location: %s\r\n", url); } else if (*url == '/') { /* relative URL which starts at the root */ if ((s = p = cgi_base ()) != NULL ) { int i; for (i = 0; i < 3; i++) { if (p) { p = strchr (p, '/'); } p++; } if (p) { strncpy (buff, s, p-s-1); buff[p-s-1] = '\0'; printf ("Location: %s%s\r\n", buff, url); } else { printf ("Location: %s\r\n", url); } } else { printf ("Location: %s\r\n", url); } } else if (*url == '#') { p = cgi_url_ref(); if (p) { hash = strrchr (p, '#'); if (!hash) { printf ("Location: %s%s\r\n", p, url); } else { /* there is still a name value, we have to remove it .. */ strncpy (buff, p, hash-p); buff[hash-p] = '\0'; strcat (buff, url); printf ("Location: %s\r\n", buff); } } else printf ("Location: %s\r\n", url); } else { /* some other kind of relative URL.. */ p = cgi_base(); printf ("Location: %s%s\r\n", p ? p:"", url); } printf ("Content-Type: text/html\r\n\r\n"); } /* * lock a name file */ int cgi_lock (const char *file) { char pfile[PATH_MAX+1]; char lfile[PATH_MAX+1]; FILE *pfp; int pid, loop; struct stat info; loop = 5; /* try five times to lock .. */ pid = getpid(); strcpy (pfile, file); sprintf (pfile+strlen(file), ".%d", pid); strcpy (lfile, file); strcat (lfile, ".LCK"); pfp = fopen (pfile, "wb"); if (!pfp) { perror (pfile); return (0); } fwrite (&pid, sizeof (pid), 1, pfp); fclose (pfp); while ((stat (lfile, &info) == 0) || (link (pfile, lfile) != 0)) { sleep (1); loop--; if (loop < 1) { unlink (pfile); return (0); } } return (1); } /* * unlock the named file */ int cgi_unlock (const char *file) { char pfile[PATH_MAX+1]; char lfile[PATH_MAX+1]; int pid; pid = getpid(); strcpy (pfile, file); sprintf (pfile+strlen(file), ".%d", pid); strcpy (lfile, file); strcat (lfile, ".LCK"); unlink (pfile); unlink (lfile); return (1); } /* */ void cgi_html_start (const char *title) { printf ("\n"); printf ("\n"); printf ("\t%s\n", title); if (cgi_source_url) { printf ("\t\n", cgi_source_url); } if (cgi_meta_desc) { printf ("\t\n", cgi_meta_desc); } if (cgi_meta_keyw) { printf ("\t\n", cgi_meta_keyw); } if (cgi_refresh_time > 0) { printf ("\t\n", cgi_refresh_url); else if (getenv("QUERY_STRING")) printf ("%s?%s'\">\n", cgi_script_name(), getenv("QUERY_STRING")); else printf ("%s'\">\n", cgi_script_name()); } if (cgi_stylesheet) { printf ("\t\n", cgi_stylesheet); } printf ("\n"); printf ("\n"); } /* */ void cgi_html_end (const char *s) { if (s) { printf ("%s\n", s); } if (cgi_bottomline) { printf ("%s\n", cgi_bottomline); } printf ("\n\n"); } /* */ const char * cgi_sourceURL (void) { return (cgi_source_url); } /* */ const char * cgi_logdir (void) { return (cgi_loggingdir); } /* */ const char * cgi_defaultMTA (void) { return (cgi_defaultmta); } /* */ int cgi_init (const char *pname) { # define CFG_bg "background" # define CFG_fg "foreground" # define CFG_css "stylesheet" # define CFG_src "source_url" # define CFG_log "loggingdir" # define CFG_btl "bottomline" # define CFG_mta "detaultMTA" # define CFG_desc "meta_desc" # define CFG_keyw "meta_keyw" char cfgfile[PATH_MAX+1]; char buff[MAX_LINE], *p; char key[256], value[256]; FILE *fp; int len; int cfg_num = 0; prog_wp = pname; program = strrchr (pname, '/'); if (program) program++; else program = (char *)pname; if (strstr (program, "nph-")) run_as_nph = 1; strcpy (cfgfile, pname); strcat (cfgfile, ".scf"); fp = fopen (cfgfile, "rb"); if (!fp) { return (0); } while (fgets (buff, MAX_LINE, fp) != NULL) { p = buff; while (*p && (*p == ' ' || *p == '\t')) p++; if (*p == '#') continue; *value = EMPTY; sscanf (p, " %[^= \t] = %[^\n]", key, value); if (*value) { len = strlen (value); if (len > 0) { if (*value == '"') { /* remove quote chars */ memmove (value, value+1, len + 1); p = strrchr (value, '"'); if (p) *p = EMPTY; } else { /* use last white char as end point */ p = strchr (value, '\t'); if (p) *p = EMPTY; else { p = strchr (value, ' '); if (p) *p = EMPTY; } } } } else { continue; } #ifdef DEBUG fprintf (stderr, "key=%s, value=%s\n", key, value); #endif len = strlen (key); if ((len == strlen (CFG_bg)) && (strcmp (key, CFG_bg) ==0)) { cgi_background = (char *) malloc (strlen (value) +1); strcpy (cgi_background, value); } else if ((len == strlen (CFG_fg)) && (strcmp (key, CFG_fg) ==0)) { cgi_foreground = (char *) malloc (strlen (value) +1); strcpy (cgi_foreground, value); } else if ((len == strlen (CFG_css)) && (strcmp (key, CFG_css) ==0)) { cgi_stylesheet = (char *) malloc (strlen (value) +1); strcpy (cgi_stylesheet, value); } else if ((len == strlen (CFG_src)) && (strcmp (key, CFG_src) ==0)) { cgi_source_url = (char *) malloc (strlen (value) +1); strcpy (cgi_source_url, value); } else if ((len == strlen (CFG_log)) && (strcmp (key, CFG_log) ==0)) { cgi_loggingdir = (char *) malloc (strlen (value) +1); strcpy (cgi_loggingdir, value); } else if ((len == strlen (CFG_btl)) && (strcmp (key, CFG_btl) ==0)) { cgi_bottomline = (char *) malloc (strlen (value) +1); strcpy (cgi_bottomline, value); } else if ((len == strlen (CFG_mta)) && (strcmp (key, CFG_mta) ==0)) { cgi_defaultmta = (char *) malloc (strlen (value) +1); strcpy (cgi_defaultmta, value); } else if ((len == strlen (CFG_desc)) && (strcmp (key, CFG_desc) ==0)) { cgi_meta_desc = (char *) malloc (strlen (value) +1); strcpy (cgi_meta_desc, value); } else if ((len == strlen (CFG_keyw)) && (strcmp (key, CFG_keyw) ==0)) { cgi_meta_keyw = (char *) malloc (strlen (value) +1); strcpy (cgi_meta_keyw, value); } else { /* private configuration data */ cfg_num += 2; if (cfg_num == 2) { /* first time */ cgi_cfg = calloc (3, sizeof(char *)); } else { cgi_cfg = realloc (cgi_cfg, (cfg_num+1) * sizeof (char *)); } cgi_cfg[cfg_num-2] = strdup (key); cgi_cfg[cfg_num-1] = strdup (value); cgi_cfg[cfg_num] = NULL; } } fclose (fp); return (1); } /* */ int cgi_content (void) { char *c; c = getenv ("CONTENT_TYPE"); if (c) { if (strstr (c, "multipart/form-data")) return (MULTIPART_FORM); } return (0); } /* * returns the method: CGI_METHOD_{GET|POST|PUT} */ int cgi_method (void) { const char *method; int rc = 0; method = getenv ("REQUEST_METHOD"); if (method) { if (strcmp (method, "GET") == 0) rc = CGI_METHOD_GET; else if (strcmp (method, "POST") == 0) rc = CGI_METHOD_POST; else if (strcmp (method, "PUT") == 0) rc = CGI_METHOD_PUT; else if (strcmp (method, "DELETE") == 0) rc = CGI_METHOD_DELETE; } return (rc); } /* */ static char * hex_to_asc (const char *str, int len) { char *p, *s; char buff[4]; int chr; if (!str) return (NULL); s = (char *) malloc (len + 1); p = s; buff[2] = '\0'; while (*str && len) { if (*str == '%') { strncpy (buff, str+1, 2); sscanf (buff, "%02X", &chr); *p = (unsigned char) chr; str += 3; len -= 3; } else { if (*str == '+') *p = ' '; else *p = *str; str++; len--; } p++; } *p = '\0'; return (s); } /* */ char ** cgi_parse_string (const char *str) { char **kv = NULL; const char *p, *end; int num = 1, i; int len; if (!str) return (NULL); p = str; while ((p = strchr (p, '&')) != NULL) { num++; p++; } kv = (char **) calloc ((num * 2 +1), sizeof (char **)); p = str; i = 0; do { len = 0; if (*p == '&') { p++; } end = p; while ((*end != '=') && (*end != '\0') && (*end != '&')) { len++; end++; } kv[i] = hex_to_asc (p, len); if (*end == '&') { /* variable has no value .. */ p += len; i++; continue; } p += len+1; end = p; i++; len = 0; while ((*end != '&') && (*end != '\0')) { len++; end++; } kv[i] = hex_to_asc (p, len); if (len > 0) p++; i++; } while ((p = strchr (p, '&')) != NULL); return (kv); } /* * return content length as int */ int cgi_content_length (void) { const char *len_env; int len = 0; len_env = getenv ("CONTENT_LENGTH"); if (!len_env) return (0); sscanf (len_env, " %d ", &len); return (len); } /* * read multipart request * still not ready! */ mime ** cgi_parse_multipart (void) { mime **mpart = NULL; char *boundary; char line[MAX_LINE]; int len, sl, read = 0, max = MAX_LINE; boundary = getenv("CONTENT_TYPE"); boundary = strstr (boundary, "boundary="); len = cgi_content_length (); if (!boundary || !len) return (NULL); if (len < MAX_LINE) max = len; boundary += 9; do { /* find the start boundary */ fgets (line, max, stdin); read += strlen (line); if (strstr (line, boundary)) break; } while (read < len); printf ("found\n"); do { fgets (line, max, stdin); sl = strlen (line); if (sl >= 20) { if (strncasecmp (line, "content-disposition:", 20)) { } } read += sl; } while (read < len); return (mpart); } /* * read stdin and encode query data */ char ** cgi_parse_stdin (void) { char **form = NULL; char *buff; int len; len = cgi_content_length(); if (!len) return (NULL); buff = (char *) malloc (len+1); buff[len] = '\0'; fread (buff, 1, len, stdin); form = cgi_parse_string(buff); free (buff); return (form); } /* */ char ** cgi_parse_query (void) { char *qs = getenv ("QUERY_STRING"); if (!qs) return (NULL); return (cgi_parse_string (qs)); } /* * parse a formular, not depending on the request method * PUT method not done until now */ char ** cgi_parse_form (void) { int method; /* changes globals! (cgi_form) */ method = cgi_method(); if (method == CGI_METHOD_POST) { if (cgi_content() == MULTIPART_FORM) cgi_form = (char **) cgi_parse_multipart (); else cgi_form = cgi_parse_stdin(); } else if (method == CGI_METHOD_GET) cgi_form = cgi_parse_query(); else cgi_form = NULL; return (cgi_form); } /* * return the corresponding value for a given key */ char * cgi_form_value (const char *key) { char **form; if (!key) return (NULL); if (!cgi_form) return (NULL); form = cgi_form; while (*form) { if (strcmp (key, *form) == 0) return (*(form+1)); form += 2; } return (NULL); } /* * return the corresponding value for a given key */ char * cgi_cfg_value (const char *key) { char **cfg; if (!key) return (NULL); if (!cgi_cfg) return (NULL); cfg = cgi_cfg; while (*cfg) { if (strcmp (key, *cfg) == 0) return (*(cfg+1)); cfg += 2; } return (NULL); } /* * set refresh time, use 0 to disable */ void cgi_refresh (int t, char *url) { cgi_refresh_time = t; cgi_refresh_url = url; } w3cam-0.7.2/cgi.h0100644000076400000620000000523107373452122012304 0ustar rascauser/* * public header for cgi.c * * Copyright (C) '97,'98 Rasca, Berlin * * 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 Mass Ave, Cambridge, MA 02139, USA. */ #define URL_MAX 2048 #define CGI_METHOD_HEAD 1 #define CGI_METHOD_GET 2 #define CGI_METHOD_POST 3 #define CGI_METHOD_PUT 4 #define CGI_METHOD_DELETE 5 #define CGI_METHOD_LINK 6 #define CGI_METHOD_UNLINK 7 #ifndef VER #define VER "1.1" #endif #define MULTIPART_FORM 1 typedef struct { int num; char *str; } http_code; /* * http 1.0 and 1.1 status codes */ enum { http_continue, http_ok, http_created, http_accepted, http_non_authoritative, http_no_content, http_reset_content, http_moved_permanently, http_moved_temporarily, http_not_modyfied, http_use_proxy, http_bad_request, http_unauthorized, http_forbidden, http_not_found, http_gone, http_internal_server_error, http_not_implemented, http_bad_gateway, http_service_unavailable, }; typedef struct { char *name; char *filename; char *data; char *content_type; char *boundary; int content_encoding; int content_length; } mime; int cgi_init (const char *); void cgi_response (int status_num, char *content_type); void cgi_status (int status_num); const char *cgi_url_ref (void); const char *cgi_base (void); const char *cgi_server_software (void); const char *cgi_server_name (void); const char *cgi_client_software (void); const char *cgi_script_name (void); void cgi_content_type (const char *ct, const char *name); void cgi_html_start (const char *); void cgi_html_end (const char *); void cgi_redirect (const char *); int cgi_lock (const char *); int cgi_unlock (const char *); char **cgi_parse_form (void); char **cgi_parse_stdin (void); char **cgi_parse_query (void); char **cgi_parse_string (const char *s); char *cgi_form_value (const char *); char *cgi_cfg_value (const char *); const char *cgi_logdir(); const char *cgi_sourceURL(); const char *cgi_defaultMTA(); int cgi_content (void); int cgi_method (void); char *cgi_gmt_str (long date); void cgi_refresh (int, char *); void cgi_multipart (const char *); w3cam-0.7.2/README0100644000076400000620000000512307412661634012255 0ustar rascauser w3cam, Version 0.7.2 [1]Rasca, Berlin 1998-2001, published under the [2]GNU GPL Note: This [3]CGI is for [4]Linux running a kernel of the [5]2.2.X series or newer! w3cam is a simple CGI to retrieve images from a so called video4linux device. In other words this program will only run on Linux machines which support a video4linux-device. w3cam supports a plain mode and a gui mode. In the gui mode a html with a form is supplied to change some parameters with the mouse .. * Supported output formats: [6]PNG, [7]JPEG and PPM * Screen dumps in GUI mode [8]double.jpg * Installation: run 'configure & make install' and edit the installed w3cam.cgi.scf file for the runtime configuration. * Usage: Install the CGI and then call {url}/w3cam.cgi?help * Download source code: [9]w3cam-0.7.2.tar.gz * Needed Libraries: [10]libz, libpng, libjpeg * Checkout [11]ChangeLog for changes since the last release. * Tips: + Don't use refresh=0 if you are not the only one, who want to access the video, cause this will lock the v4l device. + Set refresh=-1 if the image is NOT embedded in a [12]HTML-page (or set it at compile time as the default or at runtime in the configuration file). + Use w3cam.css to change the layout (don't forget to install and define the URL in the config file..) * Problems?: [13]Mini FAQ, and also consult the included documentation and HTML samples. * Links: + [14]Video4Linux + [15]Video 4 Linux Resources + [16]bttv Driver + [17]FreeType Library + [18]Motion _________________________________________________________________ rasca , 27. Dec 2001 - 18:28 References 1. http://home.pages.de/~rasca/ 2. http://home.pages.de/~rasca/w3cam/COPYING 3. http://hoohoo.ncsa.uiuc.edu/cgi/ 4. http://www.linux.org/ 5. ftp://ftp.kernel.org/pub/linux/kernel/v2.2/ 6. http://www.libpng.org/pub/png/ 7. http://www.jpeg.org/ 8. http://home.pages.de/~rasca/w3cam/double.jpg 9. http://home.pages.de/~rasca/w3cam-0.7.2.tar.gz 10. http://www.zlib.org/ 11. http://home.pages.de/~rasca/w3cam/ChangeLog.txt 12. http://www.w3.org/MarkUp/ 13. http://home.pages.de/~rasca/w3cam/FAQ.txt 14. http://roadrunner.swansea.uk.linux.org/v4l.shtml 15. http://www.exploits.org/v4l/ 16. http://www.metzlerbros.de/bttv.html 17. http://www.freetype.org/ 18. http://motion.technolust.cx/ w3cam-0.7.2/w3cam.cgi.scf0100644000076400000620000000404207343633116013641 0ustar rascauser#SCFF/sh # this is an example config file. if it is not in the same # directory as the CGI all compiled in default values are used # # options which are used by the CGI library # #background=#ffffff #foreground=#000000 source_url="http://home.pages.de/~rasca/w3cam/" # uncomment the following to include a CSS style sheet (url) # default: none #stylesheet="/~rasca/w3cam/w3cam.css" # # options for the w3cam program # you override some default values in the following # uncomment thinks you want to change at runtime # # when protected = 1 all form parameters are ignored #protected=0 # the video4linux device #device = "/dev/video" # image width and height #width=320 #height=240 # color or grey JPEGs # could also be used to define the palette. possible values are # yuv420p, yuv422p, grey, 1 (=color), 0 (= grey) #color=1 # refresh time in #.# seconds, "-1" disables refreshing # refreshing doesn't work if the cgi is not embeded in a html page, # so it is not a good idea to enable refreshing at this point! #refresh="-1" # norm, 0=PAL, 1=NTSC, 2=SECAM #norm="0" # input, 0=TV, 1=Composite1, 2=Composite2, 3=S-Video #input="0" # format, 1=PPM, 2=JPEG, 3=PNG #format="3" # jpeg quality: 1-100 #quality="30" # mode, 0=plain, 1=gui (build a control panel in html) #mode="1" # sleep micro seconds before capturing, e.g. 500000 for half a second #usleep="500000" # define a frequenzy for the tuner, 'freq' must be in 1/16 MHz and # only integers are allowed #freq="9076" # list of frequencies in gui mode #freqlist="878;9076;9844;9460" # for timestamps; all keywords are only in the configuration # file available.. # to enable time stamps as a minimum "font" and "timestamp" # must be defined. # #font = /usr/local/X11/lib/ttfonts/arial.ttf #font_size = 12 # # for the timestamp format string see the strftime(3) manpage #timestamp = "Berlin, %H:%M %d.%m.%Y" #timestamp_border = 2 # # blend value: 1 .. 100 #timestamp_blend = 60 # alignment: 0 = upper left corner, 1 = upper right corner, # 2 = lower left corner, 3 = lower right corner #timestamp_align = 1 w3cam-0.7.2/w3cam.css0100644000076400000620000000115207366313424013116 0ustar rascauser/* w3cam example CSS style file */ BODY { background: #f0f0f0; color: #0f0f0f; margin-top: 0.4em; margin-left: 0.2em; } A { text-decoration: underline; } A:link { color: rgb(040,040,238) } A:visited { color: rgb(090,090,200) } A:active { color: rgb(153,153,000) } H1,H2,H3,H4,H5,H6 { color: #a0a0ff; font-family: fattip, crillee, helvetica; } H1 { font-size: 22pt; } ADDRESS { font-style: italic; font-size: small; } FORM { background: black; font-size: small; } /* some classes */ .panel { text-align: center; /* font-size: tiny; */ } .image { align: left; } .footer { font-size: small; } w3cam-0.7.2/w3cam.h0100644000076400000620000000204107373452156012557 0ustar rascauser/* * w3cam.h * * Copyright (C) 1998 Rasca, Berlin * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define FMT_UNKNOWN 0 #define FMT_PPM 1 #define FMT_JPEG 2 #define FMT_PNG 3 #define IN_TV 0 #define IN_COMP1 1 #define IN_COMP2 2 #define IN_SVIDEO 3 #define NORM_PAL 0 #define NORM_NTSC 1 #define NORM_SECAM 2 #define MODE_GUI 1 #define MODE_PLAIN 2 #define MODE_HTML 3 #define OFF -1 w3cam-0.7.2/double.jpg0100644000076400000620000025002106622562127013347 0ustar rascauserJFIFC  !"$"$C>E k  !1"AQTU2Vaq#W347Bu$5REbrsv%6CFe 'Sft8cD:!1A"Qa2qB3R#Cbr‚ ?p}) V,V L-]oj1q#ɺۈe*P# P >n'>qx|^3>on}Aצd>צd>=.]qڜu_)ChHR8I&k%ZY5! ;ZPD%D$ 0-:.V' `?@ɩXwe6]s[KlʀZRԩ%$x Pz,@bUn"kLS_;ք( VOpwzv~Z︼>/o>t^>^>^>^>vwLNyt>&ngg>SMj}tMj}tMj}tk$^zKm"7V3Cn\F|ߧ('mWr-9ڬ+86,@bwvSe5ʛ|E+NAJRGeMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}tMj}t$T"&HmAQPJ@% vnlЗSo(i=RJHA nDMjiqƃzJ>#@e|Gڟ]F^{ާxF’ngi/7?99cP/\-;\{rouCݵRe ϲA }QZJHmOE)nRQ>@h3s.>j+EDב4qY[a* P$RX$tj9.Ssk'_2RQnvs*O? 7Πp-5([b%ېJׂ \zfm5s [5ѷó!m,Lw QZRJ6(%d.$ف67žJT%!H|e(/wnDCBbk:Yvיt-N=ru b*ie|T)hE`o;HMfE֡}w&bkvP}:8E) zvwh.nmW!N%Rrt *BZIJHl מyl G$\_}Qw三+%8DrO4)RQT[ڽͼE*\۬.iT̙2Z/!r[睥h F&=0nlܸvKAz ^T@yO%J "zcrT_/CWi;uITrm'-]IGwr@;dſQܲy(YyQ<Җʈ$c##) ^f}G^> KM׮9⺴,uܬɮΪj5X؝);۝wc͡ˇ:櫽_,4}zoHSBMj}th$nɐn%= ]h%`g ;n1͒!8@Rڕ+Je$}#[51&+a4w$+nq>'.]DYf|Gڟ]A#Mj}tH.e5_ ua %c$0=:Oy/*D,+.fKr:!NFy$צd>צd>Zm-yu;U#*yW9IZoߏk|&JVoυөviNξ(A;m6eM4gM6|^>ꄑX"&LBV\L94^Hܛݯu~e**o[,.['IeJy nW\)ZUȂr sf볪{?)Ym|Gڟ]bXuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#OuY#O\f)[J\?Mtu[oE[m91ǼR֐v(V'e&j8H,m/)a|Qs##ȍnY/DywܴtƮ+HEcޭM6^#=8l_-+Wrv:=O*KӯqBWsO /DpՖ~9>1?*ˏpIc&RHy" JF! T}edj"9`w_ f\˃6m.=NJnq?',魗nziJVSpw4(2vj ]Ϯɾ΍iSa;Rvjp7 FeSitU[TjCwV*U|6[*EE׫>08#lB@g>i:[skUaڌmիÂ錅%L-kQKC|M$'qMI;-)sYR]=]_k7M\s6YVQ7'ITew3u?~%Z Ap9{@I!|  RB*Bt<5.26ݫ_M[jG&u勵޿z2daT2)9y;@P*#R:qeM(OWxܮծ,kW=\$[)2$c Nؑ2Of$\տo}ߖO)s$MqwiӞqtT}yտJ8{]wOvd!u~,yaGC(OG?ttOl?7kee.V-+e\5,ț;iz )dN3Aq(iV>nj 9sܩ7\Қ L9k9v6U)$n J]^ Z]*J-/fv>۷e6"iu%C N/t!.\LD7NH*<2Q:HciXNm[dVc o|rTǤ&F<]>*{VғNԥ9s4]EҨ"IBӔ(nJ82@#a v}sβMtCc{+T]2i)\T} g}^ājv=^ƺ*mKpRquECJ# ,juÚxI1{'տ*l.D?pŽm.Scx].vd( (ѢQ}{jmm@+M]ܹN1lpI@Brydx+īi$.$bLq7fcB\s^6iQRs<0<huNj7dV\ڇ;Na oS2Gv{0<.J7.Qz*rEu*:;wUF6d'f%Xp.~u͊V=*Χ.IzcQ t-@np@`< ?eicϕ''WOUqoQNWTIۤRͿSu ֻw})%) 'sR|762P6,'ҿ*3mƜza&d$ΈIb7uʹRGM,ڂpL.$䲘Ґ#ee$~*Q}iI|e}o˹7'YQUU~?6ۻ}+ AMn 뵵$ڙpӍa *:xH7{hIq(y=T=0Nm'O_TSv?zz4Nד8pcs{x\G}rAWDm'|` Ocj乆c&RJKzdGu[6օ i8ﱌ+#ԩ<0uK.w~4MFQW#^d6?\w%0P-׶AJ%$@{9;y~_+_Ho jrM5޸vK}ҵ}7h)"I7;yO}Q|=ZAV$ s8=9sy`oͯtէ ͍ISiO]ؚ[k+ 'H*sK!\ moU%/ݛU~>=qwoճ~eKZ[p;K%d)dK浬bcW/veCJ` ~:u\Ϲ 䄧-7]zᖢ+?m2:Ի ug+lƝĐA#)BqϴN^29%%ΎvIn}nuی4n6pQ&mtJLro%nv[ieG׋7, %֔T) |9,cVfo\;fc6s9g$|IoU Dwmo< RpqDH )@#ׂ,yNjߵN|TR-;8Ke-Ojל [n2@Y,~,3=9[[/~z2|)c~"bJI!J H!X)8A 9~3aӒmvMMq;GW ԃL3>,^ c9r{zxֳ|km4\>os2ΠJ ɭG!,%T<=z9M/{I}~ϫMVD7\vdyt]fxR4aHpAFpץɉ%ꮻImߗs98D/p:Nnxe%i6Bm(;iPS`sE';{=xzo\]blCMc%:~r^+/x?*>nlw;yP @(P @(P @(P @(h+KSXqg CR@p-kѦ46DSa.-G Ýz@8?㩊Oq\{|kt=ϼ<CJޝX9srA7nњ{7oEhY4ծ+%EAE}#q= c'm]nvryX]i&QA -[(i VV&x|{mW 72xLD2FF|=d`YP%̲=.'Kdz\Om@82ڀq.>eq=\|#{jĸGq,KYP%̲=.'Kdz\Om@jN'*vDyK1_Ï*M|x[9Ϲsٞ$/kYOMsY%ҿ~MqME|XY @VY?_~*ꕧ{Ih}N ml4:iB$HPzzb82ڠ\|#{jĸGq,KYP%̲=.'Kdz\Om@82ڀq.>eq=\|#{jĸGq,KYP%̲=.'Kdz\Om@82ڀq.>eq=\|#{jĸGq,KYP%̲=.'Kdz\Om@82ڀq.>eq=\|#{jĸGq,KYP%̲=.'Kdz\Om@82ڀq.>eq=\|#{jĸGq,KYP%̲=.'Kdz\Om@82ڀq.>eq=\|#{jĸGq,KYP%̲=.'Kdz\Om@82ڀq.>eq=\|#{jĸGq,KYP%̲=.'Kdz\Om@SzJn]&r}99"MӱkK].O$'n;֭Jr7`f/V.zܭovnZvؿ",lPkKi'a99LŦ n.MG4%7=_UP @(&LƜa.?rvIZi m ) I).-$ٔsBSxU_Pj(PR %=D6@{3I>|c:,3psKc'#O.V;PlD O9;Mi:8()'w7uC̸q!HZRyM:gTeJ.=аP *^DGȚ&Bf| 'O߬gEnilp6=DtWgpP @("6Xٞ7Ɛ{ Gn>uOR^_ԭfw @(P *Ѩm[&$xGIHȑ~'pIrpGM,Xn<]+Y€P @i^gx4cQ$ 5|x]19ZZLO.WI}R2ۦŸjl'w Oa|`..&3ύd,ب5P Jtg;>{[Z xI,ͪbbyrKꑖ6- Sa>㼝Z{ VQqt4|k&7qfAzcrP/wGmIB/*40O9}q|oV iM*,HpQd *=e|=β;0w~kzz kxu6vI)`K>tstz Ո[y/'6"o; sAۮM)S/iR{-_}J@wOkyvط֣B{P&:ZeTO77$n)޲6%\t5EEXr$\-:Jm*! qqhlHpQd *=e|=β;0w~kzz kxu6vI)bK>tstz Ո[y/'6Ƽj:xoδN].-A|%+y)cSdSP^^3__k>/w9$.F,Rd)g+JG,r@pV/7Omi-bĥ?>S%HSʹ,THȠ7[+KΧr* ɜ.<]M6lQonsE@k'UR{vmn[JQ6Lt+UCJ2PL^9zU,YiϿ-%[V ;8d$5Vmj5y'M:୰YR8|C1h1y?%ݳ$j5Qm N pv9QJO$4?[t]O^\~ OKZtGS˸ρmo|9I6N<HXʔ6jp&RrvϿà k5QE.׸KVD+5xNO>2($!HSeNq[ (UMIO'/uɠ#7c-q5]_0~-)!`a'iSF*vu3WHl%i@ vʐh5(|LZGiqm*y \Qlmhe\ⴅ$qݽYqI4}@888 ۋDxILwG|rUy۞@L;&6 TB옐@&HmT8X- W!Nw!85t{D슝UmA0YʻԸ  0v:}I'&O_'c{<(+f-6EyY}K6z$b>ΥOSr6 $U`# N}1=?5|%3Rl{IwȗL tYn%FpHk"otsx;2EȎKbS(eJʈ%J]9'8Lگv7P}6fP$ /8[Hܠ,J<{fYl5$5:X)e$؎  nv|L>@Zc,ϪbbyrKo{Ԭ„ZOVeqXFURz4O^?۱9Kne$d<\G<$/&IdTh,X%~*6x.ՠVâ=/e4m% _$)q'H*Vo+_WJQ3^GwcyS{ x)W p.]C5\o7KS͔GKd6 8:TKZ;m gD_/w[_[L8|39murwEd!YϞi֣HkLx]19ZZLO.WI}R8m|ڕP+Rѷa cs+ʱJR}OF?2T"[v=#{m̾쇗ˈGs$,=-%V>cKHEFYvƆ>{RH\R2RO#C3ӟ&pH]>NLCIF;R2I9R@Jv v;eG/q78=T8#@ӷwc&BJ\&P8JDxK -M6ʂY () =☛o{rWr2F?ifJFsp}nme,LI <2b8+_.M/vk="b^0.qq-L@P g漣Qgkf<KEj:kJI@,@hi1oW.?-}w/jڕ9ٜ3Tm?tحn+,bqxI&sg~?Xpq3v@e<8ĈQ[iБ "?I1&:.?:CKSMH )Jsp|'e&䱵܌iYDґDÜ\[Yy !)SBH#c<# 0kk~?˓eitHhWKŽm7fbZ\@V㓞y9 MΘDMc0hGFHPK$c7\I"U*.Rm0ؒt)Є8Bw%ąPs2n& @SBZHL| p;!JO,r$vj:\лCs>CϸO$eE![{C$)=JOxR*Kw-:cf9-0eiB@ r#f+ ף}y\w h$$Rr< #h Rm=k[`Gi*47awޞ]fg$H6cqNEiBZHZ#ޯ YDLG8ZLtI[),r$>-onj6Ï2I8J@$@TAɸAv$ 9*cѴJ9rVFHÙmgn=lTd˥uoZvKx/J[;%+H|Q0w`52:J5NV+]Ԣ6nvqdzwOÀuwc6R@N\p<nAy GQ(C=|J8[-Ϻol鎣oŵroMq'%Iqe\ʁ NНj%8vO/It垗S$rֻB%,'.J3;}dm`zcL%!ێ BJROid4&PbhKI y)ID@b٬ȉ{Cĵ2:BV@(3-onj6Ï2I8J@$@@#QF5qa#g<gBIO>``s O.Vpqi_f׽~DFEo2Wpgpd$c&IdT4zſک``}RWdj-K][ʻ'طU, vOoX?*bT0~U>ſک``}RWdj-K][ʻ'طU, vOoX?*bT0~U>ſک``}RWdj-K][ʻ'طU, vOoX?*bT0~U>ſک``}RWdj-K][ʻ'طU, vOoX?*bT0~U>ſک``}RWdj-K][ʻ'طU, vOoX?*bT0~U>ſک``}RWdj-K][ʻ'طU, vOoX?*bT0~U>ſک``}RmhJ}*J4GH?=ˎ߭H dO2N<$<$ؼHp>c."ӡpʓ%ImBn9@V┃ɾGoCHvb?ɱEfI. g6]6˒{r8Tڷ #lBBPt'z֗TI)qxwb~_sz>d0ٽϡu'8ldd#'e_ЪcZQujc]LanNSIQQykbHF谵z\_mִ8QVҤzH;II#rĹ]B9FHCk T}?#ՙOD7%5#iEŅ!ǀ*B\HH+cuG-[#[Bgˌz{SIqYہ>9;ghm 32kyNgnTãm猌_M|z~_M|z~1{8֚-(%b APԆ'eJSnkW.VZbS AK!bK'p@QPXH~G7G7G7G7 51oڎnnDK+J}G)BV㭅-#jA^BTKjڕe/N= Ufj7#whZ[N#, Z! @ObIQ$a' mi+|[ACP K +;v+ f/N= U/N= U/N= U/N= U}h}eGoN=*J%$$ PG7G7G7G7#/}dwսIɅk([$ CM @I_'mߪ{_'mߪ{_'mߪ{_'mߪ{_'mߪ~9s$: 2i [BQJAVT/N= UYtD;#92n6Si[BTPZ_۔$ 7}5vM}5vM}5vM s"3ۙhj (mD})ZBTiH_y@[=鯓Bo@ah/gI[:JZ# $jB`ܤdte)|5]GŐ,N2K|B sXN{UtE5E7vt|[Lƙ ?c%\2-`D@L_'mߪy(θRk%(]ie֛q`捤+7^holYm .3ҘkeM%gnC_M|z~b骯Zqݶ]_+!nS/-6E&;1G7G7G7G7G75zkN")h,!;O@T-L)e?|s]{T9@n|y[n!cr1ΤܯwYsQc:wA9-U=wr6>3;^m?;Ol_T$I,ND"q<QFNsg }!9)}g_͑t!wY4ޣnr~T2R{I c ", 8"hͤ˨µ86O9a)^[!r[zU@*9@>_Y 4zڎ>%sלtN-j[h3XtZ.q"WӜVi؜*՘QcR}q(Z"칕.Hj+~O5n=O1l3[:IYhP_zР'm6 ]CNs,%8Gѐ_g' AZZmCiKV,ܠZ)M+ڴuBH G%1cŶK81$@So!)H;;I<4 Vǁ,Wt޳k@b+FshuB9,Q-UknM]K,Jr;;rr R-‸9cOjCKe8H%![~6܍?R9B۪WvGUCt ZJJuVBT\RN:TJBI_ 4x7!3RK~u'q'{t$m. ؐ8);BTO^}^tݏN3U·[(RTː¶l18 +n۠s,wn[A(qA}p4KMhk5l!CCj'Ɓ!pn4ėҤqI$kW:驺cPH;wj|%Bb9e- ֠ktKR$&tmśkPhuvtk.X [o-D`C4=].ty5s ͑B"4o͜YmJihv0玲t@e]Nͷ[ta%%!KHiI> P#0iw~zE,oɻ˹$ۖ]RJr;ocਕ%jr@tCbtzmA%;.iaxQRfPtT-4I˾bru%c![M-^Gl +[tۖ{)1D8' 2HWuNm c닞N<7cۦ ;gJ /!*s%@th#0nk:Aڜ$`"bOYpdC +VPѨֻ/ɠ9؇m{ n2U' %t8oaLHrsFpsRnܯwPݭImW~ֽκk_sxl4ҀjRG͟u?Pg06[$2ߐZeZRv)dNɡ)7//CkhwXz?PǸMbly/?lANUGR/ޔ&bHpDgn_hyY?@+ݱQvPMF LQ IhO؅뜻\-dυkv>{7')σ S{i_K5}M2&NZD֡8#ԑ|"NK3X^\,Rr͡@TxIxr'N/4`Ƌ$\w*u9ϼciW#9NG7΅ ڄ]0M[L7vߟRWN+ i}]-RTu,͈+($vUq'ʟYwgV si I[h۹iTrSh(NԪr=w1mnp/Np8걆yaXVUhZ-MK_B6s5$ #o<zGU[8&n_:e >ǃu8mt1up7ns9bKGn$05Kܟ.~dbbtSqFK[V(N9PWG k;vyK-ǞX*(p9JITu3Oz?s5d}闱!L* %Gp3O2>FO3nެCss]ܲÑi}Lۼ%ۺ\ ۵P>,cq}2ZcR,O]lVa9ޫ#ˑ9|Q#WJ F^rlp)@Oa쩴UKd5dV8톹w@u)ө >mں[tk$)qH @-0%1NÝnd!KeN!i*6&qo9rgU(u#Y/'p?RAVKA*\1T|a]zSK%.$I-(~PZ0>ˬ:Z}{RGГP @(P @(P @(P @(P @}W?bS:W5 s tx<9?5e*Gpo֣rHSgyg<|HEQjHx%h H<ʪ佤<4?8%IG|9x$xTO~$UKd#vR.g dx{j,?BO`=;1H5u"GB[@ @ϳŌٓ⪶c- T+i2@y?^*#]-os<Տgg'z1OX4޿RLeCOoOp_|ύJ mG!Kur) y<WZ[(EHDfm 9Ox0Dq- H: ]7Ješ9 V ddx-V*2ǶܞB\qH vଃۜ}+'67Q]uid%{[HG25l(gy):CH N{R Wn#f7}`!t({_9H+k(2;s*rEP.v/:C-k!$gi! tu)luG)LdLZ RJJPR[+N])آBqZE*;5ge)i6BNݿ}Hi($ "Ҋg/ "H[ `;0Awk mGil\/۸=7dqV§qă% `fXf^[Lk ?-٦2* m8 U#;!}m-HHZ{YHu@ 8UJ2JR0j0= Hf $ w矋QjIP @(z:7OA+GwE{o5,#9ʂt:yUI#~{@=o맽T~{@=o맽T~{@=o맽Tvj։^E<--)EYr|@W$ ˎ@J%+uVj EpZw>>+Ir[£y>N{s+}m.K>\5c[lvyO*)IrR4lk̻tG %\sbHJU>s*)S#tt7om<<n5JN*ɦ}89dGN,';FpN1!Dg|U׎7g&] 9. x vc\|?ٷhi#p,}|j>U$7I/g|\Y۔ƛ)Q0_y#qqAQޑr@'v޵l+ i-4ʸˑ%qeǜ2At!67 $;>$z>F%?k)qpL⒗KM|)Vܦ”[NC.}k M;%xJFDc# A' HlN4N#Lv~aP [A)B[ZOVlK /d֘O TQ¾QUfa@tHL觟ny:vH|-:Ždpz}^ŏIjɐ⛎ܖ{h'!\+i}'j8PG;T^Ug&2i9+rUvH'^O_*~KH*?C (>j^O)$h\@$i&9Qm`ק];u FRk7lҐ?:yrn7['!Z+XYT9c|uBkCNO-}<3=7d;<0)ug]]xyیPKS <8 Q$c`{+:؅Ne֔uԩq%I<Qe]D̋k F )ڐIǴQ9;:zU޴5)ju$)a o1r|U`Y' v +*x:W>ڸ.ppR{h*,i]ѽ͵ޱz䕦:ﶍ)!)Aٜs=a# IW:~y<8VCi`% z,c9˜w:VtZT9lIk~s;9$.Zi#*w͊js7b0q7 'jxx;N9 p_q+lk숫v'|ήB“V짰 /|)plorQ:X\=^۸w{Iwnh?9]h0vm %m)iZ@ ;d$ }'oM^Z׸1eM^`%IBd3 `+{0U8 S]lvźFʔ }7Yl'?z;hZ@(e%bRVy=N+qZS@'?I4ܘFFR{(ʰG>x?P7IWV ˎ\%A)&;FQ G"Kiw8N/[}SO4(%mh%%*YJj.2OlۥZgft[LDS)¢T\R80B@ݷq9v;ukaMi]:B_R9P,!LCre3b̕ByNPQIpi)lWըr؃ Z_-X$)#r @I) %ҏȟZW,iu'> xI⫗$mr֪8-Tf-m,-!@JrqUD{=b6]/>$If}T#%8/Ip' ² F@yv 6C90⸗diC=\e-B75}`~[[$ݸ 6+iĸ݊ą%I 怅!r?)S ~:gY,@@P @('I\J8WOKK/JNRynZ%f*n\gu)29,3{MUIfi;L),kHPWH"ߥ[+EERRV-óg =[ߐ%[ ˋۜ @πUe:獙7'@aZDrE'WcyP$c+PW&5cNY0dH#jx1ʤhmNs|}謥EZUjlx[R;y?@;>K~s@;>K~s@;>K~s@;>K~s@;>K~s@;>K~s@;>K~s@;>K~s@;>K~s@;>K~s@;>K~s@{niZ i`E]P @( ]TZl[pӡ j&;I >iϒ߬Piϒ߬Piϒ߬Piϒ߬Piϒ߬Piϒ߬Piϒ߬PzDu:XC|MN9<P O*.;(pyYd3P (z!xsB >^:FV3RGl3YI !)M^,޵egu8L-K*!ϩʱ-M[]]ov @:h<*g;f^ViNS suLë#163ޭkoG)VRȗRݘҐ焟T{O3[,"cӆ{K=d2^iTR-/rJ-O0ɡ'k#Ku*Nyrُ[_x*[Z ó Z˥xe!HS+EZjJ9vvuŗNÉqZc KmG)NO?[z*x*$YrFͫ8rR]D7KU<:UQ+r @R!96m]N-wC/DqԭiqAJHTQwUH[: Т<\PWUd"Z:?mnIjKM22TqI@'.fY'h˩˝ҸEN(8hXiv痟2{Tv*?1RG GUC9zx>k)pVōvW:> `$6#oʹ΢F̽gC~Ͻ*5˩--2mb=:B ɐ11[Iu#9j:LϋbEMNdB>6ێˈ)ZVR܂1ϟ]rA4GWmLBxRw0Gpd/4fzޏX̺0Vu9mmp=Yݨ Iv't,gfjZߓns]d\9)$-%4n^[h/Z%u=Y&MbŎdVwxz<⧂S-ڶ$ 04sV6z}rhz$.)\Pqaڃ)Kl-LԶj3D{)} i2crKBۉ Jޝ+8 tfkף;$-mj2 u~1 B`Bwwڤ W$hnf]*27sq"*AsNRTl SMii jsz\}A'O4ҹm+r[ېc%C)Kl@smk 2Ke=5 0xv/r@*Bҡa?}R" Moc-{ğ"pqvLL@ 6ϸBp +W,L/ .AwaJsWU,rh>>XPAi_sm4n]=Mc ||I5to4P O*.;(pyYd3PdFt~#VzKU{H蜵''5N_iU-2k|DT\:!˺kxE!w,vГWwy/r+QC:$xGp1ί$Kl~ᩘ 2& H'8Xζ=zEJIsY(R8w6C6ץ ce5-)aq`cs5ϒ<י[TSҋ>G (R>7vuE@jK[LuַSA\HTCcÞkЎUa(GDLb'(2~cUg4"d)K3!&(ly 0G2NΘn[,2FnI)Ч.)I琕c#95sM;:U֒!*Wqa9vRvLiR]~tWBM6+YTM.Ԟ#BK=2hi7cΥAKX ޅrP=x@*}SV2D%פ9J BB@a#(6YvӌÒ{-mG-( V%@=mp6sTDUDtl]WN+$j$j핔U&BKiCᴡ;@͞|Zpݒv: ӏ+X3IwJf>Mi&B=^:5.A T;2M]jw~Nr+&mŃKjuY ͶJ/g[t)p))yv9I!% InLq,˹['R#\b3 W.jG*>Rssrç]8\'D2 9*.:a%JZiCJ*BP.2OlۥZgft[LDS)¢T\R80B@ԷWS6n$$ ;qNII>  Zmtf<%=x}A+B\1cdvn;unwvowGo6r{RgIw˶Gf^c&S䔗V.$  ^!4sͻ4VT޽ + BF[(\JG0ɽJӋm 3ZXVB9##$`#XK6ڬzVⴧc(62O~h 녹0:#4Q`|@64o4P O*.;(pyYd3P2#;g8^nR)ʗ\|3ꠟrvԤ ?!U#,In&YQ)#5FJ_ukb]֓d޵ }Dss%'-EJ|5-n|5N_nWi+ Dyl崏O|1ߎ}Ki. I6$v~u|4i\ҕA#\9~1eo&4:*29(ۑsZcJj2839HL&dw$K.RJ|#.G';:E#aْa[aQ)O5 |b৔w~5wͺ }"6```u;&i)M.}R!ȵ-YzEpQʒp' )[BS9_=A6, ^[m!@c ݚgۏIwWc)0lV'KےJHO-$r+:ƢmNNޮQVǞr$RO*#?$]\RtQwM\BԈL 8O w!?1RG GUC9|ٗdJ )թHBRTTs9ʶ;t9'4E˳6PJzV|I?ϴ':~v}54v1aMQ)%˔2x{Dr7&$RfkeQ[keq1Y`l{~Eۢ%, cU-v ɝX^nS_aJqsiһ s-6 W0%uv/ 8F@../Z$c?ﹲ9˝J܂e-PUs= ⢯c羚}MfЋ."ᕔ:Qig IH$bduG&S|76Cm:ZZ(*ڀ'ug,p$65Gp5í&)9CMA+95ErzVZM?:$-}mM1&"dd:+*xyxlزX4[Uյ Ah #=Ze;8y@nʎ;?OIR ; @I;GRhj6S?'"/g9Zc$4Z:'$\ ^" ssIOh+X59Y^܉ Kqˆm* brF8Qz_ xN"cjgy[i^Ydiq\@~]"5l/Mk fs!Z#sd:h 'YSGr)9S]IAaE (`֐shmpa@}@hUj&r"iqԩ ##|`ט΅cV)1Ö۞TrD8ʃi)aeh|M:b5mh!A`w]e'OHz?Phkm CKSe$#%WřIiH,mOIH8vv~M_ H[6fAq >.___߇w;LJN}=BS^{AbQ[}ϢOL$I#1A?.WؠWY(P @(P @(P @(P @(Pb}ğUqD}ΣUC!€ KQqHb-k3ːTڂ7J-:O.pyYZ%G[yx+1"ϪoV*BjӵTrF+i H;j!l B-[M8[<W]6^= )BqN|d 7YZ^z Py/9Io*zV2WRrCŴps*QIw#6H9tIR oUVOggW ʮ{ThI:˖IԌ5 JQG?|g:h{+dq'6}XFmNHd0%.L2M|vFAV?Qwg̺fyfȏShKj* ~>|mLҋj ׃ Nŧ5; cAJ>,v=xhFTNr9|7EʸQ[m)•i y&2hߡ;8mӖfF[ 'IHq-LzY +l#p.jwQDFJ別EIHB 㐜B9/,E1LϽ<@S~I`$s5X6=AlꖋDHdvrQsϝeU):M-m*]']8e&Plse^910CEjA!$1~1 g3=S#8u ?Ź/= jc<+si?VhJlQ qҝ%9f}坹[.F܏QJ'&6|(:>_T0^6v< c0s%8y = :-*ހ{˓Bq榴 b[{֯b- -)+*G<XXIJ*A |٬4>r:B@O *'$*V8g:ٺz 7_Dɒ䅅`6ʂ@nw+?UVx3Spq-(''N;k6ucS.ky䖛RR;֏FuoNuxos0*=*ɖ'VG C7-#(g|j@Gι1߹ܕR{7xrQ6Qt,OĊU P;I.cYuϲ;!l$ N0||1œA(ZgR+ ~Ⱥ5Oq544'h@u$e 6U":J)^1ę9d䟺FBet}y6GӴ$}_Kx9t @(P @(%?ALP{AY;\f cx9p,s _jGP+VW@mZ`tmtV Tt!$ ;aQ ϴJ2s?5sGMDEnM?!pT7&RяE6ȼƜD,FmDS|xFWfH amurt<2ugF<.N撯㊷)X.-I$gώgMgзE"cLɸf8.J7jJǩ;gfՒqEmc:͚E”c=6% <X}+䫳wn9bR҈\YC)0p6 $nH JVN|ee.Yd/A~4Z:RVTyjS2mG~BSpm.`^cRuuG-7*Fs{|5IC{Lr{9[rP)?#pPp Ud͛﹆֮JVTE vw@#D|7o-0J_-;lT>F*UdL$K q!Óϒ+LXۊ٘t[Xk&Y-TGj8 egƚK5To\yipsڐGc $rM۲*(P @(z?1@tvbE,Ľ̖璇[ H[vɋB?Jҕ A4/M.v~TL!rvDDp8JˆARG~qWz35}uϏgG鉚Xf6U5X)4=ma.4BHZToMލҢ[_]-ڧSFu2؊ۢ2.# %a)JTK%NH~ѧE7gˍL.n+&6qE-IIHu) QB]5(խ>P @(P @($ ˎ@J%+uVj пq ־-&-sW`OIݟkF$0ͽ/"_['R0b;a[n eή4K榙2;Q}I$n{k$B=m3\;+n'g.O!mqHt٬[Tʲ{["j-c8V{ i=c -J~ίr&yd|ت5F# 2JvP - ' N7%wCճvqd91c,s؂TGJhyll^X?*ⰴ#sw9%\FC-)![{1:Q+efu@HPNpN|G3ٟJGEةHm);?7\fgoJZs>XZc{w_>䄵L`e֢Vr+i9s}i IT*I>0ynjn˺[nKiQW 1uQ'R؀- &L'XCm6z*p [O3"u[u^3x }oOc}@f:o3.&.sQۖn6aN-ZP Co—wΒV⛜ES< a{K͡!,r\ Q$j Je1cGF՝i*RBRRԣ(WocM+kmI%>P @(P @($ ˎ@J%+uVj ?pQ^ex@H)_"y|՜Y3^ Pط~ٗF#wfʭ0dlۥHl4<>a6sKIYfmHA&|I%dR%Xy`c*'㊫Bm[ NdsIOcPMgb٩$TzCէ1u3`$e[fNVt:Aq $@s*01NV{ }4LOյ)+ 9}$(:%(0|紾>J/KM ړ\5(VRբGKG)y'zT:.t1so%+jr.un5JꖒbI u|S ܍fJI|hYGy࠯3Y.!G{d7']ʇ-L-ڏ~퇢˜f=Wpo99Sh <)JMyɬ;fPrcG*cnLZG@{'{;YYvRc2dLhFr?9#Q&hj%VS‚W#s8g 7Qg]!=u˫й09dwbƌ'=(qk ܴ\Zq˒GgM u۴:i (dddzڶN0.sTILBd#TOX{#_tӎe#&+Dף)_班J9sZ9EP @(PZNEgEJȼ8m8 3}2tJP'M|%#O ? kE~uaAZ+03 Z_]Pl:֊" ƒaִW_`g=t朝x3{q?wn*uuIr)P @(P @(؟q'Us\w*Q(_u?Pg0>D-^v\RERRU?Qf܍`D:&2I$rb+=Cl_& #׊\ EsG$ZܨXu;s\qΔ!!Si<':D厚 !tjNe!9(8'k7,M촐´׿v-5\YZw Oqt=cűHb%9mjⴢp7u1ϔ|y~#ҮZ{6w%zvƌ}hW.X>|N rJk61Ri= 5zjrqNT}!\1DTb(?)ʝ#RTq%<HRx={^6g'N$ 1gK(r&Db@R#?:YJ4ϖ$%.4PeJ3\yS+lP[`Jgb; $Lu;7%>$䨞X"agc-cm)WT#[pol$r9vvvnn]eƄsґ椉܄qyq) 劒"m4̐%9d/W]f.ma#Cor{+8뎹WF\q-p! gk "8< 6\gjf~oA+  xk]IzR: DTUpvI> ^WEet ;! +#I>MT.IvUK񶩰dlnp'$/j{66!@FߊGo$hH93]Iqyr*Dy#;Nvrs\<R=:E,D}99'3c=j{{=yoxj2w}lpdetrvmϭVKe"$vcȕ%^N\3َ;KiPlkӻƏY49EP @(P @(P @(P @(P O*.;(pyYd3PACt\Bڥ$f{Nk1KiJN9J'u R )YW);a+K^K x;FkH!fMps-%qBT𚬟L [ё-)?+_6ѓE C]b874خuh̚fgtޥڟB8{<Td֎6x?r-jjYJPy{k!Tl*P$Xq$T;?1RG GUC9~nA@rsMYb>ʲZej+اHAiN@* 6$>P[A)x1Z/.u H)): ڞjXְ{9x~ĚG.l[y>*~ Jʸ,?%'59n8bVXݦ`q>T37rE6,:ۻ֞\%i(,rNӞʙA53'z)jY\A-ʐRZ9m~cӢR~ő@Z{R>ʟAqZXgN9T{}!\mD$Xܓ+ԷG=Q Qq$rrrYG?(.('$YK~ $q8U"IkSx~9~:zS䨄yY;IMmy5(זI*LJFlsl^V{سBvDCd&[;w~~`k DliTϰs1:>[+mi%aO)\`aT7WDYj'&Ҡ؟q'Us\w*Q(_u?Pg0:5[,ϣp?*j㌞\Fه$)IRԥXsL!E} eb&]c;vcj%HYMvv숏]iޔr8Yc.r=T*xim;7g8rغvoٗZZ^2qg/b|PgZ@rTÎs*'L=*xbq>H@<1^ghΈe+$g#I ؖ)*~R|uWˣfܾkcE*ہ#R<}CjG*{- Q#;VQ j^ñAaI=͑k%#]KbΫ.igW\Ci@T[ck<TU0~53V^Cn+QHQt]q냁BDXJ>l$AQ*6| Bt3>ػKl8j*)hfv+y~_:?ƚQ]gT%Ft;4Zɿ3%"i<\D-KW\жgk)1|P[z@IRފN`Bekwef4[mX+RRzJYI إ4iJI8Pk; [W %MuHq\]ޑhBnb“%;+@(̦rVV9GVK6j7.b%ЛPyfdVd>[W,:?'_jl9lkvW%/>[? #+CRmO!f4Զmr b7%[7 *4]u QBmKovm)uRŲݨ &C]"F,,,7.,ܕ%kK$:@?M4wh(m+}8Wp YP @(P @(P @($ ˎ@J%+uVj T Ϊq3|Oh]DLRA2FJ'sVt"]\K K.5+-LMl-O22Ե(we#βGϞ.mBDgؗ*lC5E$;#j$f2Sxm>+8jkH%CuqC:4ȵR,.4 3nJFD=L]i{V$ G$Lu tORT]9U%[7֔;~bj^"IreΦ4Fv)I?X{c 3ٸ \p8㗄c ZPI;}-]X F2._5yٖI:MS (9 VT}QBxPtGWH8yQG|!#N>\fsXlԛ )%C{>quwFMw(@R?]I ;yVnmp]WZB@Ilb'jEIӁX8<V<5wiV}?j\ 6v cVLkȎ#~ R#Gn>nfTX (gZ$A;/z#SAoYժ;$('98eܡbqMNO#K|e͖wQqیƹ$>GEmk^@C)E+i H^V4;Tn7vI\~'9p9u׺ۂY($ĎYIFvHy֒IQ,ej$y] QWb4X|NwGi"Cx ܐvךT927Lcc[cG@`$%+sjp7Xw9Z=R.jM+SRg{C*JJ +0%ʁ9d\gRC-')RT9@A]j kɲÌX@S qqBJ(B$ nOùD abv$6NH-#a 3Sq*nܶT ږ|qie %Y."L.!AS往ԀVZH pr57w;֡q:T͍x}oOc}@FjKPD۳ MFm )NJFԃ#J! H2P @(P @(P @(P O*.;(pyYd3P[T\4Aj2ֆԀJ»{LyWFsRe%"gNt)l{K{ KN9Y! M5LkĩJ]N:\wX##1m@~U-,r4YΚBUɁ\9%HS+ueiP_#=ZJUnq˾eKd%t 1iš#;jy3|'51܍3j-"aJk-lӨ;-j<jU)De$ﴬ^4z:nxPwSU'4-lb0?CzX2SCY/KN Q}d3uWH"Ѧ #> ,= \ս?kEQUc7 "Gգ:椞aȌyr(E7ޣvUCڅnqieHVsTqL$17juGB cdkFέ GujW>/}yH?.`1_ީNWu!I1_z2\0&4/W?TX*aTyTA+?$QpC{1qJu)PIX )ޓ|}(P&iB7,}cJ> &edPM7,k'҅oIY`Y>Ɣ(|zM4CoX>O ޓ|}(P&iB7,}cJ> &edPM7,k'҅oIY`Y>Ɣ(|zM4CoX>O ޓ|}(P&iB7,}cJ> &edPM7,k'҅oIY`Y>Ɣ(|zM4CoX>O ޓ|}(P&iB7,}cJ> &edPM7,k'҅oIY`Y>Ɣ(|zM4CoX>O ޓ|}(P&iB7,}cJ> &edPM7,k'҅oIY`Y>Ɣ(|zM4CoX>O ޓ|}(P&iB7,}cJ> &edPM7,k'҅oIY`Y>Ɣ(|zM4CoX>O ޓ|}(P&iB7,}cJ> &edPM7,k'҅oIY`Y>Ɣ(|zM4CoX>O ޓ|}(P&iB7,}cJ> &edPM7,k'҅oIY`Y>Ɣ(|zM4CoX>O ޓ|}(P&iB7,}cJ> &edPM7,k'҅oIY`Y>Ɣ(|zM4G{3ԽhK!%PÊ@Bi $(>\CvtbVCc'k{p;3ұf~G?ƥ %,|,sjX_/b~G?ƥ %,|,sjX_/b~G?ƥ %,|,sjX_/b~G?ƥ %,|,sjX_/b~G?ƥ %,|,sjX_/b~G?ƥ %,|,sjX_/b~G?ƥ %,|,sjX_/b~G?ƥ %,|,sjX_/b~G?ƥ %,|,sjX_/b~G?ƥ %,|,sjX_/b~G?ƥ %,|,sjX_/b~G?ƥ %,|,sjX_/b~G?ƥ %,|,sjX_/b~G?ƥ %,|,sjX_/b~G?ƥ %,|,sjX_/b~G?ƥ %,|,sjX_/b~G?ƥ %,|,sjX_/b~G?ƥ %,|,sjX~Kv(upPP'$N 埠xbϝ*P @(P @(P @(P @(P @(P @(P @(P @(P @(z~]N#-m]Q|@Lx:ݏkQdi\{)sUއq*.뭆UQ԰G?HI.&Zd$>ٚ=S:^`%r>Yquw7" }J7K UdQQ[!`)DG*, v"~RG!| vdwCxA)RʊE_MM Iz:[iA*H9}%\ï`mAjE$s@i{?)/>Sz{?)/>Szӷ=<[=y\7i ABvi.ɷ9Ežuͩ*;PIA'@n}'WMVNF qnܜ#@B @gT'FuM6Pe (qhPB{P#/] ^64JPĕ(gxPA mۖ\4Zn}&r^j I$Ki7x.Ӓ%X+VVC(ڎ.Dqܨd%G@`68۠P-36uYzqޒlqXJ$  ouz%ӜW~R^}9Puz%Ӝ~TL/8ZRqEJQ﹒y@(P +2HDf}d$ij8 <2ORL3蕝YhWg\BeYPRV `+;g Ռr}[cM]$ˆ{e%9D WRI5܋D(du|%:-i O.DzbQsa&N0A=Ub]i'43ӄZ$miIٜe?;/{cj~XL[KGo3G]i# y#(Q~ Mc8ΣO*}̺M^w>Zg1oC\Ey/OJt(-D<|s?S%&q=?{)R?UhB C'e RBY=tR{< hgbRM:B[ٍ`)G fN1Δ){ń;sԪ)Ԭ 01UZJuƩ?Mv󲻛!*g`$YaQ$} m(\JI" '[Vn/KiLXJf-6귤<sإ:J>#Ks;F׭HbRgpBxNҲВZ*p&u%Dj7f˻Qh%DonJ_[q)uBpr'o9qak_%끴5pDG&BPt *HNΖwpzEj-v ,e R[mn:MFT"wsnefVڄAȵJڗ1iZ27YBVJ Iɦ:L%1eknѥ`(.L2PPJCMBC3desѿ-w3a-5J 1 \CndKx Pihj~۫$鵻q Υ+M|6Yd%8CN AQOhNZ4֞iIn2CVa丷ZN.)'!ŅzDf-kd9o?FTN/ZT}آ)p.%N3DHԄpg+Q.>-6ۻ^ѿKԒ@Pe'O2iţR%+)PJ )PeCn#Fnc"5q!]f5=R.(\a)eHVwx^.;6{I[B&\ La7ƙiDJR#%iP+J`ڴۭ#F!6:st !!DaR W2ݺ4)j뱦[n mp4rRgڣGUw-pT}V~,ҷhŎ݀4 RtE E ؕ(rImJlg1y{k6EQĩP'u-? xC5hB<x f'=Ƥ76̿HbwNǕKm/Ꞃ~x,@W-՚3sRN9V Wme$! OWF~jLz Vigͧx(G-_[4A>G-5т͐U$Um AJvIu;TG dȁ@( akFcΫmBT@P|?їż/@;yLF_~֪86Y.KNfkz+-( gxE[Ϛg2T4eqo>iP|?їż/@;yLF_wU3-S6JH',TUIP @( H`}NISM)@@*}ż/RH-3~[Ϛg2T4eqo>iP|?їż/@Hd-- !h%C @(P TJ֔8X[N]\ͮ^zWKaaPxRZy;J$0].Lfi ;Rcnq>Y_VD\vmAZ7r=BJKfNgZJJHRA*_7%@w猃TrK=.$lNX2].)@$jHutjöj %`zvAZBG ~Ud6*jţbvb>ʬLlTLim82\s<=H5esMcdzGi*:kfQj * >1몸.lK4(.~0|"2j\aI^:*4Y2G%x4r>xosQ5Ez_ q|\u ӧV'wn%[h8xR}_0HiVB޿@*W/y;^g>HO^ G!HʓE[m+m4H1m!)<^{T虻 P0΄1aT3O4n^|?Wڼ@;yI_wji]%~ݫϝJtW;Ov>v+^|?Wڼ@;yI_jmˤա`IS @(P!7Y(HBR$/ Hsbwji]%~ݫϝJtW;Ov>v+^|?Wڼ@kK&[R}`m ueDO@aP @(پT0;mjX8 k\Q͋ۃk[oԗncIS@7-A ^£]R~j*oa$_A8(/ғ#'$ Z7Ka)%\#&E>H{ZvBHlܞ"PвQn!qz m•)NiC#5%i\v; ԆeF6 vb?Oe䊒Țl%N$Ukw"bٕ5dmnFqfdxv_E&'f":r.~ET#䛕xp3sOf޼K1ѯ\b_f3JIڞ,Q|c+~_dDc"D})J[T0?jЧ(Xa*E`,}&42qmZohj:^"O&‡ xwQ2v؊A0AR:9Qxn'<~i/UFgt+Q8f:j?Ru. TN$ϯWC}}|b9㕨g8+ŒޑNj;gPP;>2^V4|} !Voz)Oj1Aa9FrP @K1u6~N$- D7$߹MSn.v{?&>hMSn.v{?&>hMSn.v{?&>hMSn.v{?&>hMSn.v_K2a}69d5@(P @(l4 -\PB)J';I> [ܦ7y?@=jwAsܦ7y?@=jwAsܦ7y?@xL6q٦IZָn%)H$9<4MP @(oa7=)i Rdx1vnMSDJs[Er2*hc[߱[#G! Q<n$ސfYw-J8y2?BB)vp!8ns9VnT'`qtUI5t~ 3VdG2kYA r4o"=d'$rTsm*]=iڱjTorHh AQm[ӻ$&NvSRQ΍6Uz@T&_^*2Zq,)TRNT&EZCh[91KSPHG/?u kOWˑ4^3:LRpN1ߊo-Jwvzgzޅ1eWAЎ^d8W~#JɆ)E?׹],:+nM*hq`%$<ؾX&D.WQQ4N՜I'R\9ceyl@%TRHNT̑0̴a޹l&qXR:~s#Yޜ\JP ƗbwCiZz"U s"HAλՖ& 7)Iҕi9NF1@$J"6HՌe:YqqrJ3^Iy?@=꟔Ns^Iy?@mkߕ""K>QR{dfPz#ZMӪp􆠓eKNSz{?)/> m;}#cϼeܷ~J֜`TT*IP @(,:4rg)O\OSg @|]R[vJ VesrܜbJYϚT?JEDe"q2E7=ٻ?ΊcD)kKaPe]YՋxBXHW Qr sB sᩌCFdg SD棕@U\ m1vHѹW&tlk9 (9 ZCkbQG5F&RsG88s/.XcCm- WV]HhARY)%c8u̖|?g7r>5%!.iGI$1G<^VȐ\' $cIՕWnM- p Kkw cMZYIWݾN,Z6qgBSd׻5~8d/gqmնݫ<t%IJmXʙmܖ$GUm?*^N{| gns-$CJzwqI>/Z };u?`ˤZb\bH૑J>+t(οDx Q3\ꤝ7mus,C~B_Jf1Ik{ne8?LKWXvFȺ%"Rȷ:FZZ))A1R XiK+^mm( >Q` 9bmKC-!ŏo=ӏEӰ&KCFҚeձNYc-lHob@kr'tULkuO?w\’[ZnAl4 %O!8VҡԲs.zo[G5%7fGB DfZVZ g6vӐIMdYze)noEi2SKmL:#: 9*K1 1qKf;{M1 U@IVWGiG7$] Ό̨Z<[nWIRO%$AݶwE&{BѪTr_mns[i  ;Cu-li-mjXQ3f@p.bX\6Te/J &PBNթK yW!,):z҇*$()HZ]R?Ug՗kۡ KNv8 "5cHN'' 'c]uKVgK,K `ݼ8TW5SlS\}7[l 3˷wo:ݟ٩$P @(,Z-ېY䬧-9ӊ汏R䳨|":?:VG3U*"n.,j%*r12ͪ?Zb[Kwnj(SFW;DGND_ro4A*yUvE>m Hc,{?_CBS.Ђ[%$|<My`nI}5vU'BV%)x*Ӣil.,"a$|IBBG\Z[AO듌;A?Hj𴫮V{1쎍u-' )e/ P קhD>,my}??u.9TSk)`5P(k}[z]Ȱe>b$} |>|?ї$wU-3~[Ϛg2T4eqo>iP|?їż/@;yLF_[NZq Bke*J#vA~P @(P:]_QMmgusVRTA`#4eqo>iP|?їż/@L}#w%A :Ғ $|zEP @( 4ڕSvZmSha峏Қ4e4*IEtςrygSu\ܳl)u RRJIXő v2CI}=ۅ TQŕj⬨Mp~lXsvtI+?V+fv[ih 2 dyaYY#7y4A/Om 8El[囻f;n@}ג\-Ix8ޮ6HaV$L:}V^. W{C.kF"RՂO>0X6Fm>,N]R&SR}xKyDC;pN_yy5 -- Ve} Fd' @1ُ5:4qy5k(2QF&^Gyz5'fzLƉ.[j#aJklRrܹ'.}!%V;s_?!ϼBI|dj&-N҅5xBA ?XƤ&(]uFk] z! wI=_qGJøЏƲR# L?nI"hg)!tʮ0YoĺKr%m);\П^OJ}v>U}rRld%J ?5ϴl#e+m6ʖF@A?]3[ }Z9 gLjlY>')@(7y%BnPH^0%~ݫϝJtW;Ov>v+^|?Wڼ@;yI_wji]%~Z\2JhS* x~ P @(=>:mAhZR h ^|?Wڼ@;yI_wji]%~˗{.V%Oh#4P @(p{05/GCΫ'xl컦%YJ@Ǐkٴ3dci[||x+^I:j*J$AԢJ7m=5aS :3ZG%2Y~VwZ>#STIFYPxw:Tm3RD3r;]-<1uv6D;56q=%Zy19wtJ趷#Z0Z;5or=͌/maERaG^-}J&nĊԖQnʜ|GlII gzG*R]J}]{>tm RfjINigO2bq/ 7ȭm\D6J8ͼޥHŬG>|*9G}q5ƆRr*䯽q$`D~-ι>65- PJt \VLiO<g-՟wtSmU+E$.DگW$X%-읐ʊCgFgfف-5 P"#>.ױ] ?VWZ^Ֆp9xhx?u 1lxP @(P @(P @(P @(P @(;$J/)I'>*+tLY HXIU\ 9-Qe$0v<δI&?qֻ7F$X{I3n(ʕg5v62@'njnƏO1֊J4DId }'?UghNcYP @(P @(P @(P @(P @(Λىa;߉9*'Hgv76r;' kbtj\a%M) Y9$gObuzȥ27^+ms*|Rs$m[ 'M(~NN'J!hr2VpV3sndiuW!e}ѹmF~|vХԎcHwZ44@ZRO\4ivaϩV(AP FTtn)cmU;7*=Yk^,ȋtq+RHJ'׳J"]23ײ(fy YgE!6-zM֤?(>XŃA4&[$PJNig䔫qWQks+|1kݛw᪽dp{#UM3U^܀Ă94+{خ5'=ϋ$6kP+Ԯ/LN=F^$??J#Uh@眭 #ڶQB Rq) Wהjc;}ҋt٨ULWj2;0ΪP @(P6Hk%=SLT#`> 7W^vlow߷_Myo@:c~ހu}5kk͍z5.3ݓtPq a -Gj!8眃˲P @(P @(PE.(JwUYb2چk8 CXvkd)FGJBrsW\kLr+HO穦Sٜ@~UUY@u R<5 "M;1J; XݓBPr~x#Adkc!y|I>J#+OUXd$88[^N1tͤs9›цI^EX#N P=)uBy){E=1׽`ggџZ[Qg6G:EĦP k?_1+Cv-O> χďbĻY/VEWV+?%,yۈROa W}gN2F7dRxQN2u#JS5$js³אS>;'_I5`@gO e] /KiYJHq h"(=Hfl r^ý^?~)iN'r09#w,B#jf^ :( cj".ƚWڒJ}P @(P @(9V?W~ٟܳ]CVF]%:,  ܻͷ])ԇ V|<<밉g0P3>Ցu7YՍ8{c諬YdC G%],c#{kW>b[Q~fc[ ÄcY9YV.ZL ~SL2)huR6)(W.7VYZ5Lo~YpLeT`wC9v#Pű e;I J@y(G3î6n㳿TlUw5U"S?8q(_ Yݷ*'mi9Xc›m@+-> i K$I>1PۓE;rBvyO\^9Ij/ys:w;)WHk/ z*Fc㮸xK~6M,dar3P @(P ^jKXi.K1/Bɀӏ8o"-B% .8Vr Mfl.i9*t֫:Ib;/YPtmiajڞh!iT/|r=[]gt{t=>{$;"^Y&Z6?}S("_Ssh%R%Eh%#^"|60cWj7Vcɕڜek96/ ABk+7> MmS3;~n!wHZTƛCo,66 rTeF iEwm)P @(P @(P zҒT>aj$ێGo>t)RjUYZ!# eep>j. qSn{K.gLjt:-w4W<8f1m#eTҚ mA$r{|d0V,I *'o?ZBJlSD2*sXN*#Y!fʉ52L(($XJHh[%:Yd%(MPUrjhKNr7UF8@e9r쭮 Eie")Da{]ոzL'S}Fbxt5q= d|5 R{KJUVT S=sjsu-`ͥ)9`}>*üEG{E,iط? 2Q3ϙ*Q&iAa$\Yt|rkmF1+T*(P @(z?1@X549}bȳ1\h k_~JUAvyKkF~*+->u8VG|ۋN{Fr0@5$}ӟ*Wӟ*Wӟ*W74N'9IuƚWڒJ}P @(P @(Ӎ "Q2Z )9Rz<*3h)!I 8U㒕nI [ڄcεL(MZ[B6jimMQQdTKDGh!X+%n_$q䤏mWaI"×ma*cTH(t;WJXbGKea)mvW6H$>kڋRVM@†|͞dsm"WS2r^ƛQh`@-hͨti.rB&/鏱c/=(|wqٓ~.3_[_QcQBNK5.TO{ LA93N'k6{>S]ls5]Q gVLrÒ#5EGJ2sQHyU/sMpcP#KlRG( GIIuDvC 4v}>sk%c#F/JY9zl:BՒʥc#yލ="9x|ZjvXP @(P KO^ئ\ K[e\&e4R0@"o!j{j7~@=HZgڃC-_|mA!6~ WnշE +mq6@Q!NN(@(P @(P @()c|4 8Wn9jDQ0[_yl=L4M[6s-Y-͖[ KN2P BG<6VUj!KcjFVԅ4WF%PG._P @(P @(P @(P @(P @(P^%) *cɖFxq=12h(n@>V6x9Qd2T TVUGUz)]3Zm廂LHN1]hdNtWqqniGC9 ZPN "n(JYeh*x|aLr3E=>t%C#=U\Z~eC&Ҟ?>*tCDƍBfqqȨy$TڔٔE'* ~c;#Q]ӺNevaU63H(KO vsYV1zz\(QgD  )Y 3<$裋2nP㸙mn -N!;҈8Is'wG*,}=i[\Tdqھ.< Ddym65ކݞ x]b[؇K8PI<סlߺCV҇Z8wnVʥQx1X26WqXNq gJd#$E_٧ĕ`T9+m3n%6)EgdiLCd)E)WF%"4v hh$^+iP4iM8+S^d>D7Yq)sQul!]89}mH[ՖW{jXmcn7YۇxW($Yqvj+=v5,q6spqü ,渻5e8x۹M8v ks\]~ݍKMlm&~k;p5.Ye{nƥ&66`|nx?|5wEf߷cRow0>7 g;"nkVY^۱c3 gnf5٫,pԱoH[ՖW{jXmcn7Yۇx@$Yqvj+=v5,q6spqü ,渻5e8x۹M8v ks\]~ݍKMlm&~k;p5.Ye{nƥ&66`|nx?|5wEf߷cRow0>7 g;"nkVY^۱c3 gnf5٫,pԱoH[ՖW{jXmcn7Yۇx@$Yqvj+=v5,q6spqü ,渻5e8x۹M8v ks\]~ݍKMlm&~k;p5.Ye{nƥ&66`|nx?|5wEf߷cRow0>7 g;"nkVY^۱c3 gnf5٫,pԱoH[ՖW{jXmcn7Yۇx@$Yqvj+=v5,q6spqü ,渻5e8x۹M8v ks\]~ݍKMlm&~k;p5.Ye{nƥ&66`|nx?|5wEf߷cRow0>7 g;"nkVY^۱c3 gnf5٫,pԱoH[ՖW{jXmcn7Yۇx@$Yqvj+=v5,q6spqü ,渻5e8x۹M8v ks\]~ݍKMlm&~k;p +(d]\wبy)\ZA9·% iP @(ln֞жDg7؟vLxKـ։їJ=0a I%T<s'[C2V$j`dP@:F=&R\11!< VI} "# '<1 ׏[0]n:bLh)*Ci<ʏX3HU@RRII?>*5#$8$+c+7ܞ%o1οz”Hm#%*H;V<}<[bo,OOWWZE4(}j޷eJ-PIP)ܧ:HItѷ lQϲeŠaJo1rU1]Cc w}*&#Ts51ӻ/)[B*횎+HCjV߈k7ܯ<2"wNTr e\ϰ/?-TTJK Z!1!%ո6p'HJgo0$~9?﬒ܘoɒ]͖l-8c4l4*dZT (;>oW$3լÒl6aA[B{J[uۛlS5JU,JO<Z.w=[%kV`]@qAj `|{A|˓[ULz2=͡!)9?4Q˺i[wBxɧ&^lӖ-9ZQ[.PJTR`zh݃{Y逞2p3KWx '?}Q,2# IgO}Xz(:gaQIR2T =! 1p9_5J\g:e<٢7`˝$^dT7ڬj}㬥AF.ʢ)׍ou\6`7-,b,3q <֏Gy|6obw֖d&4IBqbyE%qW.K0a9IɪSzhzO<Ք+rz@|=(+QܪԐ(3×*z:eKi…8U!JI((P @(P @(P @(P @(P @(P @(P @(P @(P @(P @(P @(P @(P @(P @(P @(P @(P @(P @(P @(P @(P @(P @(z,XwJaԓ޹fBI#Ah3MJf.Xf8ZҪd, -YWg1Jy0i)=,6˩9gm* PKjoPg(|~?j }/_کBKjoPg(|~?j }/_کBKjoPg(|~?j 2F4nygj U(P0i)=,6˩9gm* PKjoPg(|~?j }/_کBKjoPg(|~?j }/_کBKjoPg(|~?j }/_کBKjoPg(|~?j }/_کBKjoPg(|~?j }/_کBKjoPg(|~?j }/_کBKjoPg(|~?j }/_کBKjoPg(|~?j }/_کBKjoPg(|~?j }/_کBKjoPg(|~?j }/_کBKjoPg(|~?j }/_کBKjoPg(|~?j }/_کBKjoPg(|~?j }/_کBKjoPg(|~?j 4s:G);kamiH[?iBnWlYܷ_ɫK m.Hj-*ԘW%+b@l":)kJFOwb$%} ݧq[G5٘z<2/޵Tc.n0i+㤶|G6 !IRH qַ/Ě䵫UI#@(u_JOfvl8aڔ6)KPFJ* j+% n:-.Z2SI_~V7#()!wfh6/̙<\RCHJV˙J`rJ@˨:AdrmC.-喸Sl72\HPh'RKi]m B%E)*g;*I2 @lD_HtJ~vǷJ2K,EšjNp>cOJŵ&lHlpRX.YNR; JTy=ZUz,fkòVԢkinwb N _[qvdIyJ:;9مRӚ7+-]"Fc0Y+HKZ@-ZBۍ!ť>IC5$ #=FD: n\KpNP˪܌6J Rsb{,Ѵ3%#԰xڼ**6+hڵXkIU-n*{RG}B[ VJpJA׺ܾzŠ Tx[y@FDֻmX;磉YM}:]SHۻI"&|][yee%S Yڕ$a܄֨9.tn4قێ>MêK pJT(ں s QgP_#;[ˈKޠP; S( hհrvT)Ry9!M%JT_$ J,U$@(P @(P @(P @(P @(E{GIoV*;] ]mJ""4kX[IBV9f4.VUVG֮CZa-)4e$$8U>Ol =s6ۋ1%4/S.!@kAN\6kʐuEĎGbQ, }d>?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z#O?$Z6Fg%i`?w3cam-0.7.2/font.c0100644000076400000620000001556107373452130012511 0ustar rascauser/* * font.c * * Copyright (C) 2000 Rasca, Berlin * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ERROR -1 #define DPI 76 #define TT_VALID(x) ((x).z != NULL) typedef struct _ttfont { TT_Face face; TT_Face_Properties props; TT_Instance inst; int smooth; } ttfont; static unsigned char bounded_palette[8] = {0, 1, 2, 3, 4, 4, 4, 4}; /* */ int Face_Open (char *file, TT_Engine engine, TT_Face *face, TT_Face_Properties *prop, TT_Instance *inst, int ptsize) { if (TT_Open_Face (engine, file, face)) { return ERROR; } TT_Get_Face_Properties (*face, prop); TT_New_Instance (*face, inst); TT_Set_Instance_Resolutions (*inst, DPI, DPI); TT_Set_Instance_CharSize (*inst, ptsize*64); return 0; } /* * release the resources for the instance and the face */ void Face_Done (TT_Instance inst, TT_Face face) { TT_Done_Instance (inst); TT_Close_Face (face); } /* */ TT_Glyph * Glyphs_Load (TT_Face face, TT_Face_Properties *prop, TT_Instance inst, unsigned char *str, int len) { unsigned short n, i; unsigned short platform, encoding; unsigned short num_glyphs = 0, num_cmap = 0; unsigned short load_flags, j, code; TT_CharMap char_map; TT_Glyph *gl; n = prop->num_CharMaps; for (i = 0; i < n; i++) { TT_Get_CharMap_ID (face, i, &platform, &encoding); if ((platform == 3 && encoding == 1) || (platform == 0 && encoding == 0)) { TT_Get_CharMap (face, i, &char_map); break; } } if (i == n) { num_cmap = i; num_glyphs = prop->num_Glyphs; } gl = (TT_Glyph *) malloc (256 * sizeof (TT_Glyph)); memset (gl, 0, 256 * sizeof (TT_Glyph)); load_flags = TTLOAD_SCALE_GLYPH; for (i = 0; i < len; i++) { j = str[i]; if (TT_VALID(gl[j])) { /* still done */ continue; } if (num_cmap) { /* hmm.. does this really work? */ code = (j - ' ' + 1) < 0 ? 0 : (j - ' ' + 1); if (code >= num_glyphs) { code = 0; } } else { code = TT_Char_Index (char_map, j); } TT_New_Glyph (face, &gl[j]); TT_Load_Glyph (inst, gl[j], code, load_flags); } return gl; } /* */ void Glyphs_Done (TT_Glyph *gl) { int i; if (!gl) return; for (i = 0; i < 256; i++) { TT_Done_Glyph (gl[i]); } free (gl); } /* */ void Raster_Init (TT_Face face, TT_Face_Properties *prop, TT_Instance inst, unsigned char *str, int len, int border, TT_Glyph *gl, TT_Raster_Map *bit) { TT_Instance_Metrics imetrics; int upm, ascent, descent; int width, height, i; unsigned int j; TT_Glyph_Metrics gmetrics; TT_Get_Instance_Metrics (inst, &imetrics); upm = prop->header->Units_Per_EM; ascent = (prop->horizontal->Ascender * imetrics.y_ppem) / upm; descent= (prop->horizontal->Descender * imetrics.y_ppem) / upm; width = 2 * border; height= 2 * border + ascent - descent; for (i = 0; i < len; i++) { j = str[i]; if (!TT_VALID(gl[j])) continue; TT_Get_Glyph_Metrics (gl[j], &gmetrics); width += gmetrics.advance / 64; } bit->rows = height; bit->width= width; bit->cols= (width + 3) & -4; /* for pixmap, must be 32-bits aligned */ bit->flow = TT_Flow_Down; bit->size = bit->rows * bit->cols; bit->bitmap = malloc (bit->size); if (bit->bitmap) memset (bit->bitmap, 0, bit->size); } /* */ void Raster_Done (TT_Raster_Map *bit) { free (bit->bitmap); bit->bitmap = NULL; } /* */ void Raster_Small_Init (TT_Raster_Map *map, TT_Instance *inst) { TT_Instance_Metrics metrics; TT_Get_Instance_Metrics (*inst, &metrics); map->rows = metrics.y_ppem + 32; map->width= metrics.x_ppem + 32; map->cols = (map->width + 3) & -4; map->flow = TT_Flow_Up; map->size = (long)map->rows * map->cols; map->bitmap = malloc ((int)map->size); } /* */ void Bitmap_Clear (TT_Raster_Map *map) { if (map && map->bitmap) memset (map->bitmap, 0, map->size); } /* */ void Render_Glyph (TT_Glyph g, TT_Glyph_Metrics *gm, int x_offset, int y_offset, TT_Raster_Map *bit, TT_Raster_Map *sbit) { TT_F26Dot6 x, y, xmin, ymin, xmax, ymax; int ioff, iread; char *off, *read, *off2, *read2; xmin = gm->bbox.xMin & -64; ymin = gm->bbox.yMin & -64; xmax = (gm->bbox.xMax+63) & -64; ymax = (gm->bbox.yMax+63) & -64; Bitmap_Clear (sbit); if (TT_Get_Glyph_Pixmap (g, sbit, -xmin, -ymin)) return; xmin = (xmin >> 6) + x_offset; ymin = (ymin >> 6) + y_offset; xmax = (xmax >> 6) + x_offset; ymax = (ymax >> 6) + y_offset; if (xmin >= (int)bit->width || ymin >= (int)bit->rows || xmax < 0 || ymax < 0) return; if (xmax - xmin + 1 > sbit->width) xmax = xmin + sbit->width - 1; if (ymax - ymin + 1 > sbit->rows) ymax = ymin + sbit->rows - 1; iread = 0; if (ymin < 0) { iread -= ymin * sbit->cols; ioff = 0; ymin = 0; } else { ioff = ymin * bit->cols; } if (ymax >= bit->rows) ymax = bit->rows-1; if (xmin < 0) { iread -= xmin; xmin = 0; } else { ioff += xmin; } if (xmax >= bit->width) xmax = bit->width - 1; read2 = (char *)sbit->bitmap + iread; off2 = (char *)bit->bitmap + ioff; for (y = ymin; y <= ymax; y++) { read = read2; off = off2; for (x = xmin; x <= xmax; x++) { *off = bounded_palette[*off | *read]; off++; read++; } read2 += sbit->cols; off2 += bit->cols; } } /* */ unsigned char * Render_String (TT_Glyph *gl, unsigned char *str, int len, TT_Raster_Map *bit, TT_Raster_Map *sbit, int border) { int i; unsigned int j; TT_F26Dot6 x, y, z, min_x, min_y, max_x, max_y; TT_Glyph_Metrics gmetrics; min_x = min_y = 0; max_x = max_y = 0; x = 0; y = 0; for (i = 0; i < len; i++) { j = str[i]; if (!TT_VALID(gl[j])) continue; TT_Get_Glyph_Metrics (gl[j], &gmetrics); z = x + gmetrics.bbox.xMin; if (min_x > z) min_x = z; z = x + gmetrics.bbox.xMax; if (max_x < z) max_x = z; z = y + gmetrics.bbox.yMin; if (min_y > z) min_y = z; z = y + gmetrics.bbox.yMax; if (max_y < z) max_y = z; x += gmetrics.advance & -64; } min_x = (min_x & -64) >> 6; min_y = (min_y & -64) >> 6; max_x = ((max_x + 63) & -64) >> 6; max_y = ((max_y + 63) & -64) >> 6; max_x -= min_x; max_y -= min_y; min_x = (bit->width - max_x + 2) / 2; min_y = (bit->rows - max_y + 4) / 2; max_x += min_x; max_y += min_y; /* */ x = min_x; y = min_y; for (i = 0; i < len; i++) { j = str[i]; if (!TT_VALID(gl[j])) continue; TT_Get_Glyph_Metrics (gl[j], &gmetrics); Render_Glyph (gl[j], &gmetrics, x, y, bit, sbit); x += gmetrics.advance / 64; } return NULL; } w3cam-0.7.2/Makefile.std0100644000076400000620000000200706642437313013623 0ustar rascauserCC = cc prefix=/usr/local exec_prefix=${prefix} sbindir=${exec_prefix}/sbin cgibindir=$(prefix)/cgi-bin bindir=${exec_prefix}/bin CFLAGS = -O2 -Wall -DHAVE_LIBM=1 -DHAVE_LIBZ=1 -DHAVE_LIBPNG=1 \ -DHAVE_LIBJPEG=1 -DVIDEO_DEV=\"/dev/video\" LDFLAGS = LIBS = -ljpeg -lpng -lz -lm OBJ = w3cam.o cgi.o default: w3cam.cgi vidcat w3camd/w3camd w3cam.cgi: $(OBJ) $(CC) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) vidcat: cgi.o vidcat.o $(CC) $(LDFLAGS) -o $@ vidcat.o cgi.o $(LIBS) w3camd/w3camd: cd w3camd && make install: w3cam.cgi install w3cam.cgi $(cgibindir)/ test -f $(cgibindir)/w3cam.cgi.scf || \ install w3cam.cgi.scf $(cgibindir)/ install vidcat $(bindir)/ clean: rm -f *.o w3cam.cgi vidcat cd w3camd && make clean && rm -f w3camd msproper: clean rm -f config.status config.log config.cache README: index.html lynx -dump http://www/~rasca/w3cam/index.html | \ sed "s%/www/%/home.pages.de/%g" > README tarball: clean rm -f config.status config.log config.cache Makefile cd .. && tar -czvf w3cam07.tgz w3cam/ w3cam-0.7.2/ppmtoascii.c0100644000076400000620000000545207373452143013715 0ustar rascauser/* * ppmtoascii * * Copyright (C) 1998 Rasca, Berlin * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include /* char map[] = " ,,''`//--))((" "__..::;;<<>>ii++" "rrccuuoorrzzeebb" "qqddffqqqzzuuw$$" "mmm***###hhnnn%%" "nnmm=====[[[]]{}" "VVVVYYXXirrrrrrr" "xxxxyyyyggggffff" "HHHHHHHHHHHHHHHH" "IILLNNPPUUTTRRRR" "iirreeaabbtttttt" "ddffzzuuwwHHHHHH" "GGGGGGhhrrrrssuu" "PPOOOQQQEEEEFFFF" "***###VVVVYYZZZX" "OOOXXXMMMM@@@@@@" ; */ char map[] = " `````````" "____----....++++" "rrccuuoorrzzeebb" "qqddffqqqzzuuw$$" "mmmaaaaaahhnnn%%" "nnmm=====[[[]]{}" "VVVVYYXXirrrrrrr" "xxxxyyyyggggffff" "HHHHHHHHHHHHHHHH" "IILLNNPPUUTTRRRR" "iirreeaabbtttttt" "ddffzzuuwwHHHHHH" "GGGGGGhhrrrrssuu" "PPOOOQQQEEEEFFFF" "***###VVVVYYZZZX" "OOOXXXMMMM@@@@@@" ; int main (int argc, char *argv[]) { #define BUFFSIZE 1024 int c, i, val; FILE *fp; char buff[BUFFSIZE]; int verbose = 0; int width = 0, height =0; int maxval = 0; unsigned char *image; while ((c = getopt (argc, argv, "v")) != EOF) { switch (c) { case 'v': verbose++; break; default: break; } } if (argc == optind) { fp = stdin; } else { fp = fopen (argv[argc-1], "rb"); if (!fp) return (1); } fgets (buff, BUFFSIZE, fp); if (strncmp (buff, "P6", 2) != 0) { fprintf (stderr, "input is not a raw ppm file\n"); return (2); } fgets (buff, BUFFSIZE, fp); sscanf (buff, "%d %d", &width, &height); fgets (buff, BUFFSIZE, fp); sscanf (buff, "%d", &maxval); if (width == 0 || height ==0 || maxval ==0) { fprintf (stderr, "input is not a raw ppm file\n"); return (3); } if (verbose) fprintf (stderr, "width=%d height=%d maxval=%d\n", width,height,maxval); image = malloc (width * height); if (!image) { perror (argv[0]); return (4); } for (i = 0; i < width * height; i++) { fread (buff, 1, 3, fp); val = buff[0] + buff[1] + buff[2]; image[i] = ~((unsigned char )(val / 3)); } for (i = 0; i < height; i++) { int w; for (w = 0; w < width; w++) { printf ("%c", (unsigned char) map[(unsigned char )(image[(i*width)+w])]); } printf ("\n"); } return (0); } w3cam-0.7.2/index.in0100644000076400000620000000520207412661616013032 0ustar rascauserw3cam for Video4Linux

w3cam, Version @VERSION@

© Rasca, Berlin 1998-2001, published under the GNU GPL
Note: This CGI is for Linux running a kernel of the 2.2.X series or newer!

w3cam is a simple CGI to retrieve images from a so called video4linux device. In other words this program will only run on Linux machines which support a video4linux-device.

w3cam supports a plain mode and a gui mode. In the gui mode a html with a form is supplied to change some parameters with the mouse ..

  • Supported output formats: PNG, JPEG and PPM
  • Screen dumps in GUI mode double.jpg
  • Installation: run 'configure & make install' and edit the installed w3cam.cgi.scf file for the runtime configuration.
  • Usage: Install the CGI and then call {url}/w3cam.cgi?help
  • Download source code: w3cam-@VERSION@.tar.gz
  • Needed Libraries: libz, libpng, libjpeg
  • Checkout ChangeLog for changes since the last release.
  • Tips:
    • Don't use refresh=0 if you are not the only one, who want to access the video, cause this will lock the v4l device.
    • Set refresh=-1 if the image is NOT embedded in a HTML-page (or set it at compile time as the default or at runtime in the configuration file).
    • Use w3cam.css to change the layout (don't forget to install and define the URL in the config file..)
  • Problems?: Mini FAQ, and also consult the included documentation and HTML samples.
  • Links:

rasca <fcii at gmx.de>, 27. Dec 2001 - 18:28
w3cam-0.7.2/index.html0100644000076400000620000000516607412661634013401 0ustar rascauserw3cam for Video4Linux

w3cam, Version 0.7.2

© Rasca, Berlin 1998-2001, published under the GNU GPL
Note: This CGI is for Linux running a kernel of the 2.2.X series or newer!

w3cam is a simple CGI to retrieve images from a so called video4linux device. In other words this program will only run on Linux machines which support a video4linux-device.

w3cam supports a plain mode and a gui mode. In the gui mode a html with a form is supplied to change some parameters with the mouse ..

  • Supported output formats: PNG, JPEG and PPM
  • Screen dumps in GUI mode double.jpg
  • Installation: run 'configure & make install' and edit the installed w3cam.cgi.scf file for the runtime configuration.
  • Usage: Install the CGI and then call {url}/w3cam.cgi?help
  • Download source code: w3cam-0.7.2.tar.gz
  • Needed Libraries: libz, libpng, libjpeg
  • Checkout ChangeLog for changes since the last release.
  • Tips:
    • Don't use refresh=0 if you are not the only one, who want to access the video, cause this will lock the v4l device.
    • Set refresh=-1 if the image is NOT embedded in a HTML-page (or set it at compile time as the default or at runtime in the configuration file).
    • Use w3cam.css to change the layout (don't forget to install and define the URL in the config file..)
  • Problems?: Mini FAQ, and also consult the included documentation and HTML samples.
  • Links:

rasca <fcii at gmx.de>, 27. Dec 2001 - 18:28
w3cam-0.7.2/TODO.txt0100644000076400000620000000005207343636252012700 0ustar rascauser- w3cam: brithness, saturation - cgi-path w3cam-0.7.2/out0100644000076400000620000002621607366316502012134 0ustar rascauserJFIFC   %# , #&')*)-0-(0%()(C   (((((((((((((((((((((((((((((((((((((((((((((((((((@" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?^r?Zx\JP^٩AަgR@ cҞ✃({*s8N 8> 'jMFڢ6N)R;Ԙ{fIoZ|hЕ< JRxHc4ҜֳI0L֒HÎ@w$(#UߠծRkTj@öqZXz xVFr򨤶%iLاځ\9OZobG͚]5ϕJo=U{t&m'BHNq&і=i7dw>"Q ;ՅbJkMxr)`S n52`1M%bJ jF9>:گV9l.Ҝ5*ɲA#* 珥H pFImԄ(ӂ׏¤O'i& 0lڝ9U*yF(qҗ*[ +lBQ IQT6''zi!sHu<~ggl >яB6x')IȫlL{H*!҅)'^ak1zgi9Urx戽%7psMGL}jdȣhoƓAnh9Q0=R8ҕ@}(vm=٦g*nzOzs}kE'NlohPXdt!b.audJԆ~ϕ^oCp!<ޤUrZj"fRo^qqS4Rԥ+vHɩx+o~K\G]f1 rSV{3 TCsڅ_~٥t A 8A)V1xM:f(+. &ݏGs _(R9j}W$tÌ99Rhzx$c=RVN)$ Oj^JҜ0Vwt6֕@ }{Sii~`:$9Rb)9JA럥HoJ02z*ɑ4ݻ84yx9zJF8#LR*!M"V,t˵Ӿ\sij*dPբXE*`Y2w$(m^^Aoxjb"6st\CjR{_8䊯X\[ދVR躍R.rX;!]}v' zgJbWU 3 ;b=3N#+I$3+k>RX榊W )U'8g%:&$NLd|e(JN3)KJkEh&He4M$_3vE{|ɝ֭aܳBs.4/~IT:c"=:h _qpu~^`gsUǯOJM֟:SiRCU-\hN\U  uK[=9 +W%VĊqYi"1aȩTqȧCރ\W_"ccrjOT'=Kv)INN}r,cRHVnc?u%ŽQWÞ = SXA69#jHIFVd-ӎŗc²uHXƙ~`ۯlW1k)4{XYMLB 6+yJjGZۙߡ=M8}XpG#IƮFG#5tfCAuOMBYv9Gw4EN(E H rA}jsMlB~k9nDwyqy݊R@?Z/_PqIrcEΫQ8e>-k*m{#y#W#D1#G7k>o72;E]Fu͝sEooE0s j .<@F}emկNeK6<AIv*23u VK`y6 wÎ3#52HJW-{(z@[XMJq9oqrޑ*/gu/κD"D Sm),TvtQ'-w1n$mgjjј܏OjЂ!qdD!voQfiTrI.eѼX㻉Tn=Oֶ<" RA EgQC0 8n iЄf@9ϭ10q}Ҧ_b'mm؅42w]b){UV sUM%9 *MD!V`JUbJ9G%O>m*;* O:?Zxޢ8X>`שr3*@T?er[69*\\X4dCznPIYz uc=3K#j$x1,~$ƈ dچ=Ҷ3)< z4|g1=+o[41?& ]` )FICԓEQML@ڤ^ݻQ' }k7;==W)Ҙ'4=l6>ӣgҸ1"0t/mP|HL\N `Z63IQ⸋̗w0+Z^1ۍǯ֫ۑVQhV/"VCfūǣ ʩh ¬-L=Zg2mlZwG"/k-tc+3M)øQѓ-F>Ʊm΄ѣs['ٺzj Y$/M&?['3X#9YSƥexWW99Ȯ$4j8ypcYb'  NtF92u%'_AҺ?HTgڔR[d҈v`z]zRe UUav5]HkSFU#9Yڨ9F;zJIh"L#1R֢A)9sJ) ca\ L.kr6k[Dť~~}jcfܭ@_XC"2=]#k-F8YQH9SӮRUH^b^sIliK R gs%Մ3o0囜 rGWgZ=>daR)k''/xx<oh8<X8wz \0'fF{3g:. 2~UxeH Ԣ+v6P.}Erc\Hz=,А\qX??C[ s%ٔ啉6a?3;c 1v$Тg$$θY^C)D-qmEJ+++u}k>ޭܒI&r>=WꎓB#* ~IF3Y. kI>lI=NApMIN3*% R!ҳZ=ɁzV6u"9kLIv⸽Un-u2yMu֠/(2 E%3%PI9}E0$Kx4-xw/ƻCi)pwmڼnkzm.'_“Z\ҔPCO zT*qsR)V|wJzޢgp<O5:.gÚFUsjG` hoaxQP {SNsQHHݜvQԖ6߽5: t[jnVӒC+orkf w5qQ}9A*IsqQZN{UEuHHܰ\is=LbZmv hI\_OzuÍ>bHWkI޶Ih*h`2ҧ0#}u8#.H{W_VLcW Ry@8 AM?3joS$ȹfUczq\ʼn"T2Etn*cYȮ3p-]EO<=koOr~- cwoj$ZlIZBy>k6(yY =~"Ae:2J:XZ=A~dL3%Lq4=ϥ͉;H;Vd@(^? dLjCI:mqzf VN"%?]VГ%m,o XIZyHgW5-妉5 e=?1&|d2EP8VJٜ|ҤrGZYGW+ZVT2Z7(Wk H@5x\8>.8#4^v*zR'TOV'8[X^JRޢRI'w;bqsҌPBH1<9'ꍣ3^N g՗=rN*[XB+U20 ?7 p<֒HRhOp'Žձ$nap=8==lo4)!J1/NvֶVn4scFs p YܽyϥKswcE,M̸rdGasAVQ9G_ Nc5;8= w4Mxľ^{Eqv3.{gvF6OWj.@n}0Vv⪃pkBy>\,cUƛyS-u4B Jڹ(-.#*keI&eVG;{6Ɏy5+|zW3b| +㚪m=2@"?`|X'68j% ۜTy|ϹE@'Gz|Qg{zῈ+.Vs}'ڡsg8=I ǡ+37ۖ:{9!^PP\|<U+t tY,mܓ1Z#1U)x|޼c~gD^ќ%@+E"ޟ過9.R,x:VNY-ݐ$r3,@f$0pݪbLc1nvqڧ4^kFgOAOUխ[ıCirD%ޱmK4uܠWG{ucmyvʪ3Hi픤 $Ҍy]͌S9p= GJ{3hU?0\eQ]v͓Pw[RBzqs٫T6A5۞v^Bo#?q]׈;}p\ fՑQǿ8PHKMU(ԆArANy :I29"Z-bLؠ;{Un8aC8?(⮂88YtGbu9$i#R?rYUK!Yɮ[Z2(ct.x+>Ed`#k{dG$Q7UȌ.NqT<嵈ē]8gJ^+_g7#J.܎ӇN>SJxk;䅀9_t*r84rIarpFNsQ>kڲu{py`19X.R9?Z兢0>cH 䱩I9G7iLxAkQ7ְk]VAp6#EW udr6ZMܷJđk8&ۦZ*;aL G]B9[;XY2sҧS@z4V+k?1k9TF&9Z1}Wb{g\I71]qcݹ=)3+YFqZ9Y=TVi>R 2'EQCkV8X>H ~}$,{8 \I."A#',0}ǟ ?q s(Z- 0FzuT~i1[D݋q񪊺E8xZ5 _/>E1QO(H˜:oȸTukZ4o@rKc*K.8&A/C޳"&u*ߚ,eUctl41ӽ%ev$棊H|ȹZ .\Z9TD@"s8E5?I^NYO'5=G2xMbDAhQmqlLg•w3cam-0.7.2/SAMPLES0100644000076400000620000000026607341476625012434 0ustar rascauser http://62.108.3.228/cgi-bin/w3cam.cgi?width=320&height=240&mode=gui&quality=75&usleep=20000&input=Composite&format=JPEG&size=320x240&refresh=-1 http://www.show-control.com/cam.html w3cam-0.7.2/v4l.c0100644000076400000620000002176007412642723012251 0ustar rascauser/* * v4l.c * * Copyright (C) 2001 Rasca, Berlin * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #include #include "v4l.h" #define min(a,b) ((a) < (b) ? (a) : (b)) #define max(a,b) ((a) > (b) ? (a) : (b)) /* * set the input and norm for the video4linux device */ int v4l_set_input (int fd, int input, int norm) { struct video_channel vid_chnl; if (input != INPUT_DEFAULT || norm != NORM_DEFAULT) { if (vid_chnl.channel != INPUT_DEFAULT) vid_chnl.channel = input; else vid_chnl.channel = 0; vid_chnl.norm = -1; if (ioctl (fd, VIDIOCGCHAN, &vid_chnl) == -1) { perror ("ioctl (VIDIOCGCHAN)"); return -1; } else { if (input != 0) vid_chnl.channel = input; if (norm != NORM_DEFAULT) vid_chnl.norm = norm; if (ioctl (fd, VIDIOCSCHAN, &vid_chnl) == -1) { perror ("ioctl (VIDIOCSCHAN)"); return -1; } } } return 0; } /* * check the size and readjust if necessary */ int v4l_check_size (int fd, int *width, int *height) { struct video_capability vid_caps; if (ioctl (fd, VIDIOCGCAP, &vid_caps) == -1) { perror ("ioctl (VIDIOCGCAP)"); return -1; } /* readjust if necessary */ if (*width > vid_caps.maxwidth || *width < vid_caps.minwidth) { *width = min (*width, vid_caps.maxwidth); *width = max (*width, vid_caps.minwidth); fprintf (stderr, "readjusting width to %d\n", *width); } if (*height > vid_caps.maxheight || *height < vid_caps.minheight) { *height = min (*height, vid_caps.maxheight); *height = max (*height, vid_caps.minheight); fprintf (stderr, "readjusting height to %d\n", *height); } return 0; } /* * check the requested palette and adjust if possible * seems not to work :-( */ int v4l_check_palette (int fd, int *palette) { struct video_picture vid_pic; if (!palette) return -1; if (ioctl (fd, VIDIOCGPICT, &vid_pic) == -1) { perror ("ioctl (VIDIOCGPICT)"); return -1; } vid_pic.palette = *palette; if (ioctl (fd, VIDIOCSPICT, &vid_pic) == -1) { /* try YUV420P */ fprintf (stderr, "failed\n"); vid_pic.palette = *palette = VIDEO_PALETTE_YUV420P; if (ioctl (fd, VIDIOCSPICT, &vid_pic) == -1) { perror ("ioctl (VIDIOCSPICT) to YUV"); /* ok, try grayscale.. */ vid_pic.palette = *palette = VIDEO_PALETTE_GREY; if (ioctl (fd, VIDIOCSPICT, &vid_pic) == -1) { perror ("ioctl (VIDIOCSPICT) to GREY"); return -1; } } } return 0; } /* * check if driver supports mmap'ed buffer */ int v4l_check_mmap (int fd, int *size) { struct video_mbuf vid_buf; if (ioctl (fd, VIDIOCGMBUF, &vid_buf) == -1) { return -1; } if (size) *size = vid_buf.size; return 0; } /* * mute sound if available */ int v4l_mute_sound (int fd) { struct video_capability vid_caps; struct video_audio vid_aud; if (ioctl (fd, VIDIOCGCAP, &vid_caps) == -1) { perror ("ioctl (VIDIOCGCAP)"); return -1; } if (vid_caps.audios > 0) { /* mute the sound */ if (ioctl (fd, VIDIOCGAUDIO, &vid_aud) == -1) { return -1; } else { vid_aud.flags = VIDEO_AUDIO_MUTE; if (ioctl (fd, VIDIOCSAUDIO, &vid_aud) == -1) return -1; } } return 0; } /* * Turn a YUV4:2:0 block into an RGB block * * Video4Linux seems to use the blue, green, red channel * order convention-- rgb[0] is blue, rgb[1] is green, rgb[2] is red. * * Color space conversion coefficients taken from the excellent * http://www.inforamp.net/~poynton/ColorFAQ.html * In his terminology, this is a CCIR 601.1 YCbCr -> RGB. * Y values are given for all 4 pixels, but the U (Pb) * and V (Pr) are assumed constant over the 2x2 block. * * To avoid floating point arithmetic, the color conversion * coefficients are scaled into 16.16 fixed-point integers. * They were determined as follows: * * double brightness = 1.0; (0->black; 1->full scale) * double saturation = 1.0; (0->greyscale; 1->full color) * double fixScale = brightness * 256 * 256; * int rvScale = (int)(1.402 * saturation * fixScale); * int guScale = (int)(-0.344136 * saturation * fixScale); * int gvScale = (int)(-0.714136 * saturation * fixScale); * int buScale = (int)(1.772 * saturation * fixScale); * int yScale = (int)(fixScale); */ /* LIMIT: convert a 16.16 fixed-point value to a byte, with clipping. */ #define LIMIT(x) ((x)>0xffffff?0xff: ((x)<=0xffff?0:((x)>>16))) /* */ static inline void v4l_copy_420_block (int yTL, int yTR, int yBL, int yBR, int u, int v, int rowPixels, unsigned char * rgb, int bits) { const int rvScale = 91881; const int guScale = -22553; const int gvScale = -46801; const int buScale = 116129; const int yScale = 65536; int r, g, b; g = guScale * u + gvScale * v; r = rvScale * v; b = buScale * u; yTL *= yScale; yTR *= yScale; yBL *= yScale; yBR *= yScale; if (bits == 24) { /* Write out top two pixels */ rgb[0] = LIMIT(b+yTL); rgb[1] = LIMIT(g+yTL); rgb[2] = LIMIT(r+yTL); rgb[3] = LIMIT(b+yTR); rgb[4] = LIMIT(g+yTR); rgb[5] = LIMIT(r+yTR); /* Skip down to next line to write out bottom two pixels */ rgb += 3 * rowPixels; rgb[0] = LIMIT(b+yBL); rgb[1] = LIMIT(g+yBL); rgb[2] = LIMIT(r+yBL); rgb[3] = LIMIT(b+yBR); rgb[4] = LIMIT(g+yBR); rgb[5] = LIMIT(r+yBR); } else if (bits == 16) { /* Write out top two pixels */ rgb[0] = ((LIMIT(b+yTL) >> 3) & 0x1F) | ((LIMIT(g+yTL) << 3) & 0xE0); rgb[1] = ((LIMIT(g+yTL) >> 5) & 0x07) | (LIMIT(r+yTL) & 0xF8); rgb[2] = ((LIMIT(b+yTR) >> 3) & 0x1F) | ((LIMIT(g+yTR) << 3) & 0xE0); rgb[3] = ((LIMIT(g+yTR) >> 5) & 0x07) | (LIMIT(r+yTR) & 0xF8); /* Skip down to next line to write out bottom two pixels */ rgb += 2 * rowPixels; rgb[0] = ((LIMIT(b+yBL) >> 3) & 0x1F) | ((LIMIT(g+yBL) << 3) & 0xE0); rgb[1] = ((LIMIT(g+yBL) >> 5) & 0x07) | (LIMIT(r+yBL) & 0xF8); rgb[2] = ((LIMIT(b+yBR) >> 3) & 0x1F) | ((LIMIT(g+yBR) << 3) & 0xE0); rgb[3] = ((LIMIT(g+yBR) >> 5) & 0x07) | (LIMIT(r+yBR) & 0xF8); } } /* */ static inline void v4l_copy_422_block (int yTL, int yTR, int u, int v, int rowPixels, unsigned char * rgb, int bits) { const int rvScale = 91881; const int guScale = -22553; const int gvScale = -46801; const int buScale = 116129; const int yScale = 65536; int r, g, b; g = guScale * u + gvScale * v; r = rvScale * v; b = buScale * u; yTL *= yScale; yTR *= yScale; if (bits == 24) { /* Write out top two pixels */ rgb[0] = LIMIT(b+yTL); rgb[1] = LIMIT(g+yTL); rgb[2] = LIMIT(r+yTL); rgb[3] = LIMIT(b+yTR); rgb[4] = LIMIT(g+yTR); rgb[5] = LIMIT(r+yTR); } else if (bits == 16) { /* Write out top two pixels */ rgb[0] = ((LIMIT(b+yTL) >> 3) & 0x1F) | ((LIMIT(g+yTL) << 3) & 0xE0); rgb[1] = ((LIMIT(g+yTL) >> 5) & 0x07) | (LIMIT(r+yTL) & 0xF8); rgb[2] = ((LIMIT(b+yTR) >> 3) & 0x1F) | ((LIMIT(g+yTR) << 3) & 0xE0); rgb[3] = ((LIMIT(g+yTR) >> 5) & 0x07) | (LIMIT(r+yTR) & 0xF8); } } /* * convert a YUV420P to a rgb image */ int v4l_yuv420p2rgb (unsigned char *rgb_out, unsigned char *yuv_in, int width, int height, int bits) { const int numpix = width * height; const unsigned int bytes = bits >> 3; int h, w, y00, y01, y10, y11, u, v; unsigned char *pY = yuv_in; unsigned char *pU = pY + numpix; unsigned char *pV = pU + numpix / 4; unsigned char *pOut = rgb_out; if (!rgb_out || !yuv_in) return -1; for (h = 0; h <= height - 2; h += 2) { for (w = 0; w <= width - 2; w += 2) { y00 = *(pY); y01 = *(pY + 1); y10 = *(pY + width); y11 = *(pY + width + 1); u = (*pU++) - 128; v = (*pV++) - 128; v4l_copy_420_block (y00, y01, y10, y11, u, v, width, pOut, bits); pY += 2; pOut += bytes << 1; } pY += width; pOut += width * bytes; } return 0; } /* * convert a YUV422P to a rgb image */ int v4l_yuv422p2rgb (unsigned char *rgb_out, unsigned char *yuv_in, int width, int height, int bits) { const int numpix = width * height; const unsigned int bytes = bits >> 3; int h, w, y00, y01, u, v; unsigned char *pY = yuv_in; unsigned char *pU = pY + numpix; unsigned char *pV = pU + numpix / 2; unsigned char *pOut = rgb_out; if (!rgb_out || !yuv_in) return -1; for (h = 0; h < height; h += 1) { for (w = 0; w <= width - 2; w += 2) { y00 = *(pY); y01 = *(pY + 1); u = (*pU++) - 128; v = (*pV++) - 128; v4l_copy_422_block (y00, y01, u, v, width, pOut, bits); pY += 2; pOut += bytes << 1; } //pY += width; //pOut += width * bytes; } return 0; } w3cam-0.7.2/FAQ.txt0100644000076400000620000000102307366316474012547 0ustar rascauser--- Mini FAQ ------------------------------------------------------- Q: vidcat is running fine, but with w3cam.cgi I can't see an image. ___A: Check if the user under which the CGI is running (e.g. "wwwrun") has the right to access the video device (/dev/video). Q: The refresh is not running while using IE. ___A: The used refresh method is only supported by Netscape. Q: As soon as I start "vidcat" my system freezes. Can you help? ___A: No! A system hang is allways a problem of the driver. -- 26. Oct 2001 - 19:27 w3cam-0.7.2/samples/0040755000076400000620000000000007341502706013036 5ustar rascauserw3cam-0.7.2/samples/w3cam.css0120777000076400000620000000000007152520343016512 2../w3cam.cssustar rascauserw3cam-0.7.2/samples/menu.html0100644000076400000620000000077707341502173014676 0ustar rascauser
Quality: Refresh:
w3cam-0.7.2/samples/double.html0100644000076400000620000000047106624010064015167 0ustar rascauser double tv

Your browser can't handle frames ...

w3cam-0.7.2/samples/tripple.html0100644000076400000620000000061506624007155015403 0ustar rascauser tripple tv

Your browser can't handle frames ...

w3cam-0.7.2/samples/bg2.html0100644000076400000620000000103407047031222014362 0ustar rascauser

 

In this example the CGI is used to generate a refreshing background image .. :-)

w3cam-0.7.2/samples/frames.html0100644000076400000620000000050407341502534015174 0ustar rascauser w3cam-0.7.2/samples/bg.html0100644000076400000620000000102107047031174014302 0ustar rascauser

 

In this example the CGI is used to generate a refreshing background image .. :-)

w3cam-0.7.2/samples/index.html0100644000076400000620000000234707341502706015036 0ustar rascauser w3cam demo page

w3cam.cgi Demo Page

First install w3cam.cgi before testing the following links.

Note: you have to enable JavaScript to make the following links to work.

View 1 Channel
View 2 Channels
View 3 Channels
View as background image (JPEG, B/W)
View as background image (PNG, color)
View with a self made control frame (color)


[Index]
rasca, 28. Aug 2000 - 19:34 w3cam-0.7.2/v4l.h0100644000076400000620000000240307412657511012250 0ustar rascauser/* * v4l.h * * Copyright (C) 2001 Rasca, Berlin * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __V4L_H__ #define __V4L_H__ #define INPUT_DEFAULT -1 #define NORM_DEFAULT -1 #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif int v4l_set_input (int fd, int input, int norm); int v4l_check_size (int fd, int *width, int *height); int v4l_check_palette (int fd, int *palette); int v4l_mute_sound (int fd); int v4l_check_mmap (int fd, int *size); int v4l_yuv420p2rgb (unsigned char *, unsigned char *, int, int, int); int v4l_yuv422p2rgb (unsigned char *, unsigned char *, int, int, int); #endif w3cam-0.7.2/vidcat.man0100644000076400000620000000330607366312050013336 0ustar rascauser.\" .\" Written by Rasca, Berlin 2001 .\" Published under the GNU GPL V2 .\" .TH VIDCAT 1 "Oct 2001" "GNU" "Version VERSION" .SH NAME vidcat - capture a frame from a video4linux device .SH SYNOPSIS .BI "vidcat [-h?blgV] [-d " "] [-f "jpeg|ppm|png "] [-i "tv|comp1|com1|s-video "] [-n "pal|ntsc|secam "] [-q "<1..100> "] [-s "WIDTHxHEIGHT "] [-o " "] .SH DESCRIPTION .I vidcat captures a frame from a video4linux device and writes the result to the standard output device. With the following options you can define output format, size etc.. .SH OPTIONS .TP -d device Use an alternate v4l device, '/dev/video' is the default device. .TP -b This applies only to PPM output. With this option the PPM ouput is written in binary mode. .TP -f ppm|jpeg|png|yuv4mpeg Define the file format to use for the output stream. The default is "jpeg". .TP -g Use greyscale instead of RGB24 for the output data. .TP -i tv|comp1|comp2|s-video Set the input channel to use. The default value is none, which means the preset of the device is used. .TP -l Loops until CTRL+C is pressed. This is the default for the YUV4MPEG output. .TP -n pal|ntsc|secam Select the input norm for the grabbing device. The default value is none. .TP -o file Use the named file for output instead of standard out. .TP -p c|g|y|Y Set the palette to use: c = RGB24, g=GREY, y=YUV420P, Y=YUV422P. .TP -q 1..100 Set the quality for JPEG output. The value could be a number between 1 and 100. The default value is 80. .TP -s WIDTHxHEIGHT Define the size of the output frame in pixels. The default setting is 320x240. .TP -V Show version number and exit. .SH AUTHOR Rasca .br http://home.pages.de/~rasca/ .br VIDCAT is published under the GNU General Public License w3cam-0.7.2/vidcat.10100644000076400000620000000330407366312051012722 0ustar rascauser.\" .\" Written by Rasca, Berlin 2001 .\" Published under the GNU GPL V2 .\" .TH VIDCAT 1 "Oct 2001" "GNU" "Version 0.7.1" .SH NAME vidcat - capture a frame from a video4linux device .SH SYNOPSIS .BI "vidcat [-h?blgV] [-d " "] [-f "jpeg|ppm|png "] [-i "tv|comp1|com1|s-video "] [-n "pal|ntsc|secam "] [-q "<1..100> "] [-s "WIDTHxHEIGHT "] [-o " "] .SH DESCRIPTION .I vidcat captures a frame from a video4linux device and writes the result to the standard output device. With the following options you can define output format, size etc.. .SH OPTIONS .TP -d device Use an alternate v4l device, '/dev/video' is the default device. .TP -b This applies only to PPM output. With this option the PPM ouput is written in binary mode. .TP -f ppm|jpeg|png|yuv4mpeg Define the file format to use for the output stream. The default is "jpeg". .TP -g Use greyscale instead of RGB24 for the output data. .TP -i tv|comp1|comp2|s-video Set the input channel to use. The default value is none, which means the preset of the device is used. .TP -l Loops until CTRL+C is pressed. This is the default for the YUV4MPEG output. .TP -n pal|ntsc|secam Select the input norm for the grabbing device. The default value is none. .TP -o file Use the named file for output instead of standard out. .TP -p c|g|y|Y Set the palette to use: c = RGB24, g=GREY, y=YUV420P, Y=YUV422P. .TP -q 1..100 Set the quality for JPEG output. The value could be a number between 1 and 100. The default value is 80. .TP -s WIDTHxHEIGHT Define the size of the output frame in pixels. The default setting is 320x240. .TP -V Show version number and exit. .SH AUTHOR Rasca .br http://home.pages.de/~rasca/ .br VIDCAT is published under the GNU General Public License w3cam-0.7.2/COPYING.txt0100644000076400000620000004307606622025443013251 0ustar rascauser 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 Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. 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) 19yy 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., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. w3cam-0.7.2/ChangeLog.txt0100644000076400000620000001404307412662171013763 0ustar rascauser27.12.2001 - released 0.7.2 - w3cam.cgi: added default input in the gui mode - added new option "bgr=1" to swap RGB24 to BGR24 - fixed v4l.c:v4l_set_input() for the ov511 driver 11.11.2001 - added my new email address 28.10.2001 - vidcat.c: terminate for a wrong "-i" argument with usage() 28.10.2001 - released 0.7.1 - vidcat: use RGB24 as the default palette 10.10.2001 - vidcat: new switch "-V" to show version number - configure.in: new switch for the freetype includes - vidcat.c: fixed usage() 31.08.2001 - w3cam.c: removed _check_palette() - some changes in w3cam.c to support yuv config option - added yuv support for drivers without mmap() support (not tested) 29.08.2001 - released 0.7.0 - new option for vidcat to spezify the video palette cause the auto detection doesn't work. 28.08.2001 - added YUV422P support - updated usage() in vidcat 24.08.2001 - moved yuv stuff to v4l.c - added YUV support for camera which don't support mmap() 24.08.2001 - released 0.6.9 - added the YUV420P stuff to w3cam.cgi as well - added grey scale jpeg support to vidcat.c - some reorganisations in the vidcat.c code - added the patch from nicholas to support YUV420P input - added manpage for vidcat 31.07.2001 - vidcat.c: new option "-n " to switch to e.g. ntsc - vidcat.c: return 1 instead of 0 if device can't be opened 31.07.2001 - released 0.6.8 - w3cam.c: changed argument to ioctl() for SYNC 28.08.2000 - released 0.6.7 - added new option value "mode=html" which will produce a plain html page with the image embedded. this meight be usefull in frame constructions.. see samples/frames.html and menu.html 21.08.2000 - released 0.6.6 - vidcat: added verbose switch - w3camd: minor changes to get it working without mmap(), e.g. video loopback from motion but w3camd is still a buggy dirty hack :-) 16.07.2000 - w3cam.c: added new config file parameter: device - w3cam.c: minor changes in usage() - font.c: some changes to unsigned int/char * to get ASCII > 127 in timestamps working 20.05.2000 - w3camd/w3jpeg.c: don't use ERREXIT() so i can handle sig pipes 01.05.2000 - vidcat.c: set width/height for devices which don't support mmap() - w3camd/w3jpeg.c: increased buffer size to 2048 - w3camd/w3camd.c: changed version number to 0.3 - w3camd: added w3log.h 27.04.2000 - w3camd/w3camd.c: added option "-d " - w3cam.c: added read() support for devices that don't like mmap() (untested), same for w3camd. 15.02.2000 - fixed a small bug in Makefile.in to prevent linking vidcat with cgi.o 08.02.2000 - released 0.6.5 - w3cam.c: changed perror() to log2() 05.02.2000 - close device before sending the file, so concurrent running CGIs have better chances to open the device 22.01.2000 - fixed memory leak in vidcat.c:put_image_jpeg() 22.01.2000 - released 0.6.4 - w3cam.c: added new config keyword "protected" which when enabled skips the process of parsing form variables - w3cam.c: fixed a small bug which resulted in bad timestamp pixmaps 21.01.2000 - minor cosmetic changes 21.01.2000 - released 0.6.3 - w3cam.c: fixed memory leak in put_image_png() - w3cam.c,font.c: added timestamp feature, not perfect until now, needs the freetype library 20.01.2000 - w3cam.c: fixed 2 memory leaks 03.09.1999 - small memory leack fix in w3camd 12.08.1999 - released 0.6.2 - minor changes in index.html 06.07.1999 - w3cam.cgi: added some lines to support gray JPEGs and PNGs 25.01.1999 - released 0.6.1 - vidcat.c: use normal read() of mmap() is not supported (not tested!) - vidcat.c: usage() gives more compiled-in default values - minor changes in Makefile.in - vidcat: print errors to stderr instead of stdout 30.12.1998 - added ppmtoascii - just an test program, ignore it - added "-b" for binary PPM to vidcat and modified the conversion function - changed usage() of vidcat.c - add Makefile.std for the case that configure will not run 30.12.1998 - released version 0.6 - added check for math-lib (needed on some systems for libpng !?...) to the configure.in script - changed cgi.c to allow non-quoted values in the config file 09.12.1998 - added "--with-syslog" to the configure script - added "norm" to the form options and added SIGTERM and SIGPIPE handling (thx to brian@balancesoftware.com) 01.12.1998 - changed w3camd.c:image.refresh to float - added arg "?quality=#" to w3camd - added "-i " to w3camd.c 30.11.1998 - released version 0.5 - w3camd seems to work but is not stable :( 28.11.1998 - added w3camd/ directory with a simple daemon 27.11.1998 - renamed vcat to vidcat, cause there is still an other tools which is named vcat 16.11.1998 - w3cam.c: do not close/open if refresh time == 0.0 - w3cam.c: changed quality_default to from 75 to 65 - w3cam.c: changed wait loop for open device to 1/4 second / 20 times - w3cam.c: changed "refresh" to float value 15.11.1998 - vcat.c: added loop option "-l" (does it make sense?, piping to xli doesn't work:() - w3cam.c,vcat.c: added "cjpeg.dct_method = JDCT_FASTEST;" 13.11.1998 - added "freqlist" to the config file 12.11.1998 - added option "freq" to set frequenzy for tuner, set to "0" if you want to use the value which was set by an other program like xawtv. - added tripple.html and double.html as an example to watch three inputs at the same time :) - changed w3cam.c and w3cam.css to introduce a class "image" - add compile time option MIN_REFRESH to ensure minimal refresh time. so no one could set a short refresh time to overload your system. 12.11.1998 - released version 0.4 - changed get_image() to mute audio (Chris Dornfeld and Mat Withers wanted this feature) nevertheless there is a little bit sound for some milisecs cause there is time between opening the device and setting the device to mute :( - changed get_image(): introduced new option (usleep) for sleeping some micro seconds before capturing, cause Mat Withers said his intel card needs it to adjust it's brightness level.. set USEC_DEFAULT in w3cam.c to e.g. 500000 to sleep half a second - started ChangeLog