diff options
author | Hans-Christoph Steiner <eighthave@users.sourceforge.net> | 2003-08-11 04:26:00 +0000 |
---|---|---|
committer | Hans-Christoph Steiner <eighthave@users.sourceforge.net> | 2003-08-11 04:26:00 +0000 |
commit | c5e843b82205c04c618a423d3bb223f1f630b7a1 (patch) | |
tree | 47eb18ea910be2d9735290aef960fd458b46d29c |
added sources from pidip-0.12.4svn2git-root
svn path=/trunk/externals/pidip/; revision=837
121 files changed, 35071 insertions, 0 deletions
diff --git a/CHANGES.LOG b/CHANGES.LOG new file mode 100644 index 0000000..681074f --- /dev/null +++ b/CHANGES.LOG @@ -0,0 +1,125 @@ +0.12.4 + added pdp_imgsaver : save an image from the current video stream + pdp_transition : added "melt" and "blend" transitions +0.12.3 + added pdp_imgloader : load an image and blend it with a video + added pdp_transition : some funky transitions, "circle", "wipe" and "random" + added pdp_lumafilt : lumosity filter, useful to isolate some objects + added pdp_smuck : same as pdp_transform ( mode 5 ) but setable, ported from veejay +0.12.2 + Fixed problems with Image Magick includes +0.12.1 + Added color components output in pdp_ctrack +0.12.0 + Compatibility with PDP 0.12 +0.11.3 + Nicolas Lhommet added scroll parameter in pdp_text +0.11.2 + added pdp_capture : capture a portion of screen : lets you import browser data, etc .... + fixed pdp_compose +0.11.1 + added pdp_juxta : allow juxtaposition of frames +0.11.0 + change some packet allocation policies to comply with PDP 0.11 + no new object +0.10.1 + added pdp_noquark object : moving object are clear, the background is noisy + added tolerance input in pdp_quark +0.10.0 + added pdp_segsnd~ : produces sound from a segment of the video ( similar to pdp_scanxy~ ) + binary compatible with pdp v.0.10 + improved installation instructions +0.9.2 + fixed disconnection phase in pdp_live~ +0.9.1 + remove synchronization proposed by martin pi : it lead to some deadlocks sometimes +0.9.0 + fixed audio encoding/decoding in pdp_ffmpeg~/pdp_live~ ( which caused a lot of crashes ) + add synchronization in pdp_live~ and other nice features ( thanks to martin pi ) + made the audio decoding in pdp_live~ optional + add "set cursor" message in pdp_cmap, pdp_ctrack, pdp_compose + ( used in conjonction with coordinates output of pdp_xv v0.9 ) +0.8.4 + added pdp_live~ : receive a video feed, at least from a ffmpeg server ( ffserver ) + fixed resampling in pdp_ffmpeg~ : resizing to a bigger image used to crash PD + ( now, you can't resize to a bigger scale, blame it on libavcodec ) +0.8.3 + pdp_rec became pdp_rec~ : it can record audio now + fix crash in pdp_ascii, pdp_nervous, pdp_quark +0.8.2 + added pdp_ffmpeg : stream to a ffmpeg server with possibly several formats ( mpeg, asf, ... ) + NOTE : although there is an experimental audio streaming possibility, + there are BIG synchronization issues and it's recommended to use mp3cast~ for audio streaming. + added a ratio action in pdp_ascii + added a planes number action in pdp_quark and pdp_nervous ( plays on speed of switching ) + fixed index bug in pdp_ctrack, pdp_cmap +0.8.1 + fixed colors in pdp_warhol +0.8.0 + added pdp_ascii : rendering of videos in ASCII art using character maps +0.7.7 + added pdp_aa : rendering of videos in ASCII art using aalib +0.7.6 + added pdp_cmap : color mapper ( thanx to liz for the suggestion ) + added actions in color tracker ( steady mode, cursor on/off, frame on/off ), generally improved + fixed colors in pdp_spiral, pdp_dice +0.7.5 + added pdp_form : addition of geometric forms + added pdp_compose : color-based video compositor ( thanx to liz for the suggestion ) + added actions in pdp_text ( rotations, font, resize, dither, blend ) + fixed colors in pdp_transform, pdp_warp + fix install stage +0.7.4 + added pdp_text : text addition on videos ( requires imlib2 ) + use the automake/autoconf system + optimized streaming again (pdp_i/pdp_o) + fixed colors in pdp_puzzle +0.7.3 + fixed streaming objects pdp_i/pdp_o + added "smoothing" and "framerate" controls to act on the bandwidth +0.7.2 + added shagadelic, dice and puzzle from effecTV + modified objects to use PDP queue +0.7.1 + added cycle and transform : first effetTV objects using PDP queue + ( i know i changed my mind ) + all other objects must be modified to use PDP queue +0.7.0 + compatibility with PDP 0.7 +0.6.2 + added pdp_ctrack : color tracker : lets you follow an object +0.6.1 + added pdp_i/pdp_o : PDP packets streaming objects using bz2 + added pdp_mgrid : motion grid detects movement within a grid +0.6.0 + added pdp_rec : a video recording object + fixed a bug in pdp_edge + incremented PDP release number : it's now 0.6 + set proper credits for each effecTV plugin +0.5.8 + added pdp_spigot : a video signal routing utility +0.5.7 + added nervous and quark objects + these will be the last effecTV objects added + some effectv have been left aside ( fireTV, ... ) + because they are just clones of some other effects + or because i simply wasn't interested in porting them +0.5.6 + added radioactiv and warhol objects +0.5.5 + added edge and spiral objects + happy new year 2003 +0.5.4 + renamed to PiDiP + added rev and mosaic objects +0.5.3 + added parameter "increment" to ripple + fix "threshold" in ripple + added warp and mosaic object +0.5.2 + remove buggy support of GREY packets +0.5.1 + added aging and ripple effects +0.5 + initial release + it is called 0.5 because it should be used with PDP 0.5 @@ -0,0 +1,35 @@ +first, install : + +imlib2 ( http://sourceforge.net/project/showfiles.php?group_id=2 ) +aalib (http://aa-project.sourceforge.net/aalib/) +Image Magick ( http://www.imagemagick.org ) +and ffmpeg ( watchout, it requires the cvs snapshot ! ) ( http://ffmpeg.sourceforge.net/cvs ) + +you should also have installed libquicktime that is necessary for PDP +( http://sourceforge.net/projects/libquicktime ). + +gone through it ?? yeh, i know it's a lot. +ok, first stage reached ) + +fix PD, PDP and FFMPEG paths in configure.ac + +autoconf + +./configure + +make clean + +make + +as root, make install + +pidip is a library, it should be loaded +with the "-lib <path>/pidip" command line option +but, BEWARE, it should be place AFTER the +loading of PDP library ( option "-lib <path>/pdp" ) + +Enjoy!! + +Thanx for getting here. +Yves/ +comments and bugs @ ydegoyon@free.fr diff --git a/KNOWN.BUGS b/KNOWN.BUGS new file mode 100644 index 0000000..095255f --- /dev/null +++ b/KNOWN.BUGS @@ -0,0 +1,2 @@ +pdp_live~ : requires a huge block size to operate ( otherwise, sound is shitty ) +pdp_capture : does not capture certain types of windows ( xvideo, frame buffers ) diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..022f970 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,58 @@ +PD_DIR = @PD_DIR@ +PDP_DIR = @PDP_DIR@ +FFMPEG_SOURCE_DIR = @FFMPEG_SOURCE_DIR@ + +LIBS = @LIBS@ +IMLIB_CFLAGS = @IMLIB_CFLAGS@ +IMLIB_LIBS = @IMLIB_LIBS@ +AALIB_CFLAGS = @AALIB_CFLAGS@ +AALIB_LIBS = @AALIB_LIBS@ +MAGICK_CFLAGS = @MAGICK_CFLAGS@ +MAGICK_LIBS = @MAGICK_LIBS@ +PDP_PIDIP_VERSION = @PDP_PIDIP_VERSION@ + +PDP_PIDIP_DISTRO = /mnt/c/ydegoyon.free.fr/pidip-$(PDP_PIDIP_VERSION) +PDP_PIDIP_TARBALL = $(PDP_PIDIP_DISTRO).tar.gz +# build flags + +PDP_PIDIP_INCLUDE = -I$(PD_DIR)/src -I. -I$(PDP_DIR)/include -I$(FFMPEG_SOURCE_DIR)/libavcodec -I$(FFMPEG_SOURCE_DIR)/libavformat -I../include +PDP_PIDIP_CFLAGS = $(MAGICK_CFLAGS) $(AALIB_CFLAGS) $(IMLIB_CFLAGS) \ + -DPD -DX_DISPLAY_MISSING -O2 -funroll-loops -fomit-frame-pointer -ffast-math \ + -Wall -W -Wstrict-prototypes \ + -Wno-unused -Wno-parentheses -Wno-switch \ + -DPDP_PIDIP_VERSION=\"$(PDP_PIDIP_VERSION)\" \ + -g +PDP_PIDIP_CPPFLAGS = -O + +all: pidip.pd_linux + +pdp_pidip_all: + make -C system + make -C modules + +pidip.pd_linux: pdp_pidip_all + rm -f pidip.pd_linux + gcc -export_dynamic -shared -o pidip.pd_linux modules/*.o system/*.o $(FFMPEG_SOURCE_DIR)/libavformat/libavformat.a $(FFMPEG_SOURCE_DIR)/libavcodec/libavcodec.a $(LIBS) $(IMLIB_LIBS) $(AALIB_LIBS) $(MAGICK_LIBS) + +clean: + rm -f */*.o + rm -f pidip.pd_linux + rm -f *~ + +install: + cp fonts/* /usr/X11R6/lib/X11/fonts/TTF + +distro: clean all + rm */*.o + strip --strip-unneeded pidip.pd_linux + cd .. && cp -rf pidip /tmp/pidip-$(PDP_PIDIP_VERSION) + cd /tmp && tar vczf $(PDP_PIDIP_TARBALL) pidip-$(PDP_PIDIP_VERSION) + cp /mnt/c/ydegoyon.free.fr/pidip-$(PDP_PIDIP_VERSION).tar.gz /mnt/c/Yves + rm -rf /tmp/pidip-$(PDP_PIDIP_VERSION) + +.c.o: + gcc $(PDP_PIDIP_CFLAGS) $(PDP_PIDIP_INCLUDE) -o $*.o -c $*.c + +.cpp.o: + g++ $(PDP_PIDIP_CPPFLAGS) $(PDP_PIDIP_INCLUDE) -o $*.o -c $*.cpp + @@ -0,0 +1,28 @@ +*****************************************************************************
+copyleft 2002 by Yves Degoyon ( ydegoyon@free.fr )
+
+thanx for their remarks and support :
+
+Béatrice Rettig
+Cécile Babiole
+
+tarballs and updates available @ http://ydegoyon.free.fr
+
+pidip : additional video objects for Pure Data Packet
+some of them are adapted from EffecTV
+(http://effectv.sourceforge.net/)
+or other source mentionned
+
+To install pidip, follow the steps from INSTALL
+
+This software is published under GPL terms.
+
+This is software with ABSOLUTELY NO WARRANTY.
+Use it at your OWN RISK. It's possible to damage e.g. hardware or your hearing
+due to a bug or for other reasons.
+We do not warrant that the program is free of infringement of any third-party
+patents.
+
+*****************************************************************************
+
+
diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 0000000..6e1c420 --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,136 @@ +dnl @synopsis AC_PATH_GENERIC(LIBRARY [, MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl +dnl Runs a LIBRARY-config script and defines LIBRARY_CFLAGS and LIBRARY_LIBS +dnl +dnl The script must support `--cflags' and `--libs' args. +dnl If MINIMUM-VERSION is specified, the script must also support the +dnl `--version' arg. +dnl If the `--with-library-[exec-]prefix' arguments to ./configure are given, +dnl it must also support `--prefix' and `--exec-prefix'. +dnl (In other words, it must be like gtk-config.) +dnl +dnl For example: +dnl +dnl AC_PATH_GENERIC(Foo, 1.0.0) +dnl +dnl would run `foo-config --version' and check that it is at least 1.0.0 +dnl +dnl If so, the following would then be defined: +dnl +dnl FOO_CFLAGS to `foo-config --cflags` +dnl FOO_LIBS to `foo-config --libs` +dnl +dnl At present there is no support for additional "MODULES" (see AM_PATH_GTK) +dnl (shamelessly stolen from gtk.m4 and then hacked around a fair amount) +dnl +dnl @author Angus Lees <gusl@cse.unsw.edu.au> +dnl @version $Id: acinclude.m4,v 1.1 2003-08-11 04:26:00 eighthave Exp $ + +AC_DEFUN(AC_PATH_GENERIC, +[dnl +dnl we're going to need uppercase, lowercase and user-friendly versions of the +dnl string `LIBRARY' +pushdef([UP], translit([$1], [a-z], [A-Z]))dnl +pushdef([DOWN], translit([$1], [A-Z], [a-z]))dnl + +dnl +dnl Get the cflags and libraries from the LIBRARY-config script +dnl +AC_ARG_WITH(DOWN-prefix,[ --with-]DOWN[-prefix=PFX Prefix where $1 is installed (optional)], + DOWN[]_config_prefix="$withval", DOWN[]_config_prefix="") +AC_ARG_WITH(DOWN-exec-prefix,[ --with-]DOWN[-exec-prefix=PFX Exec prefix where $1 is installed (optional)], + DOWN[]_config_exec_prefix="$withval", DOWN[]_config_exec_prefix="") + + if test x$DOWN[]_config_exec_prefix != x ; then + DOWN[]_config_args="$DOWN[]_config_args --exec-prefix=$DOWN[]_config_exec_prefix" + if test x${UP[]_CONFIG+set} != xset ; then + UP[]_CONFIG=$DOWN[]_config_exec_prefix/bin/DOWN-config + fi + fi + if test x$DOWN[]_config_prefix != x ; then + DOWN[]_config_args="$DOWN[]_config_args --prefix=$DOWN[]_config_prefix" + if test x${UP[]_CONFIG+set} != xset ; then + UP[]_CONFIG=$DOWN[]_config_prefix/bin/DOWN-config + fi + fi + + AC_PATH_PROG(UP[]_CONFIG, DOWN-config, no) + ifelse([$2], , + AC_MSG_CHECKING(for $1), + AC_MSG_CHECKING(for $1 - version >= $2) + ) + no_[]DOWN="" + if test "$UP[]_CONFIG" = "no" ; then + no_[]DOWN=yes + else + UP[]_CFLAGS="`$UP[]_CONFIG $DOWN[]_config_args --cflags`" + UP[]_LIBS="`$UP[]_CONFIG $DOWN[]_config_args --libs`" + ifelse([$2], , ,[ + DOWN[]_config_major_version=`$UP[]_CONFIG $DOWN[]_config_args \ + --version | sed 's/[[^0-9]]*\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + DOWN[]_config_minor_version=`$UP[]_CONFIG $DOWN[]_config_args \ + --version | sed 's/[[^0-9]]*\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + DOWN[]_config_micro_version=`$UP[]_CONFIG $DOWN[]_config_args \ + --version | sed 's/[[^0-9]]*\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + DOWN[]_wanted_major_version="regexp($2, [\<\([0-9]*\)], [\1])" + DOWN[]_wanted_minor_version="regexp($2, [\<\([0-9]*\)\.\([0-9]*\)], [\2])" + DOWN[]_wanted_micro_version="regexp($2, [\<\([0-9]*\).\([0-9]*\).\([0-9]*\)], [\3])" + + # Compare wanted version to what config script returned. + # If I knew what library was being run, i'd probably also compile + # a test program at this point (which also extracted and tested + # the version in some library-specific way) + if test "$DOWN[]_config_major_version" -lt \ + "$DOWN[]_wanted_major_version" \ + -o \( "$DOWN[]_config_major_version" -eq \ + "$DOWN[]_wanted_major_version" \ + -a "$DOWN[]_config_minor_version" -lt \ + "$DOWN[]_wanted_minor_version" \) \ + -o \( "$DOWN[]_config_major_version" -eq \ + "$DOWN[]_wanted_major_version" \ + -a "$DOWN[]_config_minor_version" -eq \ + "$DOWN[]_wanted_minor_version" \ + -a "$DOWN[]_config_micro_version" -lt \ + "$DOWN[]_wanted_micro_version" \) ; then + # older version found + no_[]DOWN=yes + echo -n "*** An old version of $1 " + echo -n "($DOWN[]_config_major_version" + echo -n ".$DOWN[]_config_minor_version" + echo ".$DOWN[]_config_micro_version) was found." + echo -n "*** You need a version of $1 newer than " + echo -n "$DOWN[]_wanted_major_version" + echo -n ".$DOWN[]_wanted_minor_version" + echo ".$DOWN[]_wanted_micro_version." + echo "***" + echo "*** If you have already installed a sufficiently new version, this error" + echo "*** probably means that the wrong copy of the DOWN-config shell script is" + echo "*** being found. The easiest way to fix this is to remove the old version" + echo "*** of $1, but you can also set the UP[]_CONFIG environment to point to the" + echo "*** correct copy of DOWN-config. (In this case, you will have to" + echo "*** modify your LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf" + echo "*** so that the correct libraries are found at run-time)" + fi + ]) + fi + if test "x$no_[]DOWN" = x ; then + AC_MSG_RESULT(yes) + ifelse([$3], , :, [$3]) + else + AC_MSG_RESULT(no) + if test "$UP[]_CONFIG" = "no" ; then + echo "*** The DOWN-config script installed by $1 could not be found" + echo "*** If $1 was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the UP[]_CONFIG environment variable to the" + echo "*** full path to DOWN-config." + fi + UP[]_CFLAGS="" + UP[]_LIBS="" + ifelse([$4], , :, [$4]) + fi + AC_SUBST(UP[]_CFLAGS) + AC_SUBST(UP[]_LIBS) + + popdef([UP]) + popdef([DOWN]) +]) diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..cdbfaeb --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,4112 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4-p4 + +dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +dnl @synopsis AC_PATH_GENERIC(LIBRARY [, MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl +dnl Runs a LIBRARY-config script and defines LIBRARY_CFLAGS and LIBRARY_LIBS +dnl +dnl The script must support `--cflags' and `--libs' args. +dnl If MINIMUM-VERSION is specified, the script must also support the +dnl `--version' arg. +dnl If the `--with-library-[exec-]prefix' arguments to ./configure are given, +dnl it must also support `--prefix' and `--exec-prefix'. +dnl (In other words, it must be like gtk-config.) +dnl +dnl For example: +dnl +dnl AC_PATH_GENERIC(Foo, 1.0.0) +dnl +dnl would run `foo-config --version' and check that it is at least 1.0.0 +dnl +dnl If so, the following would then be defined: +dnl +dnl FOO_CFLAGS to `foo-config --cflags` +dnl FOO_LIBS to `foo-config --libs` +dnl +dnl At present there is no support for additional "MODULES" (see AM_PATH_GTK) +dnl (shamelessly stolen from gtk.m4 and then hacked around a fair amount) +dnl +dnl @author Angus Lees <gusl@cse.unsw.edu.au> +dnl @version $Id: aclocal.m4,v 1.1 2003-08-11 04:26:00 eighthave Exp $ + +AC_DEFUN(AC_PATH_GENERIC, +[dnl +dnl we're going to need uppercase, lowercase and user-friendly versions of the +dnl string `LIBRARY' +pushdef([UP], translit([$1], [a-z], [A-Z]))dnl +pushdef([DOWN], translit([$1], [A-Z], [a-z]))dnl + +dnl +dnl Get the cflags and libraries from the LIBRARY-config script +dnl +AC_ARG_WITH(DOWN-prefix,[ --with-]DOWN[-prefix=PFX Prefix where $1 is installed (optional)], + DOWN[]_config_prefix="$withval", DOWN[]_config_prefix="") +AC_ARG_WITH(DOWN-exec-prefix,[ --with-]DOWN[-exec-prefix=PFX Exec prefix where $1 is installed (optional)], + DOWN[]_config_exec_prefix="$withval", DOWN[]_config_exec_prefix="") + + if test x$DOWN[]_config_exec_prefix != x ; then + DOWN[]_config_args="$DOWN[]_config_args --exec-prefix=$DOWN[]_config_exec_prefix" + if test x${UP[]_CONFIG+set} != xset ; then + UP[]_CONFIG=$DOWN[]_config_exec_prefix/bin/DOWN-config + fi + fi + if test x$DOWN[]_config_prefix != x ; then + DOWN[]_config_args="$DOWN[]_config_args --prefix=$DOWN[]_config_prefix" + if test x${UP[]_CONFIG+set} != xset ; then + UP[]_CONFIG=$DOWN[]_config_prefix/bin/DOWN-config + fi + fi + + AC_PATH_PROG(UP[]_CONFIG, DOWN-config, no) + ifelse([$2], , + AC_MSG_CHECKING(for $1), + AC_MSG_CHECKING(for $1 - version >= $2) + ) + no_[]DOWN="" + if test "$UP[]_CONFIG" = "no" ; then + no_[]DOWN=yes + else + UP[]_CFLAGS="`$UP[]_CONFIG $DOWN[]_config_args --cflags`" + UP[]_LIBS="`$UP[]_CONFIG $DOWN[]_config_args --libs`" + ifelse([$2], , ,[ + DOWN[]_config_major_version=`$UP[]_CONFIG $DOWN[]_config_args \ + --version | sed 's/[[^0-9]]*\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + DOWN[]_config_minor_version=`$UP[]_CONFIG $DOWN[]_config_args \ + --version | sed 's/[[^0-9]]*\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + DOWN[]_config_micro_version=`$UP[]_CONFIG $DOWN[]_config_args \ + --version | sed 's/[[^0-9]]*\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + DOWN[]_wanted_major_version="regexp($2, [\<\([0-9]*\)], [\1])" + DOWN[]_wanted_minor_version="regexp($2, [\<\([0-9]*\)\.\([0-9]*\)], [\2])" + DOWN[]_wanted_micro_version="regexp($2, [\<\([0-9]*\).\([0-9]*\).\([0-9]*\)], [\3])" + + # Compare wanted version to what config script returned. + # If I knew what library was being run, i'd probably also compile + # a test program at this point (which also extracted and tested + # the version in some library-specific way) + if test "$DOWN[]_config_major_version" -lt \ + "$DOWN[]_wanted_major_version" \ + -o \( "$DOWN[]_config_major_version" -eq \ + "$DOWN[]_wanted_major_version" \ + -a "$DOWN[]_config_minor_version" -lt \ + "$DOWN[]_wanted_minor_version" \) \ + -o \( "$DOWN[]_config_major_version" -eq \ + "$DOWN[]_wanted_major_version" \ + -a "$DOWN[]_config_minor_version" -eq \ + "$DOWN[]_wanted_minor_version" \ + -a "$DOWN[]_config_micro_version" -lt \ + "$DOWN[]_wanted_micro_version" \) ; then + # older version found + no_[]DOWN=yes + echo -n "*** An old version of $1 " + echo -n "($DOWN[]_config_major_version" + echo -n ".$DOWN[]_config_minor_version" + echo ".$DOWN[]_config_micro_version) was found." + echo -n "*** You need a version of $1 newer than " + echo -n "$DOWN[]_wanted_major_version" + echo -n ".$DOWN[]_wanted_minor_version" + echo ".$DOWN[]_wanted_micro_version." + echo "***" + echo "*** If you have already installed a sufficiently new version, this error" + echo "*** probably means that the wrong copy of the DOWN-config shell script is" + echo "*** being found. The easiest way to fix this is to remove the old version" + echo "*** of $1, but you can also set the UP[]_CONFIG environment to point to the" + echo "*** correct copy of DOWN-config. (In this case, you will have to" + echo "*** modify your LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf" + echo "*** so that the correct libraries are found at run-time)" + fi + ]) + fi + if test "x$no_[]DOWN" = x ; then + AC_MSG_RESULT(yes) + ifelse([$3], , :, [$3]) + else + AC_MSG_RESULT(no) + if test "$UP[]_CONFIG" = "no" ; then + echo "*** The DOWN-config script installed by $1 could not be found" + echo "*** If $1 was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the UP[]_CONFIG environment variable to the" + echo "*** full path to DOWN-config." + fi + UP[]_CFLAGS="" + UP[]_LIBS="" + ifelse([$4], , :, [$4]) + fi + AC_SUBST(UP[]_CFLAGS) + AC_SUBST(UP[]_LIBS) + + popdef([UP]) + popdef([DOWN]) +]) + +# Configure paths for GTK+ +# Owen Taylor 97-11-3 + +dnl AM_PATH_GTK([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, MODULES]]]]) +dnl Test for GTK, and define GTK_CFLAGS and GTK_LIBS +dnl +AC_DEFUN(AM_PATH_GTK, +[dnl +dnl Get the cflags and libraries from the gtk-config script +dnl +AC_ARG_WITH(gtk-prefix,[ --with-gtk-prefix=PFX Prefix where GTK is installed (optional)], + gtk_config_prefix="$withval", gtk_config_prefix="") +AC_ARG_WITH(gtk-exec-prefix,[ --with-gtk-exec-prefix=PFX Exec prefix where GTK is installed (optional)], + gtk_config_exec_prefix="$withval", gtk_config_exec_prefix="") +AC_ARG_ENABLE(gtktest, [ --disable-gtktest Do not try to compile and run a test GTK program], + , enable_gtktest=yes) + + for module in . $4 + do + case "$module" in + gthread) + gtk_config_args="$gtk_config_args gthread" + ;; + esac + done + + if test x$gtk_config_exec_prefix != x ; then + gtk_config_args="$gtk_config_args --exec-prefix=$gtk_config_exec_prefix" + if test x${GTK_CONFIG+set} != xset ; then + GTK_CONFIG=$gtk_config_exec_prefix/bin/gtk-config + fi + fi + if test x$gtk_config_prefix != x ; then + gtk_config_args="$gtk_config_args --prefix=$gtk_config_prefix" + if test x${GTK_CONFIG+set} != xset ; then + GTK_CONFIG=$gtk_config_prefix/bin/gtk-config + fi + fi + + AC_PATH_PROG(GTK_CONFIG, gtk-config, no) + min_gtk_version=ifelse([$1], ,0.99.7,$1) + AC_MSG_CHECKING(for GTK - version >= $min_gtk_version) + no_gtk="" + if test "$GTK_CONFIG" = "no" ; then + no_gtk=yes + else + GTK_CFLAGS=`$GTK_CONFIG $gtk_config_args --cflags` + GTK_LIBS=`$GTK_CONFIG $gtk_config_args --libs` + gtk_config_major_version=`$GTK_CONFIG $gtk_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + gtk_config_minor_version=`$GTK_CONFIG $gtk_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + gtk_config_micro_version=`$GTK_CONFIG $gtk_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + if test "x$enable_gtktest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $GTK_CFLAGS" + LIBS="$GTK_LIBS $LIBS" +dnl +dnl Now check if the installed GTK is sufficiently new. (Also sanity +dnl checks the results of gtk-config to some extent +dnl + rm -f conf.gtktest + AC_TRY_RUN([ +#include <gtk/gtk.h> +#include <stdio.h> +#include <stdlib.h> + +int +main () +{ + int major, minor, micro; + char *tmp_version; + + system ("touch conf.gtktest"); + + /* HP/UX 9 (%@#!) writes to sscanf strings */ + tmp_version = g_strdup("$min_gtk_version"); + if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_gtk_version"); + exit(1); + } + + if ((gtk_major_version != $gtk_config_major_version) || + (gtk_minor_version != $gtk_config_minor_version) || + (gtk_micro_version != $gtk_config_micro_version)) + { + printf("\n*** 'gtk-config --version' returned %d.%d.%d, but GTK+ (%d.%d.%d)\n", + $gtk_config_major_version, $gtk_config_minor_version, $gtk_config_micro_version, + gtk_major_version, gtk_minor_version, gtk_micro_version); + printf ("*** was found! If gtk-config was correct, then it is best\n"); + printf ("*** to remove the old version of GTK+. You may also be able to fix the error\n"); + printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n"); + printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n"); + printf("*** required on your system.\n"); + printf("*** If gtk-config was wrong, set the environment variable GTK_CONFIG\n"); + printf("*** to point to the correct copy of gtk-config, and remove the file config.cache\n"); + printf("*** before re-running configure\n"); + } +#if defined (GTK_MAJOR_VERSION) && defined (GTK_MINOR_VERSION) && defined (GTK_MICRO_VERSION) + else if ((gtk_major_version != GTK_MAJOR_VERSION) || + (gtk_minor_version != GTK_MINOR_VERSION) || + (gtk_micro_version != GTK_MICRO_VERSION)) + { + printf("*** GTK+ header files (version %d.%d.%d) do not match\n", + GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION); + printf("*** library (version %d.%d.%d)\n", + gtk_major_version, gtk_minor_version, gtk_micro_version); + } +#endif /* defined (GTK_MAJOR_VERSION) ... */ + else + { + if ((gtk_major_version > major) || + ((gtk_major_version == major) && (gtk_minor_version > minor)) || + ((gtk_major_version == major) && (gtk_minor_version == minor) && (gtk_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** An old version of GTK+ (%d.%d.%d) was found.\n", + gtk_major_version, gtk_minor_version, gtk_micro_version); + printf("*** You need a version of GTK+ newer than %d.%d.%d. The latest version of\n", + major, minor, micro); + printf("*** GTK+ is always available from ftp://ftp.gtk.org.\n"); + printf("***\n"); + printf("*** If you have already installed a sufficiently new version, this error\n"); + printf("*** probably means that the wrong copy of the gtk-config shell script is\n"); + printf("*** being found. The easiest way to fix this is to remove the old version\n"); + printf("*** of GTK+, but you can also set the GTK_CONFIG environment to point to the\n"); + printf("*** correct copy of gtk-config. (In this case, you will have to\n"); + printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n"); + printf("*** so that the correct libraries are found at run-time))\n"); + } + } + return 1; +} +],, no_gtk=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_gtk" = x ; then + AC_MSG_RESULT(yes) + ifelse([$2], , :, [$2]) + else + AC_MSG_RESULT(no) + if test "$GTK_CONFIG" = "no" ; then + echo "*** The gtk-config script installed by GTK could not be found" + echo "*** If GTK was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the GTK_CONFIG environment variable to the" + echo "*** full path to gtk-config." + else + if test -f conf.gtktest ; then + : + else + echo "*** Could not run GTK test program, checking why..." + CFLAGS="$CFLAGS $GTK_CFLAGS" + LIBS="$LIBS $GTK_LIBS" + AC_TRY_LINK([ +#include <gtk/gtk.h> +#include <stdio.h> +], [ return ((gtk_major_version) || (gtk_minor_version) || (gtk_micro_version)); ], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding GTK or finding the wrong" + echo "*** version of GTK. If it is not finding GTK, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" + echo "***" + echo "*** If you have a RedHat 5.0 system, you should remove the GTK package that" + echo "*** came with the system with the command" + echo "***" + echo "*** rpm --erase --nodeps gtk gtk-devel" ], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means GTK was incorrectly installed" + echo "*** or that you have moved GTK since it was installed. In the latter case, you" + echo "*** may want to edit the gtk-config script: $GTK_CONFIG" ]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + GTK_CFLAGS="" + GTK_LIBS="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(GTK_CFLAGS) + AC_SUBST(GTK_LIBS) + rm -f conf.gtktest +]) + +# Like AC_CONFIG_HEADER, but automatically create stamp file. + +AC_DEFUN(AM_CONFIG_HEADER, +[AC_PREREQ([2.12]) +AC_CONFIG_HEADER([$1]) +dnl When config.status generates a header, we must update the stamp-h file. +dnl This file resides in the same directory as the config header +dnl that is generated. We must strip everything past the first ":", +dnl and everything past the last "/". +AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl +ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>, +<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>, +<<am_indx=1 +for am_file in <<$1>>; do + case " <<$>>CONFIG_HEADERS " in + *" <<$>>am_file "*<<)>> + echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx + ;; + esac + am_indx=`expr "<<$>>am_indx" + 1` +done<<>>dnl>>) +changequote([,]))]) + +# Do all the work for Automake. This macro actually does too much -- +# some checks are only needed if your package does certain things. +# But this isn't really a big deal. + +# serial 1 + +dnl Usage: +dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +AC_DEFUN(AM_INIT_AUTOMAKE, +[AC_REQUIRE([AC_PROG_INSTALL]) +PACKAGE=[$1] +AC_SUBST(PACKAGE) +VERSION=[$2] +AC_SUBST(VERSION) +dnl test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi +ifelse([$3],, +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) +AC_REQUIRE([AM_SANITY_CHECK]) +AC_REQUIRE([AC_ARG_PROGRAM]) +dnl FIXME This is truly gross. +missing_dir=`cd $ac_aux_dir && pwd` +AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) +AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) +AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) +AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) +AC_REQUIRE([AC_PROG_MAKE_SET])]) + +# +# Check to make sure that the build environment is sane. +# + +AC_DEFUN(AM_SANITY_CHECK, +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "[$]*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "[$]*" != "X $srcdir/configure conftestfile" \ + && test "[$]*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "[$]2" = conftestfile + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +rm -f conftest* +AC_MSG_RESULT(yes)]) + +dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) +dnl The program must properly implement --version. +AC_DEFUN(AM_MISSING_PROG, +[AC_MSG_CHECKING(for working $2) +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if ($2 --version) < /dev/null > /dev/null 2>&1; then + $1=$2 + AC_MSG_RESULT(found) +else + $1="$3/missing $2" + AC_MSG_RESULT(missing) +fi +AC_SUBST($1)]) + +#serial 1 +# This test replaces the one in autoconf. +# Currently this macro should have the same name as the autoconf macro +# because gettext's gettext.m4 (distributed in the automake package) +# still uses it. Otherwise, the use in gettext.m4 makes autoheader +# give these diagnostics: +# configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX +# configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX + +undefine([AC_ISC_POSIX]) + +AC_DEFUN([AC_ISC_POSIX], + [ + dnl This test replaces the obsolescent AC_ISC_POSIX kludge. + AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"]) + ] +) + + +# serial 1 + +# @defmac AC_PROG_CC_STDC +# @maindex PROG_CC_STDC +# @ovindex CC +# If the C compiler in not in ANSI C mode by default, try to add an option +# to output variable @code{CC} to make it so. This macro tries various +# options that select ANSI C on some system or another. It considers the +# compiler to be in ANSI C mode if it handles function prototypes correctly. +# +# If you use this macro, you should check after calling it whether the C +# compiler has been set to accept ANSI C; if not, the shell variable +# @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source +# code in ANSI C, you can make an un-ANSIfied copy of it by using the +# program @code{ansi2knr}, which comes with Ghostscript. +# @end defmac + +AC_DEFUN(AM_PROG_CC_STDC, +[AC_REQUIRE([AC_PROG_CC]) +AC_BEFORE([$0], [AC_C_INLINE]) +AC_BEFORE([$0], [AC_C_CONST]) +dnl Force this before AC_PROG_CPP. Some cpp's, eg on HPUX, require +dnl a magic option to avoid problems with ANSI preprocessor commands +dnl like #elif. +dnl FIXME: can't do this because then AC_AIX won't work due to a +dnl circular dependency. +dnl AC_BEFORE([$0], [AC_PROG_CPP]) +AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C) +AC_CACHE_VAL(am_cv_prog_cc_stdc, +[am_cv_prog_cc_stdc=no +ac_save_CC="$CC" +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + AC_TRY_COMPILE( +[#include <stdarg.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +], [ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; +], +[am_cv_prog_cc_stdc="$ac_arg"; break]) +done +CC="$ac_save_CC" +]) +if test -z "$am_cv_prog_cc_stdc"; then + AC_MSG_RESULT([none needed]) +else + AC_MSG_RESULT($am_cv_prog_cc_stdc) +fi +case "x$am_cv_prog_cc_stdc" in + x|xno) ;; + *) CC="$CC $am_cv_prog_cc_stdc" ;; +esac +]) + +# libtool.m4 - Configure libtool for the host system. -*-Shell-script-*- + +# serial 46 AC_PROG_LIBTOOL + +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Prevent multiple expansion +define([AC_PROG_LIBTOOL], []) +]) + +AC_DEFUN([AC_LIBTOOL_SETUP], +[AC_PREREQ(2.13)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +_LT_AC_PROG_ECHO_BACKSLASH +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +enable_win32_dll=yes, enable_win32_dll=no) + +AC_ARG_ENABLE(libtool-lock, + [ --disable-libtool-lock avoid locking (might break parallel builds)]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_SAVE + AC_LANG_C + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_RESTORE]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one + AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain, + [AC_TRY_LINK([], + [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*); + DllMain (0, 0, 0);], + [lt_cv_need_dllmain=no],[lt_cv_need_dllmain=yes])]) + + case $host/$CC in + *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*) + # old mingw systems require "-dll" to link a DLL, while more recent ones + # require "-mdll" + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -mdll" + AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch, + [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])]) + CFLAGS="$SAVE_CFLAGS" ;; + *-*-cygwin* | *-*-pw32*) + # cygwin systems need to pass --dll to the linker, and not link + # crt.o which will require a WinMain@16 definition. + lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;; + esac + ;; + ]) +esac + +_LT_AC_LTCONFIG_HACK + +]) + +# AC_LIBTOOL_HEADER_ASSERT +# ------------------------ +AC_DEFUN([AC_LIBTOOL_HEADER_ASSERT], +[AC_CACHE_CHECK([whether $CC supports assert without backlinking], + [lt_cv_func_assert_works], + [case $host in + *-*-solaris*) + if test "$GCC" = yes && test "$with_gnu_ld" != yes; then + case `$CC --version 2>/dev/null` in + [[12]].*) lt_cv_func_assert_works=no ;; + *) lt_cv_func_assert_works=yes ;; + esac + fi + ;; + esac]) + +if test "x$lt_cv_func_assert_works" = xyes; then + AC_CHECK_HEADERS(assert.h) +fi +])# AC_LIBTOOL_HEADER_ASSERT + +# _LT_AC_CHECK_DLFCN +# -------------------- +AC_DEFUN([_LT_AC_CHECK_DLFCN], +[AC_CHECK_HEADERS(dlfcn.h) +])# _LT_AC_CHECK_DLFCN + +# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +# --------------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_NM]) +AC_REQUIRE([AC_OBJEXT]) +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [dnl + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Transform the above into a raw symbol and a C symbol. +symxfrm='\1 \2\3 \3' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) # Its linker distinguishes data from code symbols + lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +solaris* | sysv5*) + symcode='[[BDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $host_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then + symcode='[[ABCDGISTW]]' +fi + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Write the raw and C identifiers. +lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + rm -f conftest* + cat > conftest.$ac_ext <<EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if egrep ' nm_test_var$' "$nlist" >/dev/null; then + if egrep ' nm_test_func$' "$nlist" >/dev/null; then + cat <<EOF > conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext' + + cat <<EOF >> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[[]] = +{ +EOF + sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr) \&\2},/" < "$nlist" >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$no_builtin_flag" + if AC_TRY_EVAL(ac_link) && test -s conftest; then + pipe_works=yes + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AC_FD_CC + fi + else + echo "cannot find nm_test_var in $nlist" >&AC_FD_CC + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AC_FD_CC + fi + else + echo "$progname: failed program was:" >&AC_FD_CC + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +global_symbol_pipe="$lt_cv_sys_global_symbol_pipe" +if test -z "$lt_cv_sys_global_symbol_pipe"; then + global_symbol_to_cdecl= + global_symbol_to_c_name_address= +else + global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl" + global_symbol_to_c_name_address="$lt_cv_global_symbol_to_c_name_address" +fi +if test -z "$global_symbol_pipe$global_symbol_to_cdec$global_symbol_to_c_name_address"; +then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi +]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE + +# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR +# --------------------------------- +AC_DEFUN([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR], +[# Find the correct PATH separator. Usually this is `:', but +# DJGPP uses `;' like DOS. +if test "X${PATH_SEPARATOR+set}" != Xset; then + UNAME=${UNAME-`uname 2>/dev/null`} + case X$UNAME in + *-DOS) lt_cv_sys_path_separator=';' ;; + *) lt_cv_sys_path_separator=':' ;; + esac + PATH_SEPARATOR=$lt_cv_sys_path_separator +fi +])# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR + +# _LT_AC_PROG_ECHO_BACKSLASH +# -------------------------- +# Add some code to the start of the generated configure script which +# will find an echo command which doesn't interpret backslashes. +AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], +[ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +echo=${ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat <<EOF +$* +EOF + exit 0 +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi + +if test -z "$ECHO"; then +if test "X${echo_test_string+set}" != Xset; then +# find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string="`eval $cmd`") 2>/dev/null && + echo_test_string="`eval $cmd`" && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + IFS="${IFS= }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(ECHO) +AC_DIVERT_POP +])# _LT_AC_PROG_ECHO_BACKSLASH + +# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ------------------------------------------------------------------ +AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], +[if test "$cross_compiling" = yes; then : + [$4] +else + AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<EOF +[#line __oline__ "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +}] +EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_unknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_AC_TRY_DLOPEN_SELF + +# AC_LIBTOOL_DLOPEN_SELF +# ------------------- +AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], +[if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + cygwin* | mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + LDFLAGS="$LDFLAGS $link_static_flag" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +])# AC_LIBTOOL_DLOPEN_SELF + +AC_DEFUN([_LT_AC_LTCONFIG_HACK], +[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])dnl +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +sed_quote_subst='s/\([[\\"\\`$\\\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([[\\"\\`\\\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" +need_locks="$enable_libtool_lock" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +if test x"$host" != x"$build"; then + ac_tool_prefix=${host_alias}- +else + ac_tool_prefix= +fi + +# Transform linux* to *-*-linux-gnu*, to support old configure scripts. +case $host_os in +linux-gnu*) ;; +linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` +esac + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" + ;; + *) + old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +# Allow CC to be a program name with arguments. +set dummy $CC +compiler="[$]2" + +AC_MSG_CHECKING([for objdir]) +rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + objdir=_libs +fi +rmdir .libs 2>/dev/null +AC_MSG_RESULT($objdir) + + +AC_ARG_WITH(pic, +[ --with-pic try to use only PIC/non-PIC objects [default=use both]], +pic_mode="$withval", pic_mode=default) +test -z "$pic_mode" && pic_mode=default + +# We assume here that the value for lt_cv_prog_cc_pic will not be cached +# in isolation, and that seeing it set (from the cache) indicates that +# the associated values are set (in the cache) correctly too. +AC_MSG_CHECKING([for $compiler option to produce PIC]) +AC_CACHE_VAL(lt_cv_prog_cc_pic, +[ lt_cv_prog_cc_pic= + lt_cv_prog_cc_shlib= + lt_cv_prog_cc_wl= + lt_cv_prog_cc_static= + lt_cv_prog_cc_no_builtin= + lt_cv_prog_cc_can_build_shared=$can_build_shared + + if test "$GCC" = yes; then + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-static' + + case $host_os in + aix*) + # Below there is a dirty hack to force normal static linking with -ldl + # The problem is because libdl dynamically linked with both libc and + # libC (AIX C++ library), which obviously doesn't included in libraries + # list by gcc. This cause undefined symbols with -static flags. + # This hack allows C programs to be linked with "-static -ldl", but + # not sure about C++ programs. + lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC" + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_cv_prog_cc_pic='-fno-common' + ;; + cygwin* | mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_cv_prog_cc_pic=-Kconform_pic + fi + ;; + *) + lt_cv_prog_cc_pic='-fPIC' + ;; + esac + else + # PORTME Check for PIC flags for the system compiler. + case $host_os in + aix3* | aix4* | aix5*) + lt_cv_prog_cc_wl='-Wl,' + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_cv_prog_cc_static='-Bstatic' + else + lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + hpux9* | hpux10* | hpux11*) + # Is there a better lt_cv_prog_cc_static that works with the bundled CC? + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive" + lt_cv_prog_cc_pic='+Z' + ;; + + irix5* | irix6* | nonstopux*) + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-non_shared' + # PIC (with -KPIC) is the default. + ;; + + cygwin* | mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + + newsos6) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + ;; + + osf3* | osf4* | osf5*) + # All OSF/1 code is PIC. + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-non_shared' + ;; + + sco3.2v5*) + lt_cv_prog_cc_pic='-Kpic' + lt_cv_prog_cc_static='-dn' + lt_cv_prog_cc_shlib='-belf' + ;; + + solaris*) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Wl,' + ;; + + sunos4*) + lt_cv_prog_cc_pic='-PIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Qoption ld ' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + if test "x$host_vendor" = xsni; then + lt_cv_prog_cc_wl='-LD' + else + lt_cv_prog_cc_wl='-Wl,' + fi + ;; + + uts4*) + lt_cv_prog_cc_pic='-pic' + lt_cv_prog_cc_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_cv_prog_cc_pic='-Kconform_pic' + lt_cv_prog_cc_static='-Bstatic' + fi + ;; + + *) + lt_cv_prog_cc_can_build_shared=no + ;; + esac + fi +]) +if test -z "$lt_cv_prog_cc_pic"; then + AC_MSG_RESULT([none]) +else + AC_MSG_RESULT([$lt_cv_prog_cc_pic]) + + # Check to make sure the pic_flag actually works. + AC_MSG_CHECKING([if $compiler PIC flag $lt_cv_prog_cc_pic works]) + AC_CACHE_VAL(lt_cv_prog_cc_pic_works, [dnl + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC" + AC_TRY_COMPILE([], [], [dnl + case $host_os in + hpux9* | hpux10* | hpux11*) + # On HP-UX, both CC and GCC only warn that PIC is supported... then + # they create non-PIC objects. So, if there were any warnings, we + # assume that PIC is not supported. + if test -s conftest.err; then + lt_cv_prog_cc_pic_works=no + else + lt_cv_prog_cc_pic_works=yes + fi + ;; + *) + lt_cv_prog_cc_pic_works=yes + ;; + esac + ], [dnl + lt_cv_prog_cc_pic_works=no + ]) + CFLAGS="$save_CFLAGS" + ]) + + if test "X$lt_cv_prog_cc_pic_works" = Xno; then + lt_cv_prog_cc_pic= + lt_cv_prog_cc_can_build_shared=no + else + lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic" + fi + + AC_MSG_RESULT([$lt_cv_prog_cc_pic_works]) +fi + +# Check for any special shared library compilation flags. +if test -n "$lt_cv_prog_cc_shlib"; then + AC_MSG_WARN([\`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries]) + if echo "$old_CC $old_CFLAGS " | egrep -e "[[ ]]$lt_cv_prog_cc_shlib[[ ]]" >/dev/null; then : + else + AC_MSG_WARN([add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure]) + lt_cv_prog_cc_can_build_shared=no + fi +fi + +AC_MSG_CHECKING([if $compiler static flag $lt_cv_prog_cc_static works]) +AC_CACHE_VAL([lt_cv_prog_cc_static_works], [dnl + lt_cv_prog_cc_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static" + AC_TRY_LINK([], [], [lt_cv_prog_cc_static_works=yes]) + LDFLAGS="$save_LDFLAGS" +]) + +# Belt *and* braces to stop my trousers falling down: +test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static= +AC_MSG_RESULT([$lt_cv_prog_cc_static_works]) + +pic_flag="$lt_cv_prog_cc_pic" +special_shlib_compile_flags="$lt_cv_prog_cc_shlib" +wl="$lt_cv_prog_cc_wl" +link_static_flag="$lt_cv_prog_cc_static" +no_builtin_flag="$lt_cv_prog_cc_no_builtin" +can_build_shared="$lt_cv_prog_cc_can_build_shared" + + +# Check to see if options -o and -c are simultaneously supported by compiler +AC_MSG_CHECKING([if $compiler supports -c -o file.$ac_objext]) +AC_CACHE_VAL([lt_cv_compiler_c_o], [ +$rm -r conftest 2>/dev/null +mkdir conftest +cd conftest +echo "int some_variable = 0;" > conftest.$ac_ext +mkdir out +# According to Tom Tromey, Ian Lance Taylor reported there are C compilers +# that will create temporary files in the current directory regardless of +# the output directory. Thus, making CWD read-only will cause this test +# to fail, enabling locking or at least warning the user not to do parallel +# builds. +chmod -w . +save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -o out/conftest2.$ac_objext" +compiler_c_o=no +if { (eval echo configure:__oline__: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s out/conftest.err; then + lt_cv_compiler_c_o=no + else + lt_cv_compiler_c_o=yes + fi +else + # Append any errors to the config.log. + cat out/conftest.err 1>&AC_FD_CC + lt_cv_compiler_c_o=no +fi +CFLAGS="$save_CFLAGS" +chmod u+w . +$rm conftest* out/* +rmdir out +cd .. +rmdir conftest +$rm -r conftest 2>/dev/null +]) +compiler_c_o=$lt_cv_compiler_c_o +AC_MSG_RESULT([$compiler_c_o]) + +if test x"$compiler_c_o" = x"yes"; then + # Check to see if we can write to a .lo + AC_MSG_CHECKING([if $compiler supports -c -o file.lo]) + AC_CACHE_VAL([lt_cv_compiler_o_lo], [ + lt_cv_compiler_o_lo=no + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -c -o conftest.lo" + save_objext="$ac_objext" + ac_objext=lo + AC_TRY_COMPILE([], [int some_variable = 0;], [dnl + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + lt_cv_compiler_o_lo=no + else + lt_cv_compiler_o_lo=yes + fi + ]) + ac_objext="$save_objext" + CFLAGS="$save_CFLAGS" + ]) + compiler_o_lo=$lt_cv_compiler_o_lo + AC_MSG_RESULT([$compiler_o_lo]) +else + compiler_o_lo=no +fi + +# Check to see if we can do hard links to lock some files if needed +hard_links="nottested" +if test "$compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([\`$CC' does not support \`-c -o', so \`make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi + +if test "$GCC" = yes; then + # Check to see if options -fno-rtti -fno-exceptions are supported by compiler + AC_MSG_CHECKING([if $compiler supports -fno-rtti -fno-exceptions]) + echo "int some_variable = 0;" > conftest.$ac_ext + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext" + compiler_rtti_exceptions=no + AC_TRY_COMPILE([], [int some_variable = 0;], [dnl + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + compiler_rtti_exceptions=no + else + compiler_rtti_exceptions=yes + fi + ]) + CFLAGS="$save_CFLAGS" + AC_MSG_RESULT([$compiler_rtti_exceptions]) + + if test "$compiler_rtti_exceptions" = "yes"; then + no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' + else + no_builtin_flag=' -fno-builtin' + fi +fi + +# See if the linker supports building shared libraries. +AC_MSG_CHECKING([whether the linker ($LD) supports shared libraries]) + +allow_undefined_flag= +no_undefined_flag= +need_lib_prefix=unknown +need_version=unknown +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +archive_cmds= +archive_expsym_cmds= +old_archive_from_new_cmds= +old_archive_from_expsyms_cmds= +export_dynamic_flag_spec= +whole_archive_flag_spec= +thread_safe_flag_spec= +hardcode_into_libs=no +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no +hardcode_shlibpath_var=unsupported +runpath_var= +link_all_deplibs=unknown +always_export_symbols=no +export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' +# include_expsyms should be a list of space-separated symbols to be *always* +# included in the symbol list +include_expsyms= +# exclude_expsyms can be an egrep regular expression of symbols to exclude +# it will be wrapped by ` (' and `)$', so one must not match beginning or +# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', +# as well as any symbol that contains `d'. +exclude_expsyms="_GLOBAL_OFFSET_TABLE_" +# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out +# platforms (ab)use it in PIC code, but their linkers get confused if +# the symbol is explicitly referenced. Since portable code cannot +# rely on this symbol name, it's probably fine to never include it in +# preloaded symbol tables. +extract_expsyms_cmds= + +case $host_os in +cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; +openbsd*) + with_gnu_ld=no + ;; +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX, the GNU linker is very broken + # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available. + ld_shlibs=no + cat <<EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + + # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can use + # them. + ld_shlibs=no + ;; + + beos*) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=yes + + extract_expsyms_cmds='test -f $output_objdir/impgen.c || \ + sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~ + test -f $output_objdir/impgen.exe || (cd $output_objdir && \ + if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \ + else $CC -o impgen impgen.c ; fi)~ + $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def' + + old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib' + + # cygwin and mingw dlls have different entry points and sets of symbols + # to exclude. + # FIXME: what about values for MSVC? + dll_entry=__cygwin_dll_entry@12 + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~ + case $host_os in + mingw*) + # mingw values + dll_entry=_DllMainCRTStartup@12 + dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~ + ;; + esac + + # mingw and cygwin differ, and it's simplest to just exclude the union + # of the two symbol sets. + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12 + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one (in ltdll.c) + if test "x$lt_cv_need_dllmain" = "xyes"; then + ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext " + ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $''0 > $output_objdir/$soname-ltdll.c~ + test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~' + else + ltdll_obj= + ltdll_cmds= + fi + + # Extract the symbol export list from an `--export-all' def file, + # then regenerate the def file from the symbol export list, so that + # the compiled dll only exports the symbol export list. + # Be careful not to strip the DATA tag left be newer dlltools. + export_symbols_cmds="$ltdll_cmds"' + $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~ + sed -e "1,/EXPORTS/d" -e "s/ @ [[0-9]]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols' + + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is. + # If DATA tags from a recent dlltool are present, honour them! + archive_expsym_cmds='if test "x`head -1 $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname-def; + else + echo EXPORTS > $output_objdir/$soname-def; + _lt_hint=1; + cat $export_symbols | while read symbol; do + set dummy \$symbol; + case \[$]# in + 2) echo " \[$]2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;; + *) echo " \[$]2 @ \$_lt_hint \[$]3 ; " >> $output_objdir/$soname-def;; + esac; + _lt_hint=`expr 1 + \$_lt_hint`; + done; + fi~ + '"$ltdll_cmds"' + $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~ + $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~ + $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags' + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris* | sysv5*) + if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = yes; then + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + case $host_os in + cygwin* | mingw* | pw32*) + # dlltool doesn't understand --whole-archive et. al. + whole_archive_flag_spec= + ;; + *) + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + ;; + esac + fi +else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + hardcode_direct=yes + archive_cmds='' + hardcode_libdir_separator=':' + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + esac + + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + shared_flag='${wl}-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall can do strange things, so it is better to + # generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib' + archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib' + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='${wl}-berok' + # This is a bit strange, but is similar to how AIX traditionally builds + # it's shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + ;; + + darwin* | rhapsody*) + case "$host_os" in + rhapsody* | darwin1.[[012]]) + allow_undefined_flag='-undefined suppress' + ;; + *) # Darwin 1.3 on + allow_undefined_flag='-flat_namespace -undefined suppress' + ;; + esac + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. Also zsh mangles + # `"' quotes if we put them in here... so don't! + archive_cmds='$nonopt $(test .$module = .yes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs$linker_flags -install_name $rpath/$soname $verstring' + # We need to add '_' to the symbols in $export_symbols first + #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols' + hardcode_direct=yes + hardcode_shlibpath_var=no + whole_archive_flag_spec='-all_load $convenience' + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9* | hpux10* | hpux11*) + case $host_os in + hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;; + *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;; + esac + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_minus_L=yes # Not in the search PATH, but as the default + # location of the library. + export_dynamic_flag_spec='${wl}-E' + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + openbsd*) + hardcode_direct=yes + hardcode_shlibpath_var=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case "$host_os" in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + + #Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + + sco3.2v5*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + export_dynamic_flag_spec='${wl}-Bexport' + ;; + + solaris*) + # gcc --version < 3.0 without binutils cannot create self contained + # shared libraries reliably, requiring libgcc.a to resolve some of + # the object symbols generated in some cases. Libraries that use + # assert need libgcc.a to resolve __eprintf, for example. Linking + # a copy of libgcc.a into every shared library to guarantee resolving + # such symbols causes other problems: According to Tim Van Holder + # <tim.van.holder@pandora.be>, C++ libraries end up with a separate + # (to the application) exception stack for one thing. + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + case `$CC --version 2>/dev/null` in + [[12]].*) + cat <<EOF 1>&2 + +*** Warning: Releases of GCC earlier than version 3.0 cannot reliably +*** create self contained shared libraries on Solaris systems, without +*** introducing a dependency on libgcc.a. Therefore, libtool is disabling +*** -no-undefined support, which will at least allow you to build shared +*** libraries. However, you may find that when you link such libraries +*** into an application without using GCC, you have to manually add +*** \`gcc --print-libgcc-file-name\` to the link command. We urge you to +*** upgrade to a newer version of GCC. Another option is to rebuild your +*** current GCC to use the GNU linker from GNU binutils 2.9.1 or newer. + +EOF + no_undefined_flag= + ;; + esac + fi + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + if test "x$host_vendor" = xsno; then + archive_cmds='$LD -G -Bsymbolic -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + else + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + fi + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv5*) + no_undefined_flag=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + hardcode_libdir_flag_spec= + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4.2uw2*) + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=no + hardcode_shlibpath_var=no + hardcode_runpath_var=yes + runpath_var=LD_RUN_PATH + ;; + + sysv5uw7* | unixware7*) + no_undefined_flag='${wl}-z ${wl}text' + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac +fi +AC_MSG_RESULT([$ld_shlibs]) +test "$ld_shlibs" = no && can_build_shared=no + +# Check hardcoding attributes. +AC_MSG_CHECKING([how to hardcode library paths into programs]) +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || \ + test -n "$runpath_var"; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$hardcode_shlibpath_var" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +AC_MSG_RESULT([$hardcode_action]) + +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +reload_cmds='$LD$reload_flag -o $output$reload_objs' +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +# PORTME Fill in your ld.so characteristics +AC_MSG_CHECKING([dynamic linker characteristics]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}.so$major' + ;; + +aix4* | aix5*) + version_type=linux + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can + # not hardcode correct soname into executable. Probably we can + # add versioning support to collect2, so additional links can + # be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}.so$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}.so' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi4*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + export_dynamic_flag_spec=-rdynamic + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + need_version=no + need_lib_prefix=no + case $GCC,$host_os in + yes,cygwin*) + library_names_spec='$libname.dll.a' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll' + postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog .libs/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + ;; + yes,mingw*) + library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g"` + ;; + yes,pw32*) + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' + ;; + *) + library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. + library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)' + soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd*) + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + *) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + dynamic_linker="$host_os dld.sl" + version_type=sunos + need_lib_prefix=no + need_version=no + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl' + soname_spec='${libname}${release}.sl$major' + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) version_type=irix ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux-gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so' + soname_spec='${libname}${release}.so$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case "$host_os" in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + ;; + +os2*) + libname_spec='$name' + need_lib_prefix=no + library_names_spec='$libname.dll $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_version=no + need_lib_prefix=no + soname_spec='${libname}${release}.so' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so' + soname_spec='$libname.so.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +# Report the final consequences. +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) + +AC_MSG_CHECKING([whether to build shared libraries]) +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case "$host_os" in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +AC_MSG_RESULT([$enable_shared]) + +AC_MSG_CHECKING([whether to build static libraries]) +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +AC_MSG_RESULT([$enable_static]) + +if test "$hardcode_action" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +AC_LIBTOOL_DLOPEN_SELF + +if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + AC_CACHE_VAL([lt_cv_archive_cmds_need_lc], + [$rm conftest* + echo 'static int dummy;' > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile); then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_cv_prog_cc_wl + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if AC_TRY_EVAL(archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi]) + AC_MSG_RESULT([$lt_cv_archive_cmds_need_lc]) + ;; + esac +fi +need_lc=${lt_cv_archive_cmds_need_lc-yes} + +# The second clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + : +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + test -f Makefile && make "$ltmain" +fi + +if test -f "$ltmain"; then + trap "$rm \"${ofile}T\"; exit 1" 1 2 15 + $rm -f "${ofile}T" + + echo creating $ofile + + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS \ + AR AR_FLAGS CC LD LN_S NM SHELL \ + reload_flag reload_cmds wl \ + pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \ + thread_safe_flag_spec whole_archive_flag_spec libname_spec \ + library_names_spec soname_spec \ + RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \ + old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \ + postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \ + old_striplib striplib file_magic_cmd export_symbols_cmds \ + deplibs_check_method allow_undefined_flag no_undefined_flag \ + finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \ + global_symbol_to_c_name_address \ + hardcode_libdir_flag_spec hardcode_libdir_separator \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do + + case $var in + reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + export_symbols_cmds | archive_cmds | archive_expsym_cmds | \ + extract_expsyms_cmds | old_archive_from_expsyms_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + cat <<__EOF__ > "${ofile}T" +#! $SHELL + +# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996-2000 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="sed -e s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi + +# ### BEGIN LIBTOOL CONFIG + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$need_lc + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# The default C compiler. +CC=$lt_CC + +# Is the compiler the GNU C compiler? +with_gcc=$GCC + +# The linker used to build libraries. +LD=$lt_LD + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_wl + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_pic_flag +pic_mode=$pic_mode + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_compiler_c_o + +# Can we write directly to a .lo ? +compiler_o_lo=$lt_compiler_o_lo + +# Must we lock files when doing compilation ? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_link_static_flag + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_no_builtin_flag + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# ### END LIBTOOL CONFIG + +__EOF__ + + case $host_os in + aix3*) + cat <<\EOF >> "${ofile}T" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + case $host_os in + cygwin* | mingw* | pw32* | os2*) + cat <<'EOF' >> "${ofile}T" + # This is a source program that is used to create dlls on Windows + # Don't remove nor modify the starting and closing comments +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include <windows.h> +# #undef WIN32_LEAN_AND_MEAN +# #include <stdio.h> +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include <cygwin/cygwin_dll.h> +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ + # This is a source program that is used to create import libraries + # on Windows for dlls which lack them. Don't remove nor modify the + # starting and closing comments +# /* impgen.c starts here */ +# /* Copyright (C) 1999-2000 Free Software Foundation, Inc. +# +# This file is part of GNU libtool. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# */ +# +# #include <stdio.h> /* for printf() */ +# #include <unistd.h> /* for open(), lseek(), read() */ +# #include <fcntl.h> /* for O_RDONLY, O_BINARY */ +# #include <string.h> /* for strdup() */ +# +# /* O_BINARY isn't required (or even defined sometimes) under Unix */ +# #ifndef O_BINARY +# #define O_BINARY 0 +# #endif +# +# static unsigned int +# pe_get16 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[2]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 2); +# return b[0] + (b[1]<<8); +# } +# +# static unsigned int +# pe_get32 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[4]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 4); +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# static unsigned int +# pe_as32 (ptr) +# void *ptr; +# { +# unsigned char *b = ptr; +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# int +# main (argc, argv) +# int argc; +# char *argv[]; +# { +# int dll; +# unsigned long pe_header_offset, opthdr_ofs, num_entries, i; +# unsigned long export_rva, export_size, nsections, secptr, expptr; +# unsigned long name_rvas, nexp; +# unsigned char *expdata, *erva; +# char *filename, *dll_name; +# +# filename = argv[1]; +# +# dll = open(filename, O_RDONLY|O_BINARY); +# if (dll < 1) +# return 1; +# +# dll_name = filename; +# +# for (i=0; filename[i]; i++) +# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':') +# dll_name = filename + i +1; +# +# pe_header_offset = pe_get32 (dll, 0x3c); +# opthdr_ofs = pe_header_offset + 4 + 20; +# num_entries = pe_get32 (dll, opthdr_ofs + 92); +# +# if (num_entries < 1) /* no exports */ +# return 1; +# +# export_rva = pe_get32 (dll, opthdr_ofs + 96); +# export_size = pe_get32 (dll, opthdr_ofs + 100); +# nsections = pe_get16 (dll, pe_header_offset + 4 +2); +# secptr = (pe_header_offset + 4 + 20 + +# pe_get16 (dll, pe_header_offset + 4 + 16)); +# +# expptr = 0; +# for (i = 0; i < nsections; i++) +# { +# char sname[8]; +# unsigned long secptr1 = secptr + 40 * i; +# unsigned long vaddr = pe_get32 (dll, secptr1 + 12); +# unsigned long vsize = pe_get32 (dll, secptr1 + 16); +# unsigned long fptr = pe_get32 (dll, secptr1 + 20); +# lseek(dll, secptr1, SEEK_SET); +# read(dll, sname, 8); +# if (vaddr <= export_rva && vaddr+vsize > export_rva) +# { +# expptr = fptr + (export_rva - vaddr); +# if (export_rva + export_size > vaddr + vsize) +# export_size = vsize - (export_rva - vaddr); +# break; +# } +# } +# +# expdata = (unsigned char*)malloc(export_size); +# lseek (dll, expptr, SEEK_SET); +# read (dll, expdata, export_size); +# erva = expdata - export_rva; +# +# nexp = pe_as32 (expdata+24); +# name_rvas = pe_as32 (expdata+32); +# +# printf ("EXPORTS\n"); +# for (i = 0; i<nexp; i++) +# { +# unsigned long name_rva = pe_as32 (erva+name_rvas+i*4); +# printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i); +# } +# +# return 0; +# } +# /* impgen.c ends here */ + +EOF + ;; + esac + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "${ofile}T" || (rm -f "${ofile}T"; exit 1) + + mv -f "${ofile}T" "$ofile" || \ + (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T") + chmod +x "$ofile" +fi + +])# _LT_AC_LTCONFIG_HACK + +# AC_LIBTOOL_DLOPEN - enable checks for dlopen support +AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])]) + +# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's +AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])]) + +# AC_ENABLE_SHARED - implement the --enable-shared flag +# Usage: AC_ENABLE_SHARED[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_SHARED], +[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(shared, +changequote(<<, >>)dnl +<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl +]) + +# AC_DISABLE_SHARED - set the default shared flag to --disable-shared +AC_DEFUN([AC_DISABLE_SHARED], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no)]) + +# AC_ENABLE_STATIC - implement the --enable-static flag +# Usage: AC_ENABLE_STATIC[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_STATIC], +[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(static, +changequote(<<, >>)dnl +<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_static=AC_ENABLE_STATIC_DEFAULT)dnl +]) + +# AC_DISABLE_STATIC - set the default static flag to --disable-static +AC_DEFUN([AC_DISABLE_STATIC], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no)]) + + +# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag +# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_FAST_INSTALL], +[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(fast-install, +changequote(<<, >>)dnl +<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl +]) + +# AC_DISABLE_FAST_INSTALL - set the default to --disable-fast-install +AC_DEFUN([AC_DISABLE_FAST_INSTALL], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no)]) + +# AC_LIBTOOL_PICMODE - implement the --with-pic flag +# Usage: AC_LIBTOOL_PICMODE[(MODE)] +# Where MODE is either `yes' or `no'. If omitted, it defaults to +# `both'. +AC_DEFUN([AC_LIBTOOL_PICMODE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default)]) + + +# AC_PATH_TOOL_PREFIX - find a file program which can recognise shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <<EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +]) + + +# AC_PATH_MAGIC - find a file program which can recognise a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])dnl +AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin:$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin:$PATH) + else + MAGIC_CMD=: + fi +fi +]) + + +# AC_PROG_LD - find the path to the GNU or non-GNU linker +AC_DEFUN([AC_PROG_LD], +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | [[A-Za-z]]:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$lt_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_PROG_LD_GNU +]) + +# AC_PROG_LD_GNU - +AC_DEFUN([AC_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then + lt_cv_prog_gnu_ld=yes +else + lt_cv_prog_gnu_ld=no +fi]) +with_gnu_ld=$lt_cv_prog_gnu_ld +]) + +# AC_PROG_LD_RELOAD_FLAG - find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +AC_DEFUN([AC_PROG_LD_RELOAD_FLAG], +[AC_CACHE_CHECK([for $LD option to reload object files], lt_cv_ld_reload_flag, +[lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +test -n "$reload_flag" && reload_flag=" $reload_flag" +]) + +# AC_DEPLIBS_CHECK_METHOD - how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +AC_DEFUN([AC_DEPLIBS_CHECK_METHOD], +[AC_CACHE_CHECK([how to recognise dependant libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given egrep regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix4* | aix5*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi4*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin* | mingw* | pw32*) + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' + lt_cv_file_magic_cmd='/usr/bin/file -L' + case "$host_os" in + rhapsody* | darwin1.[[012]]) + lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1` + ;; + *) # Darwin 1.3 on + lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' + ;; + esac + ;; + +freebsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20*|hpux11*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + irix5* | nonstopux*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[[1234]] dynamic lib MIPS - version 1" + ;; + esac + lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux-gnu*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so\.[[0-9]]+\.[[0-9]]+$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +openbsd*) + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB shared object' + else + lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library' + fi + ;; + +osf3* | osf4* | osf5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' + lt_cv_file_magic_test_file=/shlib/libc.so + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=/lib/libc.so + ;; + +sysv5uw[[78]]* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + esac + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +]) + + +# AC_PROG_NM - find the path to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl +AC_MSG_CHECKING([for BSD-compatible nm]) +AC_CACHE_VAL(lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/${ac_tool_prefix}nm + if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then + lt_cv_path_NM="$tmp_nm -B" + break + elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + lt_cv_path_NM="$tmp_nm -p" + break + else + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +AC_MSG_RESULT([$NM]) +]) + +# AC_CHECK_LIBM - check for math library +AC_DEFUN([AC_CHECK_LIBM], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32*) + # These system don't have libm + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, main, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, main, LIBM="-lm") + ;; +esac +]) + +# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl convenience library and LTDLINCL to the include flags for +# the libltdl header and adds --enable-ltdl-convenience to the +# configure arguments. Note that LIBLTDL and LTDLINCL are not +# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not +# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed +# with '${top_builddir}/' and LTDLINCL will be prefixed with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +AC_DEFUN([AC_LIBLTDL_CONVENIENCE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +]) + +# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl installable library and LTDLINCL to the include flags for +# the libltdl header and adds --enable-ltdl-install to the configure +# arguments. Note that LIBLTDL and LTDLINCL are not AC_SUBSTed, nor is +# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed +# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will +# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed +# with '${top_srcdir}/' (note the single quotes!). If your package is +# not flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN([AC_LIBLTDL_INSTALLABLE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, main, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + LTDLINCL= + fi + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +]) + +# old names +AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) + +# This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL]) + +# Add --enable-maintainer-mode option to configure. +# From Jim Meyering + +# serial 1 + +AC_DEFUN(AM_MAINTAINER_MODE, +[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode is disabled by default + AC_ARG_ENABLE(maintainer-mode, +[ --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + USE_MAINTAINER_MODE=$enableval, + USE_MAINTAINER_MODE=no) + AC_MSG_RESULT($USE_MAINTAINER_MODE) + AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST(MAINT)dnl +] +) + +# Define a conditional. + +AC_DEFUN(AM_CONDITIONAL, +[AC_SUBST($1_TRUE) +AC_SUBST($1_FALSE) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi]) + + +# serial 1 + +AC_DEFUN(AM_WITH_DMALLOC, +[AC_MSG_CHECKING(if malloc debugging is wanted) +AC_ARG_WITH(dmalloc, +[ --with-dmalloc use dmalloc, as in + ftp://ftp.letters.com/src/dmalloc/dmalloc.tar.gz], +[if test "$withval" = yes; then + AC_MSG_RESULT(yes) + AC_DEFINE(WITH_DMALLOC,1, + [Define if using the dmalloc debugging malloc package]) + LIBS="$LIBS -ldmalloc" + LDFLAGS="$LDFLAGS -g" +else + AC_MSG_RESULT(no) +fi], [AC_MSG_RESULT(no)]) +]) + diff --git a/configure b/configure new file mode 100755 index 0000000..b17f4a0 --- /dev/null +++ b/configure @@ -0,0 +1,4975 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.53. +# +# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + + +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# NLS nuisances. +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + +(set +x; test -n "`(LANG=C; export LANG) 2>&1`") && + { $as_unset LANG || test "${LANG+set}" != set; } || + { LANG=C; export LANG; } +(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") && + { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } || + { LC_ALL=C; export LC_ALL; } +(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") && + { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } || + { LC_TIME=C; export LC_TIME; } +(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") && + { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } || + { LC_CTYPE=C; export LC_CTYPE; } +(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") && + { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } || + { LANGUAGE=C; export LANGUAGE; } +(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") && + { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } || + { LC_COLLATE=C; export LC_COLLATE; } +(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") && + { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } || + { LC_NUMERIC=C; export LC_NUMERIC; } +(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") && + { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } || + { LC_MESSAGES=C; export LC_MESSAGES; } + + +# Name of the executable. +as_me=`(basename "$0") 2>/dev/null || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conftest.sh + echo "exit 0" >>conftest.sh + chmod +x conftest.sh + if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conftest.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; } + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +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' + +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 + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # 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_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) 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 | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -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 | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# 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_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-dmalloc use dmalloc, as in + ftp://ftp.letters.com/src/dmalloc/dmalloc.tar.gz + --with-imlib2-prefix=PFX Prefix where imlib2 is installed (optional) + --with-imlib2-exec-prefix=PFX Exec prefix where imlib2 is installed (optional) + --with-aalib-prefix=PFX Prefix where aalib is installed (optional) + --with-aalib-exec-prefix=PFX Exec prefix where aalib is installed (optional) + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have + headers in a nonstandard directory <include dir> + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 +Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.53. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell meta-characters. +ac_configure_args= +ac_sep= +for ac_arg +do + case $ac_arg in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n ) continue ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + ac_sep=" " ;; + esac + # Get rid of the leading space. +done + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core core.* *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -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 "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + +PDP_PIDIP_VERSION=0.12.4 +PD_DIR=/usr/local/pd +PDP_DIR=/usr/local/pd/pdp +FFMPEG_SOURCE_DIR=/SOURCES/ffmpeg + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$as_dir/$ac_word" ${1+"$@"} + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH" >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH" >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5 + (eval $ac_compiler --version </dev/null >&5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5 + (eval $ac_compiler -v </dev/null >&5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5 + (eval $ac_compiler -V </dev/null >&5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output" >&5 +echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +for ac_file in `ls a_out.exe a.exe conftest.exe 2>/dev/null; + ls a.out conftest 2>/dev/null; + ls a.* conftest.* 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb | *.xSYM ) ;; + a.out ) # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool --akim. + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables" >&5 +echo "$as_me: error: C compiler cannot create executables" >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in `(ls conftest.exe; ls conftest; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link" >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link" >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile" >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile" >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_compiler_gnu=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_prog_cc_g=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + ''\ + '#include <stdlib.h>' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <stdlib.h> +$ac_declaration +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +continue +fi +rm -f conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_declaration +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + echo "$as_me:$LINENO: checking for strerror in -lcposix" >&5 +echo $ECHO_N "checking for strerror in -lcposix... $ECHO_C" >&6 +if test "${ac_cv_lib_cposix_strerror+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcposix $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char strerror (); +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +strerror (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_cposix_strerror=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_cposix_strerror=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_cposix_strerror" >&5 +echo "${ECHO_T}$ac_cv_lib_cposix_strerror" >&6 +if test $ac_cv_lib_cposix_strerror = yes; then + LIBS="$LIBS -lcposix" +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$as_dir/$ac_word" ${1+"$@"} + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH" >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH" >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5 + (eval $ac_compiler --version </dev/null >&5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5 + (eval $ac_compiler -v </dev/null >&5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5 + (eval $ac_compiler -V </dev/null >&5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_compiler_gnu=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_prog_cc_g=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + ''\ + '#include <stdlib.h>' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <stdlib.h> +$ac_declaration +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +continue +fi +rm -f conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_declaration +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +echo "$as_me:$LINENO: checking for ${CC-cc} option to accept ANSI C" >&5 +echo $ECHO_N "checking for ${CC-cc} option to accept ANSI C... $ECHO_C" >&6 +if test "${am_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + am_cv_prog_cc_stdc=no +ac_save_CC="$CC" +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <stdarg.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ + +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + am_cv_prog_cc_stdc="$ac_arg"; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +CC="$ac_save_CC" + +fi + +if test -z "$am_cv_prog_cc_stdc"; then + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 +else + echo "$as_me:$LINENO: result: $am_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$am_cv_prog_cc_stdc" >&6 +fi +case "x$am_cv_prog_cc_stdc" in + x|xno) ;; + *) CC="$CC $am_cv_prog_cc_stdc" ;; +esac + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <assert.h> + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <ac_nonexistent.h> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <assert.h> + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <ac_nonexistent.h> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check" >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <ctype.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \${MAKE}... $ECHO_C" >&6 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +all: + @echo 'ac_maketemp="${MAKE}"' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftest.make +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + SET_MAKE= +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "$*" != "X $srcdir/configure conftestfile" \ + && test "$*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftestfile + ) +then + # Ok. + : +else + { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +rm -f conftest* +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5 +echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6 + # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then + enableval="$enable_maintainer_mode" + USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi; + echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5 +echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6 + + +if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + MAINT=$MAINTAINER_MODE_TRUE + + +echo "$as_me:$LINENO: checking if malloc debugging is wanted" >&5 +echo $ECHO_N "checking if malloc debugging is wanted... $ECHO_C" >&6 + +# Check whether --with-dmalloc or --without-dmalloc was given. +if test "${with_dmalloc+set}" = set; then + withval="$with_dmalloc" + if test "$withval" = yes; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +cat >>confdefs.h <<\_ACEOF +#define WITH_DMALLOC 1 +_ACEOF + + LIBS="$LIBS -ldmalloc" + LDFLAGS="$LDFLAGS -g" +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi; + + + + +# Check whether --with-imlib2-prefix or --without-imlib2-prefix was given. +if test "${with_imlib2_prefix+set}" = set; then + withval="$with_imlib2_prefix" + imlib2_config_prefix="$withval" +else + imlib2_config_prefix="" +fi; + +# Check whether --with-imlib2-exec-prefix or --without-imlib2-exec-prefix was given. +if test "${with_imlib2_exec_prefix+set}" = set; then + withval="$with_imlib2_exec_prefix" + imlib2_config_exec_prefix="$withval" +else + imlib2_config_exec_prefix="" +fi; + + if test x$imlib2_config_exec_prefix != x ; then + imlib2_config_args="$imlib2_config_args --exec-prefix=$imlib2_config_exec_prefix" + if test x${IMLIB2_CONFIG+set} != xset ; then + IMLIB2_CONFIG=$imlib2_config_exec_prefix/bin/imlib2-config + fi + fi + if test x$imlib2_config_prefix != x ; then + imlib2_config_args="$imlib2_config_args --prefix=$imlib2_config_prefix" + if test x${IMLIB2_CONFIG+set} != xset ; then + IMLIB2_CONFIG=$imlib2_config_prefix/bin/imlib2-config + fi + fi + + # Extract the first word of "imlib2-config", so it can be a program name with args. +set dummy imlib2-config; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_IMLIB2_CONFIG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $IMLIB2_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_IMLIB2_CONFIG="$IMLIB2_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_IMLIB2_CONFIG="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_path_IMLIB2_CONFIG" && ac_cv_path_IMLIB2_CONFIG="no" + ;; +esac +fi +IMLIB2_CONFIG=$ac_cv_path_IMLIB2_CONFIG + +if test -n "$IMLIB2_CONFIG"; then + echo "$as_me:$LINENO: result: $IMLIB2_CONFIG" >&5 +echo "${ECHO_T}$IMLIB2_CONFIG" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + echo "$as_me:$LINENO: checking for imlib2 - version >= 1.0.0" >&5 +echo $ECHO_N "checking for imlib2 - version >= 1.0.0... $ECHO_C" >&6 + + no_imlib2="" + if test "$IMLIB2_CONFIG" = "no" ; then + no_imlib2=yes + else + IMLIB2_CFLAGS="`$IMLIB2_CONFIG $imlib2_config_args --cflags`" + IMLIB2_LIBS="`$IMLIB2_CONFIG $imlib2_config_args --libs`" + + imlib2_config_major_version=`$IMLIB2_CONFIG $imlib2_config_args \ + --version | sed 's/[^0-9]*\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` + imlib2_config_minor_version=`$IMLIB2_CONFIG $imlib2_config_args \ + --version | sed 's/[^0-9]*\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'` + imlib2_config_micro_version=`$IMLIB2_CONFIG $imlib2_config_args \ + --version | sed 's/[^0-9]*\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` + imlib2_wanted_major_version="1" + imlib2_wanted_minor_version="0" + imlib2_wanted_micro_version="0" + + # Compare wanted version to what config script returned. + # If I knew what library was being run, i'd probably also compile + # a test program at this point (which also extracted and tested + # the version in some library-specific way) + if test "$imlib2_config_major_version" -lt \ + "$imlib2_wanted_major_version" \ + -o \( "$imlib2_config_major_version" -eq \ + "$imlib2_wanted_major_version" \ + -a "$imlib2_config_minor_version" -lt \ + "$imlib2_wanted_minor_version" \) \ + -o \( "$imlib2_config_major_version" -eq \ + "$imlib2_wanted_major_version" \ + -a "$imlib2_config_minor_version" -eq \ + "$imlib2_wanted_minor_version" \ + -a "$imlib2_config_micro_version" -lt \ + "$imlib2_wanted_micro_version" \) ; then + # older version found + no_imlib2=yes + echo -n "*** An old version of imlib2 " + echo -n "($imlib2_config_major_version" + echo -n ".$imlib2_config_minor_version" + echo ".$imlib2_config_micro_version) was found." + echo -n "*** You need a version of imlib2 newer than " + echo -n "$imlib2_wanted_major_version" + echo -n ".$imlib2_wanted_minor_version" + echo ".$imlib2_wanted_micro_version." + echo "***" + echo "*** If you have already installed a sufficiently new version, this error" + echo "*** probably means that the wrong copy of the imlib2-config shell script is" + echo "*** being found. The easiest way to fix this is to remove the old version" + echo "*** of imlib2, but you can also set the IMLIB2_CONFIG environment to point to the" + echo "*** correct copy of imlib2-config. (In this case, you will have to" + echo "*** modify your LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf" + echo "*** so that the correct libraries are found at run-time)" + fi + + fi + if test "x$no_imlib2" = x ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + + + + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + if test "$IMLIB2_CONFIG" = "no" ; then + echo "*** The imlib2-config script installed by imlib2 could not be found" + echo "*** If imlib2 was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the IMLIB2_CONFIG environment variable to the" + echo "*** full path to imlib2-config." + fi + IMLIB2_CFLAGS="" + IMLIB2_LIBS="" + { { echo "$as_me:$LINENO: error: Cannot find imlib2: Is imlib2-config in the path?" >&5 +echo "$as_me: error: Cannot find imlib2: Is imlib2-config in the path?" >&2;} + { (exit 1); exit 1; }; } + fi + + + + + + + +IMLIB_LIBS=`imlib2-config --libs` +IMLIB_CFLAGS=`imlib2-config --cflags` + + + + + +# Check whether --with-aalib-prefix or --without-aalib-prefix was given. +if test "${with_aalib_prefix+set}" = set; then + withval="$with_aalib_prefix" + aalib_config_prefix="$withval" +else + aalib_config_prefix="" +fi; + +# Check whether --with-aalib-exec-prefix or --without-aalib-exec-prefix was given. +if test "${with_aalib_exec_prefix+set}" = set; then + withval="$with_aalib_exec_prefix" + aalib_config_exec_prefix="$withval" +else + aalib_config_exec_prefix="" +fi; + + if test x$aalib_config_exec_prefix != x ; then + aalib_config_args="$aalib_config_args --exec-prefix=$aalib_config_exec_prefix" + if test x${AALIB_CONFIG+set} != xset ; then + AALIB_CONFIG=$aalib_config_exec_prefix/bin/aalib-config + fi + fi + if test x$aalib_config_prefix != x ; then + aalib_config_args="$aalib_config_args --prefix=$aalib_config_prefix" + if test x${AALIB_CONFIG+set} != xset ; then + AALIB_CONFIG=$aalib_config_prefix/bin/aalib-config + fi + fi + + # Extract the first word of "aalib-config", so it can be a program name with args. +set dummy aalib-config; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_AALIB_CONFIG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $AALIB_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_AALIB_CONFIG="$AALIB_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_AALIB_CONFIG="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_path_AALIB_CONFIG" && ac_cv_path_AALIB_CONFIG="no" + ;; +esac +fi +AALIB_CONFIG=$ac_cv_path_AALIB_CONFIG + +if test -n "$AALIB_CONFIG"; then + echo "$as_me:$LINENO: result: $AALIB_CONFIG" >&5 +echo "${ECHO_T}$AALIB_CONFIG" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + echo "$as_me:$LINENO: checking for aalib - version >= 1.0.0" >&5 +echo $ECHO_N "checking for aalib - version >= 1.0.0... $ECHO_C" >&6 + + no_aalib="" + if test "$AALIB_CONFIG" = "no" ; then + no_aalib=yes + else + AALIB_CFLAGS="`$AALIB_CONFIG $aalib_config_args --cflags`" + AALIB_LIBS="`$AALIB_CONFIG $aalib_config_args --libs`" + + aalib_config_major_version=`$AALIB_CONFIG $aalib_config_args \ + --version | sed 's/[^0-9]*\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` + aalib_config_minor_version=`$AALIB_CONFIG $aalib_config_args \ + --version | sed 's/[^0-9]*\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'` + aalib_config_micro_version=`$AALIB_CONFIG $aalib_config_args \ + --version | sed 's/[^0-9]*\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` + aalib_wanted_major_version="1" + aalib_wanted_minor_version="0" + aalib_wanted_micro_version="0" + + # Compare wanted version to what config script returned. + # If I knew what library was being run, i'd probably also compile + # a test program at this point (which also extracted and tested + # the version in some library-specific way) + if test "$aalib_config_major_version" -lt \ + "$aalib_wanted_major_version" \ + -o \( "$aalib_config_major_version" -eq \ + "$aalib_wanted_major_version" \ + -a "$aalib_config_minor_version" -lt \ + "$aalib_wanted_minor_version" \) \ + -o \( "$aalib_config_major_version" -eq \ + "$aalib_wanted_major_version" \ + -a "$aalib_config_minor_version" -eq \ + "$aalib_wanted_minor_version" \ + -a "$aalib_config_micro_version" -lt \ + "$aalib_wanted_micro_version" \) ; then + # older version found + no_aalib=yes + echo -n "*** An old version of aalib " + echo -n "($aalib_config_major_version" + echo -n ".$aalib_config_minor_version" + echo ".$aalib_config_micro_version) was found." + echo -n "*** You need a version of aalib newer than " + echo -n "$aalib_wanted_major_version" + echo -n ".$aalib_wanted_minor_version" + echo ".$aalib_wanted_micro_version." + echo "***" + echo "*** If you have already installed a sufficiently new version, this error" + echo "*** probably means that the wrong copy of the aalib-config shell script is" + echo "*** being found. The easiest way to fix this is to remove the old version" + echo "*** of aalib, but you can also set the AALIB_CONFIG environment to point to the" + echo "*** correct copy of aalib-config. (In this case, you will have to" + echo "*** modify your LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf" + echo "*** so that the correct libraries are found at run-time)" + fi + + fi + if test "x$no_aalib" = x ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + + + + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + if test "$AALIB_CONFIG" = "no" ; then + echo "*** The aalib-config script installed by aalib could not be found" + echo "*** If aalib was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the AALIB_CONFIG environment variable to the" + echo "*** full path to aalib-config." + fi + AALIB_CFLAGS="" + AALIB_LIBS="" + { { echo "$as_me:$LINENO: error: Cannot find aalib: Is aalib-config in the path?" >&5 +echo "$as_me: error: Cannot find aalib: Is aalib-config in the path?" >&2;} + { (exit 1); exit 1; }; } + fi + + + + + + + +AALIB_LIBS=`aalib-config --libs` +AALIB_CFLAGS=`aalib-config --cflags` + + + + +echo "$as_me:$LINENO: checking for XWindowByProperty in -lMagick" >&5 +echo $ECHO_N "checking for XWindowByProperty in -lMagick... $ECHO_C" >&6 +if test "${ac_cv_lib_Magick_XWindowByProperty+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lMagick -I/usr/X11R6/include -L/usr/X11R6/lib $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char XWindowByProperty (); +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +XWindowByProperty (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_Magick_XWindowByProperty=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_Magick_XWindowByProperty=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_Magick_XWindowByProperty" >&5 +echo "${ECHO_T}$ac_cv_lib_Magick_XWindowByProperty" >&6 +if test $ac_cv_lib_Magick_XWindowByProperty = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBMAGICK 1 +_ACEOF + + LIBS="-lMagick $LIBS" + +else + { { echo "$as_me:$LINENO: error: screen captures requires ImageMagick library!!" >&5 +echo "$as_me: error: screen captures requires ImageMagick library!!" >&2;} + { (exit 1); exit 1; }; } +fi + + +echo "$as_me:$LINENO: checking for BZ2_bzBuffToBuffCompress in -lbz2" >&5 +echo $ECHO_N "checking for BZ2_bzBuffToBuffCompress in -lbz2... $ECHO_C" >&6 +if test "${ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lbz2 $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char BZ2_bzBuffToBuffCompress (); +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +BZ2_bzBuffToBuffCompress (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress" >&5 +echo "${ECHO_T}$ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress" >&6 +if test $ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBBZ2 1 +_ACEOF + + LIBS="-lbz2 $LIBS" + +else + { { echo "$as_me:$LINENO: error: streaming requires bz2 library!!" >&5 +echo "$as_me: error: streaming requires bz2 library!!" >&2;} + { (exit 1); exit 1; }; } +fi + + +echo "$as_me:$LINENO: checking for deflate in -lz" >&5 +echo $ECHO_N "checking for deflate in -lz... $ECHO_C" >&6 +if test "${ac_cv_lib_z_deflate+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lz $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char deflate (); +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +deflate (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_z_deflate=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_z_deflate=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_z_deflate" >&5 +echo "${ECHO_T}$ac_cv_lib_z_deflate" >&6 +if test $ac_cv_lib_z_deflate = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBZ 1 +_ACEOF + + LIBS="-lz $LIBS" + +else + { { echo "$as_me:$LINENO: error: streaming requires compress library!!" >&5 +echo "$as_me: error: streaming requires compress library!!" >&2;} + { (exit 1); exit 1; }; } +fi + + +echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBDL 1 +_ACEOF + + LIBS="-ldl $LIBS" + +else + { { echo "$as_me:$LINENO: error: streaming requires dynamic loader library!!" >&5 +echo "$as_me: error: streaming requires dynamic loader library!!" >&2;} + { (exit 1); exit 1; }; } +fi + + +echo "$as_me:$LINENO: checking for InitMP3 in -lmp3lame" >&5 +echo $ECHO_N "checking for InitMP3 in -lmp3lame... $ECHO_C" >&6 +if test "${ac_cv_lib_mp3lame_InitMP3+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lmp3lame -lm $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char InitMP3 (); +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +InitMP3 (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_mp3lame_InitMP3=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_mp3lame_InitMP3=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_mp3lame_InitMP3" >&5 +echo "${ECHO_T}$ac_cv_lib_mp3lame_InitMP3" >&6 +if test $ac_cv_lib_mp3lame_InitMP3 = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBMP3LAME 1 +_ACEOF + + LIBS="-lmp3lame $LIBS" + +else + { { echo "$as_me:$LINENO: error: streaming requires lame library!!" >&5 +echo "$as_me: error: streaming requires lame library!!" >&2;} + { (exit 1); exit 1; }; } +fi + + +echo "$as_me:$LINENO: checking for ogg_stream_init in -logg" >&5 +echo $ECHO_N "checking for ogg_stream_init in -logg... $ECHO_C" >&6 +if test "${ac_cv_lib_ogg_ogg_stream_init+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-logg -lm $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char ogg_stream_init (); +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +ogg_stream_init (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_ogg_ogg_stream_init=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_ogg_ogg_stream_init=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_ogg_ogg_stream_init" >&5 +echo "${ECHO_T}$ac_cv_lib_ogg_ogg_stream_init" >&6 +if test $ac_cv_lib_ogg_ogg_stream_init = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBOGG 1 +_ACEOF + + LIBS="-logg $LIBS" + +else + { { echo "$as_me:$LINENO: error: streaming requires ogg library!!" >&5 +echo "$as_me: error: streaming requires ogg library!!" >&2;} + { (exit 1); exit 1; }; } +fi + + +echo "$as_me:$LINENO: checking for vorbis_analysis_init in -lvorbis" >&5 +echo $ECHO_N "checking for vorbis_analysis_init in -lvorbis... $ECHO_C" >&6 +if test "${ac_cv_lib_vorbis_vorbis_analysis_init+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lvorbis -lm $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char vorbis_analysis_init (); +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +vorbis_analysis_init (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_vorbis_vorbis_analysis_init=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_vorbis_vorbis_analysis_init=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_vorbis_vorbis_analysis_init" >&5 +echo "${ECHO_T}$ac_cv_lib_vorbis_vorbis_analysis_init" >&6 +if test $ac_cv_lib_vorbis_vorbis_analysis_init = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBVORBIS 1 +_ACEOF + + LIBS="-lvorbis $LIBS" + +else + { { echo "$as_me:$LINENO: error: streaming requires vorbis library!!" >&5 +echo "$as_me: error: streaming requires vorbis library!!" >&2;} + { (exit 1); exit 1; }; } +fi + + +echo "$as_me:$LINENO: checking for vorbis_encode_setup_init in -lvorbisenc" >&5 +echo $ECHO_N "checking for vorbis_encode_setup_init in -lvorbisenc... $ECHO_C" >&6 +if test "${ac_cv_lib_vorbisenc_vorbis_encode_setup_init+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lvorbisenc -lm $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char vorbis_encode_setup_init (); +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +vorbis_encode_setup_init (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_vorbisenc_vorbis_encode_setup_init=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_vorbisenc_vorbis_encode_setup_init=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_vorbisenc_vorbis_encode_setup_init" >&5 +echo "${ECHO_T}$ac_cv_lib_vorbisenc_vorbis_encode_setup_init" >&6 +if test $ac_cv_lib_vorbisenc_vorbis_encode_setup_init = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBVORBISENC 1 +_ACEOF + + LIBS="-lvorbisenc $LIBS" + +else + { { echo "$as_me:$LINENO: error: streaming requires vorbis encoder library!!" >&5 +echo "$as_me: error: streaming requires vorbis encoder library!!" >&2;} + { (exit 1); exit 1; }; } +fi + + + + +MAGICK_LIBS="-L/usr/X11R6/lib `Magick-config --libs` `Magick-config --ldflags`" +MAGICK_CFLAGS="-I/usr/X11R6/include `Magick-config --cflags` " + + + +echo -n "looking for pd sources (required) ... " +if test -f $PD_DIR/src/m_pd.h +then + + echo "ok." +else + echo "pd source tree not found... install it, fix the path in configure.ac and run autoconf" + exit -1 +fi + +echo -n "looking for pdp sources (required) ... " +if test -f $PDP_DIR/CHANGES.LOG +then + + echo "ok." +else + echo "pdp source tree not found... install it, fix the path in configure.ac and run autoconf" + exit -1 +fi + +echo -n "looking for ffmpeg sources (required) ... " +if test -f $FFMPEG_SOURCE_DIR/libavformat/avformat.h +then + + echo "ok." +else + echo "ffmpeg source tree not found... install it, fix the path in configure.ac and run autoconf" + exit -1 +fi + +LIBS="$LIBS -lbz2 -lz -ldl -lmp3lame -logg -lvorbis -lvorbisenc" +CFLAGS="$CFLAGS -Wall" + +ac_config_files="$ac_config_files Makefile system/Makefile modules/Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overriden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, 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 \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if cmp -s $cache_file confcache; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then we branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +cat >confdef2opt.sed <<\_ACEOF +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g +t quote +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g +t quote +d +: quote +s,[ `~#$^&*(){}\\|;'"<>?],\\&,g +s,\[,\\&,g +s,\],\\&,g +s,\$,$$,g +p +_ACEOF +# We use echo to avoid assuming a particular line-breaking character. +# The extra dot is to prevent the shell from consuming trailing +# line-breaks from the sub-command output. A line-break within +# single-quotes doesn't work because, if this script is created in a +# platform that uses two characters for line-breaks (e.g., DOS), tr +# would break. +ac_LF_and_DOT=`echo; echo .` +DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` +rm -f confdef2opt.sed + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# NLS nuisances. +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + +(set +x; test -n "`(LANG=C; export LANG) 2>&1`") && + { $as_unset LANG || test "${LANG+set}" != set; } || + { LANG=C; export LANG; } +(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") && + { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } || + { LC_ALL=C; export LC_ALL; } +(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") && + { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } || + { LC_TIME=C; export LC_TIME; } +(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") && + { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } || + { LC_CTYPE=C; export LC_CTYPE; } +(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") && + { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } || + { LANGUAGE=C; export LANGUAGE; } +(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") && + { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } || + { LC_COLLATE=C; export LC_COLLATE; } +(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") && + { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } || + { LC_NUMERIC=C; export LC_NUMERIC; } +(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") && + { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } || + { LC_MESSAGES=C; export LC_MESSAGES; } + + +# Name of the executable. +as_me=`(basename "$0") 2>/dev/null || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conftest.sh + echo "exit 0" >>conftest.sh + chmod +x conftest.sh + if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conftest.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; } + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by $as_me, which was +generated by GNU Autoconf 2.53. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Report bugs to <bug-autoconf@gnu.org>." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.53, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + shift + set dummy "$ac_option" "$ac_optarg" ${1+"$@"} + shift + ;; + -*);; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_need_defaults=false;; + esac + + case $1 in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running $SHELL $0 " $ac_configure_args " --no-create --no-recursion" + exec $SHELL $0 $ac_configure_args --no-create --no-recursion ;; +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + shift + CONFIG_FILES="$CONFIG_FILES $1" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + shift + CONFIG_HEADERS="$CONFIG_HEADERS $1" + ac_need_defaults=false;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +_ACEOF + + + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "system/Makefile" ) CONFIG_FILES="$CONFIG_FILES system/Makefile" ;; + "modules/Makefile" ) CONFIG_FILES="$CONFIG_FILES modules/Makefile" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files +fi + +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. +: ${TMPDIR=/tmp} +{ + tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=$TMPDIR/cs$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in $TMPDIR" >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@CPP@,$CPP,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@SET_MAKE@,$SET_MAKE,;t t +s,@MAINTAINER_MODE_TRUE@,$MAINTAINER_MODE_TRUE,;t t +s,@MAINTAINER_MODE_FALSE@,$MAINTAINER_MODE_FALSE,;t t +s,@MAINT@,$MAINT,;t t +s,@IMLIB2_CONFIG@,$IMLIB2_CONFIG,;t t +s,@IMLIB_LIBS@,$IMLIB_LIBS,;t t +s,@IMLIB_CFLAGS@,$IMLIB_CFLAGS,;t t +s,@IMLIB2_CFLAGS@,$IMLIB2_CFLAGS,;t t +s,@IMLIB2_LIBS@,$IMLIB2_LIBS,;t t +s,@AALIB_CONFIG@,$AALIB_CONFIG,;t t +s,@AALIB_LIBS@,$AALIB_LIBS,;t t +s,@AALIB_CFLAGS@,$AALIB_CFLAGS,;t t +s,@PDP_PIDIP_VERSION@,$PDP_PIDIP_VERSION,;t t +s,@MAGICK_LIBS@,$MAGICK_LIBS,;t t +s,@MAGICK_CFLAGS@,$MAGICK_CFLAGS,;t t +s,@PD_DIR@,$PD_DIR,;t t +s,@PDP_DIR@,$PDP_DIR,;t t +s,@FFMPEG_SOURCE_DIR@,$FFMPEG_SOURCE_DIR,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # 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_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # 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" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { case "$ac_dir" in + [\\/]* | ?:[\\/]* ) as_incr_dir=;; + *) as_incr_dir=.;; +esac +as_dummy="$ac_dir" +for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do + case $as_mkdir_dir in + # Skip DOS drivespec + ?:) as_incr_dir=$as_mkdir_dir ;; + *) + as_incr_dir=$as_incr_dir/$as_mkdir_dir + test -d "$as_incr_dir" || + mkdir "$as_incr_dir" || + { { echo "$as_me:$LINENO: error: cannot create \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; } + ;; + esac +done; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + exec 5>/dev/null + $SHELL $CONFIG_STATUS || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..f7951e7 --- /dev/null +++ b/configure.ac @@ -0,0 +1,96 @@ +dnl Process this file with autoconf to produce a configure script. + +AC_INIT +PDP_PIDIP_VERSION=0.12.4 +PD_DIR=/usr/local/pd +PDP_DIR=/usr/local/pd/pdp +FFMPEG_SOURCE_DIR=/SOURCES/ffmpeg + +AC_ISC_POSIX +AC_PROG_CC +AM_PROG_CC_STDC +AC_HEADER_STDC +AC_PROG_INSTALL +AC_PROG_MAKE_SET +AM_SANITY_CHECK + +AM_MAINTAINER_MODE +AM_WITH_DMALLOC + +AC_PATH_GENERIC(imlib2, 1.0.0, [ + AC_SUBST(IMLIB_LIBS) + AC_SUBST(IMLIB_CFLAGS) ], + AC_MSG_ERROR(Cannot find imlib2: Is imlib2-config in the path?) ) + +dnl the above doesn't work for some reason :/ +IMLIB_LIBS=`imlib2-config --libs` +IMLIB_CFLAGS=`imlib2-config --cflags` +AC_SUBST(IMLIB_LIBS) +AC_SUBST(IMLIB_CFLAGS) + +AC_PATH_GENERIC(aalib, 1.0.0, [ + AC_SUBST(AALIB_LIBS) + AC_SUBST(AALIB_CFLAGS) ], + AC_MSG_ERROR(Cannot find aalib: Is aalib-config in the path?) ) + +dnl the above doesn't work for some reason :/ +AALIB_LIBS=`aalib-config --libs` +AALIB_CFLAGS=`aalib-config --cflags` +AC_SUBST(AALIB_LIBS) +AC_SUBST(AALIB_CFLAGS) + +AC_CHECK_LIB(Magick, XWindowByProperty, , AC_MSG_ERROR(screen captures requires ImageMagick library!!), -I/usr/X11R6/include -L/usr/X11R6/lib ) +AC_CHECK_LIB(bz2, BZ2_bzBuffToBuffCompress, , AC_MSG_ERROR(streaming requires bz2 library!!)) +AC_CHECK_LIB(z, deflate, , AC_MSG_ERROR(streaming requires compress library!!)) +AC_CHECK_LIB(dl, dlopen, , AC_MSG_ERROR(streaming requires dynamic loader library!!)) +AC_CHECK_LIB(mp3lame, InitMP3, , AC_MSG_ERROR(streaming requires lame library!!), -lm) +AC_CHECK_LIB(ogg, ogg_stream_init, , AC_MSG_ERROR(streaming requires ogg library!!), -lm) +AC_CHECK_LIB(vorbis, vorbis_analysis_init, , AC_MSG_ERROR(streaming requires vorbis library!!), -lm) +AC_CHECK_LIB(vorbisenc, vorbis_encode_setup_init, , AC_MSG_ERROR(streaming requires vorbis encoder library!!), -lm) + +AC_SUBST(PDP_PIDIP_VERSION) + +MAGICK_LIBS="-L/usr/X11R6/lib `Magick-config --libs` `Magick-config --ldflags`" +MAGICK_CFLAGS="-I/usr/X11R6/include `Magick-config --cflags` " +AC_SUBST(MAGICK_LIBS) +AC_SUBST(MAGICK_CFLAGS) + +echo -n "looking for pd sources (required) ... " +if test -f $PD_DIR/src/m_pd.h +then + AC_SUBST(PD_DIR) + echo "ok." +else + echo "pd source tree not found... install it, fix the path in configure.ac and run autoconf" + exit -1 +fi + +echo -n "looking for pdp sources (required) ... " +if test -f $PDP_DIR/CHANGES.LOG +then + AC_SUBST(PDP_DIR) + echo "ok." +else + echo "pdp source tree not found... install it, fix the path in configure.ac and run autoconf" + exit -1 +fi + +echo -n "looking for ffmpeg sources (required) ... " +if test -f $FFMPEG_SOURCE_DIR/libavformat/avformat.h +then + AC_SUBST(FFMPEG_SOURCE_DIR) + echo "ok." +else + echo "ffmpeg source tree not found... install it, fix the path in configure.ac and run autoconf" + exit -1 +fi + +LIBS="$LIBS -lbz2 -lz -ldl -lmp3lame -logg -lvorbis -lvorbisenc" +CFLAGS="$CFLAGS -Wall" + +AC_CONFIG_FILES([ +Makefile +system/Makefile +modules/Makefile +]) +AC_OUTPUT diff --git a/doc/help_emboss.pd b/doc/help_emboss.pd new file mode 100644 index 0000000..2c6bcf2 --- /dev/null +++ b/doc/help_emboss.pd @@ -0,0 +1,43 @@ +#N canvas 237 46 649 451 10; +#X obj 134 240 pdp_conv_emboss; +#X obj 151 303 pdp_xv; +#X floatatom 223 210 5 0 0; +#X obj 153 39 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 58 107 loop \$1; +#X obj 59 85 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1 +; +#X msg 255 19 open \$1; +#X obj 254 -5 openpanel; +#X obj 239 -22 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 201 74 5 0 0; +#X msg 110 40 stop; +#X obj 208 43 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 142 110 metro 70; +#X obj 137 142 pdp_yqt; +#X obj 306 141 pdp_v4l; +#X obj 315 110 metro 70; +#X obj 360 76 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 317 77 stop; +#X msg 402 108 open /dev/video; +#X connect 0 0 1 0; +#X connect 2 0 0 1; +#X connect 3 0 12 0; +#X connect 4 0 13 0; +#X connect 5 0 4 0; +#X connect 6 0 13 0; +#X connect 7 0 6 0; +#X connect 8 0 7 0; +#X connect 9 0 12 1; +#X connect 10 0 12 0; +#X connect 11 0 9 0; +#X connect 12 0 13 0; +#X connect 13 0 0 0; +#X connect 14 0 0 0; +#X connect 15 0 14 0; +#X connect 16 0 15 0; +#X connect 17 0 15 0; +#X connect 18 0 14 0; diff --git a/doc/help_invert.pd b/doc/help_invert.pd new file mode 100644 index 0000000..2f40700 --- /dev/null +++ b/doc/help_invert.pd @@ -0,0 +1,42 @@ +#N canvas 237 46 649 451 10; +#X obj 134 240 pdp_invert; +#X obj 151 303 pdp_xv; +#X floatatom 223 210 5 0 0; +#X obj 153 39 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 58 107 loop \$1; +#X obj 59 85 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1 +; +#X msg 255 19 open \$1; +#X obj 254 -5 openpanel; +#X obj 239 -22 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 201 74 5 0 0; +#X msg 110 40 stop; +#X obj 208 43 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 142 110 metro 70; +#X obj 137 142 pdp_yqt; +#X obj 306 141 pdp_v4l; +#X obj 315 110 metro 70; +#X obj 360 76 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 317 77 stop; +#X msg 402 108 open /dev/video; +#X connect 0 0 1 0; +#X connect 3 0 12 0; +#X connect 4 0 13 0; +#X connect 5 0 4 0; +#X connect 6 0 13 0; +#X connect 7 0 6 0; +#X connect 8 0 7 0; +#X connect 9 0 12 1; +#X connect 10 0 12 0; +#X connect 11 0 9 0; +#X connect 12 0 13 0; +#X connect 13 0 0 0; +#X connect 14 0 0 0; +#X connect 15 0 14 0; +#X connect 16 0 15 0; +#X connect 17 0 15 0; +#X connect 18 0 14 0; diff --git a/doc/help_pdp_aa.pd b/doc/help_pdp_aa.pd new file mode 100644 index 0000000..b768611 --- /dev/null +++ b/doc/help_pdp_aa.pd @@ -0,0 +1,72 @@ +#N canvas 84 12 763 664 10; +#X obj 191 444 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 1 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X obj 346 203 pdp_v4l; +#X obj 355 172 metro 70; +#X obj 400 138 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 357 139 stop; +#X msg 442 170 open /dev/video; +#X obj 252 167 pdp_yqt; +#X obj 606 530 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 606 582 pdp_control; +#X msg 606 555 thread \$1; +#X floatatom 606 643 5 0 0; +#X obj 606 614 route pdp_drop; +#X text 224 632 written by Yves Degoyon (ydegoyon@free.fr); +#X msg 445 203 dim 800 600; +#X text 223 618 ( http://aa-project.sourceforge.net/aalib ); +#X text 224 603 it makes use of aalib; +#X obj 191 411 pdp_aa -----------------; +#X msg 318 287 driver X11; +#X msg 420 287 driver slang; +#X msg 419 309 driver stdout; +#X msg 318 309 driver stderr; +#X text 523 285 Set the driver; +#X msg 319 356 render \$1; +#X obj 396 356 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X text 418 356 Activate/Deactivate rendering; +#X text 225 589 pdp_aa : output images in ASCII art; +#X connect 1 0 10 0; +#X connect 2 0 16 0; +#X connect 3 0 2 0; +#X connect 4 0 16 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 10 1; +#X connect 8 0 10 0; +#X connect 9 0 7 0; +#X connect 10 0 16 0; +#X connect 11 0 26 0; +#X connect 12 0 11 0; +#X connect 13 0 12 0; +#X connect 14 0 12 0; +#X connect 15 0 11 0; +#X connect 16 0 26 0; +#X connect 17 0 19 0; +#X connect 18 0 21 0; +#X connect 19 0 18 0; +#X connect 21 0 20 0; +#X connect 23 0 11 0; +#X connect 26 0 0 0; +#X connect 27 0 26 0; +#X connect 28 0 26 0; +#X connect 29 0 26 0; +#X connect 30 0 26 0; +#X connect 32 0 26 0; +#X connect 33 0 32 0; diff --git a/doc/help_pdp_aging.pd b/doc/help_pdp_aging.pd new file mode 100644 index 0000000..07d3c56 --- /dev/null +++ b/doc/help_pdp_aging.pd @@ -0,0 +1,60 @@ +#N canvas 237 21 712 664 10; +#X obj 218 367 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 283 243 dac~; +#X obj 257 135 metro 70; +#X obj 252 167 pdp_yqt; +#X floatatom 311 275 5 0 0; +#X floatatom 331 301 5 0 0; +#X text 387 301 Number of scratches; +#X text 366 272 Dust density; +#X obj 217 299 pdp_aging; +#X obj 421 166 pdp_v4l; +#X obj 430 135 metro 70; +#X obj 475 101 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 432 102 stop; +#X msg 517 133 open /dev/video; +#X obj 414 352 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 414 404 pdp_control; +#X msg 414 377 thread \$1; +#X floatatom 414 465 5 0 0; +#X obj 414 436 route pdp_drop; +#X connect 1 0 11 0; +#X connect 2 0 12 0; +#X connect 3 0 2 0; +#X connect 4 0 12 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 11 1; +#X connect 8 0 11 0; +#X connect 9 0 7 0; +#X connect 11 0 12 0; +#X connect 12 0 17 0; +#X connect 12 3 10 0; +#X connect 12 4 10 1; +#X connect 13 0 17 1; +#X connect 14 0 17 2; +#X connect 17 0 0 0; +#X connect 18 0 17 0; +#X connect 19 0 18 0; +#X connect 20 0 19 0; +#X connect 21 0 19 0; +#X connect 22 0 18 0; +#X connect 23 0 25 0; +#X connect 24 0 27 0; +#X connect 25 0 24 0; +#X connect 27 0 26 0; diff --git a/doc/help_pdp_ascii.pd b/doc/help_pdp_ascii.pd new file mode 100644 index 0000000..94e2290 --- /dev/null +++ b/doc/help_pdp_ascii.pd @@ -0,0 +1,67 @@ +#N canvas 84 12 763 664 10; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X obj 346 203 pdp_v4l; +#X obj 355 172 metro 70; +#X obj 400 138 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 357 139 stop; +#X msg 442 170 open /dev/video; +#X obj 252 167 pdp_yqt; +#X obj 606 530 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 606 582 pdp_control; +#X msg 606 555 thread \$1; +#X floatatom 606 643 5 0 0; +#X obj 606 614 route pdp_drop; +#X text 226 604 written by Yves Degoyon (ydegoyon@free.fr); +#X text 225 589 pdp_aa : output images in ASCII art; +#X msg 302 347 color \$1; +#X obj 373 348 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X text 393 347 activate/suppress colors; +#X obj 191 413 pdp_ascii; +#X msg 302 372 brightness \$1; +#X floatatom 404 373 5 0 0; +#X text 452 374 increase brightness ( default 25 ); +#X floatatom 302 398 5 0 0; +#X text 352 397 Character to pixel ratio; +#X obj 191 444 pdp_xv; +#X connect 0 0 9 0; +#X connect 1 0 15 0; +#X connect 2 0 1 0; +#X connect 3 0 15 0; +#X connect 4 0 3 0; +#X connect 5 0 4 0; +#X connect 6 0 9 1; +#X connect 7 0 9 0; +#X connect 8 0 6 0; +#X connect 9 0 15 0; +#X connect 10 0 26 0; +#X connect 11 0 10 0; +#X connect 12 0 11 0; +#X connect 13 0 11 0; +#X connect 14 0 10 0; +#X connect 15 0 26 0; +#X connect 16 0 18 0; +#X connect 17 0 20 0; +#X connect 18 0 17 0; +#X connect 20 0 19 0; +#X connect 23 0 26 0; +#X connect 24 0 23 0; +#X connect 26 0 32 0; +#X connect 27 0 26 0; +#X connect 28 0 27 0; +#X connect 30 0 26 1; diff --git a/doc/help_pdp_baltan.pd b/doc/help_pdp_baltan.pd new file mode 100644 index 0000000..422c513 --- /dev/null +++ b/doc/help_pdp_baltan.pd @@ -0,0 +1,60 @@ +#N canvas 237 21 712 664 10; +#X obj 218 367 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 283 243 dac~; +#X obj 257 135 metro 70; +#X obj 217 299 pdp_baltan; +#X obj 252 167 pdp_yqt; +#X floatatom 347 280 10 0 0; +#X msg 367 249 1.65798e+07; +#X obj 387 219 loadbang; +#X obj 421 166 pdp_v4l; +#X obj 430 135 metro 70; +#X obj 475 101 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 432 102 stop; +#X msg 517 133 open /dev/video; +#X obj 414 352 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 414 404 pdp_control; +#X msg 414 377 thread \$1; +#X floatatom 414 465 5 0 0; +#X obj 414 436 route pdp_drop; +#X connect 1 0 11 0; +#X connect 2 0 13 0; +#X connect 3 0 2 0; +#X connect 4 0 13 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 11 1; +#X connect 8 0 11 0; +#X connect 9 0 7 0; +#X connect 11 0 13 0; +#X connect 12 0 0 0; +#X connect 13 0 12 0; +#X connect 13 3 10 0; +#X connect 13 4 10 1; +#X connect 14 0 12 1; +#X connect 15 0 14 0; +#X connect 16 0 15 0; +#X connect 17 0 12 0; +#X connect 18 0 17 0; +#X connect 19 0 18 0; +#X connect 20 0 18 0; +#X connect 21 0 17 0; +#X connect 22 0 24 0; +#X connect 23 0 26 0; +#X connect 24 0 23 0; +#X connect 26 0 25 0; diff --git a/doc/help_pdp_capture.pd b/doc/help_pdp_capture.pd new file mode 100644 index 0000000..7eca873 --- /dev/null +++ b/doc/help_pdp_capture.pd @@ -0,0 +1,44 @@ +#N canvas 237 21 712 664 10; +#X obj 131 353 pdp_xv; +#X obj 494 427 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 494 479 pdp_control; +#X msg 494 452 thread \$1; +#X floatatom 494 540 5 0 0 0 - - -; +#X obj 494 511 route pdp_drop; +#X text 44 481 written by Yves Degoyon ( ydegoyon@free.fr ); +#X text 43 466 pdp_capture : capture a portion of the screen; +#X floatatom 237 156 5 0 0 0 - - -; +#X floatatom 248 179 5 0 0 0 - - -; +#X floatatom 265 202 5 0 0 0 - - -; +#X floatatom 279 227 5 0 0 0 - - -; +#X msg 72 90 bang; +#X msg 125 89 stop; +#X msg 229 125 screen 0; +#X text 392 101 Sets the display; +#X text 296 125 Sets the screen number; +#X obj 183 300 pdp_scale 320 240; +#X obj 89 135 metro 200; +#X obj 183 264 pdp_capture; +#X text 318 201 Width ( default : 320 ); +#X text 301 178 Upper left Y position ( default : 0 ); +#X text 290 155 Upper left X position ( default : 0 ); +#X text 332 226 Height ( default : 240 ); +#X floatatom 174 109 5 0 0 0 - - -; +#X msg 218 101 display 192.168.0.7:0; +#X connect 1 0 3 0; +#X connect 2 0 5 0; +#X connect 3 0 2 0; +#X connect 5 0 4 0; +#X connect 8 0 19 1; +#X connect 9 0 19 2; +#X connect 10 0 19 3; +#X connect 11 0 19 4; +#X connect 12 0 18 0; +#X connect 13 0 18 0; +#X connect 14 0 19 0; +#X connect 17 0 0 0; +#X connect 18 0 19 0; +#X connect 19 0 17 0; +#X connect 24 0 18 1; +#X connect 25 0 19 0; diff --git a/doc/help_pdp_cmap.pd b/doc/help_pdp_cmap.pd new file mode 100644 index 0000000..5d49b7c --- /dev/null +++ b/doc/help_pdp_cmap.pd @@ -0,0 +1,113 @@ +#N canvas 137 28 781 666 10; +#X obj 32 596 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X obj 252 167 pdp_yqt; +#X obj 26 263 pdp_v4l; +#X obj 35 232 metro 70; +#X obj 80 198 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 37 199 stop; +#X msg 122 230 open /dev/video; +#X floatatom 253 369 5 0 0; +#X floatatom 262 390 5 0 0; +#X floatatom 270 414 5 0 0; +#X floatatom 228 321 5 0 0; +#X text 346 633 written by Yves Degoyon ( ydegoyon@free.fr ); +#X floatatom 237 345 5 0 0; +#X msg 93 382 pick; +#X floatatom 282 438 5 0 0; +#X msg 293 466 luminosity \$1; +#X obj 394 468 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X text 417 469 Use luminosity in color detection; +#X obj 378 491 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X msg 302 490 cursor \$1; +#X text 401 492 Show cursor or not; +#X obj 100 565 pdp_cmap ----; +#X text 346 618 pdp_cmap : color mapper; +#X text 346 648 idea suggested by liz; +#X obj 218 300 hdl 15 1 0 10 empty empty empty 0 -6 0 8 -262144 -1 +-1 0; +#X text 372 300 Select color index ( capacity is 10 by default ); +#X text 61 364 Pick up the color; +#X text 276 320 X coordinate of cursor; +#X text 285 344 Y coordinate of cursor; +#X text 299 369 R component of the replaced color; +#X text 307 389 G component of the replaced color; +#X text 315 413 B component of the replaced color; +#X text 328 437 Tolerance ( default = 10 ); +#X msg 310 514 clear; +#X msg 318 538 delete \$1; +#X text 440 540 Delete a mapping; +#X msg 341 565 resize 20; +#X floatatom 393 540 5 0 0; +#X obj 669 329 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 669 381 pdp_control; +#X msg 669 354 thread \$1; +#X floatatom 669 442 5 0 0; +#X obj 669 413 route pdp_drop; +#X msg 82 596 cursor \$1; +#X obj 157 597 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X text 401 492 Show cursor or not; +#X text 425 566 Resize the color table; +#X text 371 514 Clear the color table; +#X text 1 422 Set the cursor; +#X msg 105 422 setcur \$1 \$2; +#X connect 0 0 59 0; +#X connect 1 0 10 0; +#X connect 2 0 11 0; +#X connect 3 0 2 0; +#X connect 4 0 11 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 10 1; +#X connect 8 0 10 0; +#X connect 9 0 7 0; +#X connect 10 0 11 0; +#X connect 11 0 31 0; +#X connect 12 0 31 0; +#X connect 13 0 12 0; +#X connect 14 0 13 0; +#X connect 15 0 13 0; +#X connect 16 0 12 0; +#X connect 17 0 31 4; +#X connect 18 0 31 5; +#X connect 19 0 31 6; +#X connect 20 0 31 2; +#X connect 22 0 31 3; +#X connect 23 0 31 0; +#X connect 24 0 31 7; +#X connect 25 0 31 0; +#X connect 26 0 25 0; +#X connect 28 0 29 0; +#X connect 29 0 31 0; +#X connect 31 0 0 0; +#X connect 34 0 31 1; +#X connect 43 0 31 0; +#X connect 44 0 31 0; +#X connect 46 0 31 0; +#X connect 47 0 44 0; +#X connect 48 0 50 0; +#X connect 49 0 52 0; +#X connect 50 0 49 0; +#X connect 52 0 51 0; +#X connect 53 0 0 0; +#X connect 54 0 53 0; +#X connect 59 0 31 0; +#X connect 59 0 23 0; diff --git a/doc/help_pdp_compose.pd b/doc/help_pdp_compose.pd new file mode 100644 index 0000000..4c4e8f7 --- /dev/null +++ b/doc/help_pdp_compose.pd @@ -0,0 +1,137 @@ +#N canvas 221 9 712 664 10; +#X obj 105 562 pdp_xv; +#X obj 100 167 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 54 201 loop \$1; +#X obj 55 179 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1 +; +#X msg 39 146 open \$1; +#X obj 38 122 openpanel; +#X obj 23 105 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 144 stop; +#X obj 121 168 metro 70; +#X obj 116 200 pdp_yqt; +#X floatatom 244 273 5 0 0; +#X floatatom 253 294 5 0 0; +#X floatatom 270 315 5 0 0; +#X floatatom 288 339 5 0 0; +#X text 269 614 written by Yves Degoyon ( ydegoyon@free.fr ); +#X text 290 273 R component; +#X text 298 293 G component; +#X text 315 314 B component; +#X floatatom 299 360 5 0 0; +#X text 336 338 X coordinate of cursor ( pick ); +#X text 347 359 Y coordinate of cursor ( pick ); +#X msg 14 443 pick; +#X text 11 422 Pick up the color; +#X floatatom 309 380 5 0 0; +#X text 356 380 Tolerance ( default = 50 ); +#X text 269 583 pdp_compose : video compositor; +#X text 269 599 change all pixels of a given color by a second video +source; +#X obj 261 160 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 264 195 loop \$1; +#X obj 325 196 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 1 +1; +#X msg 200 139 open \$1; +#X obj 199 115 openpanel; +#X obj 184 98 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 284 137 stop; +#X obj 282 161 metro 70; +#X obj 185 194 pdp_yqt; +#X text 39 76 1st video source; +#X text 182 74 2nd video source; +#X obj 589 455 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 589 507 pdp_control; +#X msg 589 480 thread \$1; +#X floatatom 589 568 5 0 0; +#X obj 589 539 route pdp_drop; +#X obj 97 305 pdp_form ---------; +#X msg 116 246 ellipse 69 124 59 78; +#X floatatom 130 274 5 0 0; +#X floatatom 176 274 5 0 0; +#X msg 317 410 luminosity \$1; +#X obj 419 411 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 258 544 pdp_v4l; +#X obj 258 523 metro 70; +#X obj 362 524 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 322 523 stop; +#X text 269 628 idea suggested by liz; +#X obj 165 466 pdp_compose ----; +#X obj 394 132 pdp_v4l; +#X obj 403 101 metro 70; +#X obj 448 67 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 405 68 stop; +#X msg 490 99 open /dev/video; +#X text 471 67 Live; +#X floatatom 514 66 5 0 0; +#X obj 401 437 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X msg 325 436 cursor \$1; +#X msg 13 393 setcur \$1 \$2; +#X text 10 372 Set the cursor; +#X text 441 409 Use luminosity; +#X text 424 435 Show the cursor; +#X msg 155 561 cursor \$1; +#X obj 233 562 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X connect 0 0 64 0; +#X connect 1 0 8 0; +#X connect 2 0 9 0; +#X connect 3 0 2 0; +#X connect 4 0 9 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 8 0; +#X connect 8 0 9 0; +#X connect 9 0 43 0; +#X connect 10 0 54 2; +#X connect 11 0 54 3; +#X connect 12 0 54 4; +#X connect 13 0 54 5; +#X connect 18 0 54 6; +#X connect 21 0 54 0; +#X connect 23 0 54 7; +#X connect 27 0 34 0; +#X connect 28 0 35 0; +#X connect 29 0 28 0; +#X connect 30 0 35 0; +#X connect 31 0 30 0; +#X connect 32 0 31 0; +#X connect 33 0 34 0; +#X connect 34 0 35 0; +#X connect 35 0 54 1; +#X connect 38 0 40 0; +#X connect 39 0 42 0; +#X connect 40 0 39 0; +#X connect 42 0 41 0; +#X connect 43 0 54 0; +#X connect 44 0 43 0; +#X connect 45 0 43 2; +#X connect 46 0 43 3; +#X connect 47 0 54 0; +#X connect 48 0 47 0; +#X connect 49 0 54 1; +#X connect 50 0 49 0; +#X connect 51 0 50 0; +#X connect 52 0 50 0; +#X connect 54 0 0 0; +#X connect 55 0 43 0; +#X connect 56 0 55 0; +#X connect 57 0 56 0; +#X connect 58 0 56 0; +#X connect 59 0 55 0; +#X connect 61 0 56 1; +#X connect 62 0 63 0; +#X connect 63 0 54 0; +#X connect 64 0 54 0; +#X connect 64 0 21 0; +#X connect 68 0 0 0; +#X connect 69 0 68 0; diff --git a/doc/help_pdp_ctrack.pd b/doc/help_pdp_ctrack.pd new file mode 100644 index 0000000..c57a6d9 --- /dev/null +++ b/doc/help_pdp_ctrack.pd @@ -0,0 +1,128 @@ +#N canvas 42 26 781 666 10; +#X obj 35 493 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 1 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0 0 - - -; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X obj 252 167 pdp_yqt; +#X obj 26 263 pdp_v4l; +#X obj 35 232 metro 70; +#X obj 80 198 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 37 199 stop; +#X msg 122 230 open /dev/video; +#X floatatom 244 273 5 0 0 0 - - -; +#X floatatom 253 294 5 0 0 0 - - -; +#X floatatom 270 315 5 0 0 0 - - -; +#X floatatom 275 337 5 0 0 0 - - -; +#X floatatom 164 496 5 0 0 0 - - -; +#X floatatom 210 496 5 0 0 0 - - -; +#X text 294 592 written by Yves Degoyon ( ydegoyon@free.fr ); +#X text 295 575 pdp_ctrack : color tracker; +#X floatatom 123 516 5 0 0 0 - - -; +#X floatatom 123 537 5 0 0 0 - - -; +#X text 290 273 R component; +#X text 298 293 G component; +#X text 315 314 B component; +#X floatatom 284 362 5 0 0 0 - - -; +#X text 323 336 X coordinate of cursor ( pick ); +#X text 332 361 Y coordinate of cursor ( pick ); +#X msg 89 341 pick; +#X text 57 323 Pick up the color; +#X floatatom 297 385 5 0 0 0 - - -; +#X text 343 384 Tolerance ( default = 50 ); +#X msg 312 411 luminosity \$1; +#X obj 413 413 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X text 436 414 Use luminosity in color detection; +#X obj 396 439 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X msg 320 438 steady \$1; +#X text 425 438 Steady mode ( zone is selected around the cursor ) +; +#X text 122 554 Coordinates of detected block; +#X obj 405 466 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X msg 329 465 cursor \$1; +#X text 428 467 Show cursor or not; +#X obj 421 490 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X text 444 491 Show frame or not; +#X msg 345 489 frame \$1; +#X obj 594 197 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 594 249 pdp_control; +#X msg 594 222 thread \$1; +#X floatatom 594 310 5 0 0 0 - - -; +#X obj 594 281 route pdp_drop; +#X msg 118 379 setcur \$1 \$2; +#X text 6 378 Set the cursor; +#X msg 12 527 cursor \$1; +#X obj 85 529 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X floatatom 123 591 5 0 0 0 - - -; +#X floatatom 173 592 5 0 0 0 - - -; +#X floatatom 220 591 5 0 0 0 - - -; +#X text 140 631 Color components; +#X text 135 609 R; +#X text 186 609 G; +#X text 230 609 B; +#X obj 110 459 pdp_ctrack ----; +#X connect 0 0 55 0; +#X connect 1 0 10 0; +#X connect 2 0 11 0; +#X connect 3 0 2 0; +#X connect 4 0 11 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 10 1; +#X connect 8 0 10 0; +#X connect 9 0 7 0; +#X connect 10 0 11 0; +#X connect 11 0 66 0; +#X connect 12 0 66 0; +#X connect 13 0 12 0; +#X connect 14 0 13 0; +#X connect 15 0 13 0; +#X connect 16 0 12 0; +#X connect 17 0 66 1; +#X connect 18 0 66 2; +#X connect 19 0 66 3; +#X connect 20 0 66 4; +#X connect 30 0 66 5; +#X connect 33 0 66 0; +#X connect 35 0 66 6; +#X connect 37 0 66 0; +#X connect 38 0 37 0; +#X connect 40 0 41 0; +#X connect 41 0 66 0; +#X connect 44 0 45 0; +#X connect 45 0 66 0; +#X connect 47 0 49 0; +#X connect 49 0 66 0; +#X connect 50 0 52 0; +#X connect 51 0 54 0; +#X connect 52 0 51 0; +#X connect 54 0 53 0; +#X connect 55 0 33 0; +#X connect 55 0 66 0; +#X connect 57 0 0 0; +#X connect 58 0 57 0; +#X connect 66 0 0 0; +#X connect 66 1 21 0; +#X connect 66 2 25 0; +#X connect 66 3 22 0; +#X connect 66 4 26 0; +#X connect 66 5 59 0; +#X connect 66 6 60 0; +#X connect 66 7 61 0; diff --git a/doc/help_pdp_cycle.pd b/doc/help_pdp_cycle.pd new file mode 100644 index 0000000..384d9e5 --- /dev/null +++ b/doc/help_pdp_cycle.pd @@ -0,0 +1,66 @@ +#N canvas 84 12 712 664 10; +#X obj 263 378 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 1 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X obj 346 203 pdp_v4l; +#X obj 355 172 metro 70; +#X obj 400 138 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 357 139 stop; +#X msg 442 170 open /dev/video; +#X obj 252 167 pdp_yqt; +#X obj 283 243 dac~; +#X obj 351 264 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 +1; +#X obj 363 286 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 +1; +#X obj 374 305 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 +1; +#X text 377 263 Cycle Y; +#X text 390 284 Cycle U; +#X text 396 306 Cycle V; +#X obj 264 334 pdp_cycle; +#X obj 469 381 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 +1; +#X obj 469 433 pdp_control; +#X msg 469 406 thread \$1; +#X floatatom 469 494 5 0 0; +#X obj 469 465 route pdp_drop; +#X connect 1 0 10 0; +#X connect 2 0 16 0; +#X connect 3 0 2 0; +#X connect 4 0 16 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 10 1; +#X connect 8 0 10 0; +#X connect 9 0 7 0; +#X connect 10 0 16 0; +#X connect 11 0 24 0; +#X connect 12 0 11 0; +#X connect 13 0 12 0; +#X connect 14 0 12 0; +#X connect 15 0 11 0; +#X connect 16 0 24 0; +#X connect 16 3 17 0; +#X connect 16 4 17 1; +#X connect 18 0 24 1; +#X connect 19 0 24 2; +#X connect 20 0 24 3; +#X connect 24 0 0 0; +#X connect 25 0 27 0; +#X connect 26 0 29 0; +#X connect 27 0 26 0; +#X connect 29 0 28 0; diff --git a/doc/help_pdp_dice.pd b/doc/help_pdp_dice.pd new file mode 100644 index 0000000..aaafe44 --- /dev/null +++ b/doc/help_pdp_dice.pd @@ -0,0 +1,57 @@ +#N canvas 84 12 712 664 10; +#X obj 263 378 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X obj 346 203 pdp_v4l; +#X obj 355 172 metro 70; +#X obj 400 138 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 357 139 stop; +#X msg 442 170 open /dev/video; +#X obj 252 167 pdp_yqt; +#X obj 283 243 dac~; +#X obj 264 334 pdp_dice; +#X obj 469 381 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 469 433 pdp_control; +#X msg 469 406 thread \$1; +#X floatatom 469 494 5 0 0; +#X obj 469 465 route pdp_drop; +#X floatatom 327 305 5 0 0; +#X text 328 281 Dice size; +#X connect 1 0 10 0; +#X connect 2 0 16 0; +#X connect 3 0 2 0; +#X connect 4 0 16 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 10 1; +#X connect 8 0 10 0; +#X connect 9 0 7 0; +#X connect 10 0 16 0; +#X connect 11 0 18 0; +#X connect 12 0 11 0; +#X connect 13 0 12 0; +#X connect 14 0 12 0; +#X connect 15 0 11 0; +#X connect 16 0 18 0; +#X connect 16 3 17 0; +#X connect 16 4 17 1; +#X connect 18 0 0 0; +#X connect 19 0 21 0; +#X connect 20 0 23 0; +#X connect 21 0 20 0; +#X connect 23 0 22 0; +#X connect 24 0 18 1; diff --git a/doc/help_pdp_edge.pd b/doc/help_pdp_edge.pd new file mode 100644 index 0000000..3738358 --- /dev/null +++ b/doc/help_pdp_edge.pd @@ -0,0 +1,54 @@ +#N canvas 237 21 712 664 10; +#X obj 248 367 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 283 243 dac~; +#X obj 257 135 metro 70; +#X obj 252 167 pdp_yqt; +#X obj 249 323 pdp_edge; +#X obj 421 166 pdp_v4l; +#X obj 430 135 metro 70; +#X obj 475 101 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 432 102 stop; +#X msg 517 133 open /dev/video; +#X obj 414 352 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 414 404 pdp_control; +#X msg 414 377 thread \$1; +#X floatatom 414 465 5 0 0; +#X obj 414 436 route pdp_drop; +#X connect 1 0 11 0; +#X connect 2 0 12 0; +#X connect 3 0 2 0; +#X connect 4 0 12 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 11 1; +#X connect 8 0 11 0; +#X connect 9 0 7 0; +#X connect 11 0 12 0; +#X connect 12 0 13 0; +#X connect 12 3 10 0; +#X connect 12 4 10 1; +#X connect 13 0 0 0; +#X connect 14 0 13 0; +#X connect 15 0 14 0; +#X connect 16 0 15 0; +#X connect 17 0 15 0; +#X connect 18 0 14 0; +#X connect 19 0 21 0; +#X connect 20 0 23 0; +#X connect 21 0 20 0; +#X connect 23 0 22 0; diff --git a/doc/help_pdp_effects_rack.pd b/doc/help_pdp_effects_rack.pd new file mode 100644 index 0000000..80e356a --- /dev/null +++ b/doc/help_pdp_effects_rack.pd @@ -0,0 +1,461 @@ +#N canvas 5 16 986 661 10; +#X obj 230 7 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 150 44 loop \$1; +#X obj 151 22 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 1 1 +; +#X msg 86 45 open \$1; +#X obj 78 21 openpanel; +#X obj 48 20 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 262 24 5 0 0 0 - - -; +#X msg 187 8 stop; +#X obj 211 44 metro 70; +#X obj 206 69 pdp_yqt; +#X obj 375 71 pdp_v4l; +#X obj 374 41 metro 70; +#X obj 419 7 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 376 8 stop; +#X msg 441 41 open /dev/video; +#X obj 130 99 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X obj 48 111 pdp_spigot; +#X text 7 20 Load; +#X text 436 7 Live; +#X obj 272 101 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 190 113 pdp_spigot; +#X floatatom 46 167 5 0 0 0 - - -; +#X floatatom 93 168 5 0 0 0 - - -; +#X obj 46 141 pdp_aging; +#X obj 190 140 pdp_baltan; +#X floatatom 189 164 10 0 0 0 - - -; +#X obj 403 102 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 321 114 pdp_spigot; +#X obj 320 141 pdp_edge; +#X obj 518 104 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 436 116 pdp_spigot; +#X msg 436 165 bang; +#X floatatom 476 166 5 0 0 0 - - -; +#X obj 436 141 pdp_intrusion; +#X obj 648 106 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 566 118 pdp_spigot; +#X obj 566 144 pdp_lens; +#X floatatom 561 173 5 0 0 0 - - -; +#X floatatom 609 173 5 0 0 0 - - -; +#X floatatom 561 189 5 0 0 0 - - -; +#X floatatom 608 190 5 0 0 0 - - -; +#X obj 658 188 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 778 105 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 696 117 pdp_spigot; +#X msg 697 164 bang; +#X obj 697 142 pdp_mosaic; +#X floatatom 740 166 5 0 0 0 - - -; +#X obj 863 204 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 781 216 pdp_spigot; +#X obj 782 241 pdp_nervous; +#X obj 784 267 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 659 209 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 577 221 pdp_spigot; +#X obj 578 247 pdp_quark; +#X obj 531 207 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 449 219 pdp_spigot; +#X floatatom 450 290 5 0 0 0 - - -; +#X obj 449 245 pdp_radioactiv; +#X obj 449 270 hdl 15 1 0 4 empty empty empty 0 -6 0 8 -262144 -1 -1 +0; +#X floatatom 500 289 5 0 0 0 - - -; +#X obj 413 208 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 331 220 pdp_spigot; +#X floatatom 329 267 5 0 0 0 - - -; +#X floatatom 375 267 5 0 0 0 - - -; +#X floatatom 329 284 5 0 0 0 - - -; +#X floatatom 375 286 5 0 0 0 - - -; +#X obj 331 245 pdp_rev; +#X obj 285 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 203 217 pdp_spigot; +#X msg 218 270 bang; +#X obj 199 272 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 202 247 pdp_ripple; +#X floatatom 198 292 5 0 0 0 - - -; +#X floatatom 242 291 5 0 0 0 - - -; +#X obj 147 201 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 65 213 pdp_spigot; +#X obj 65 240 pdp_simura; +#X floatatom 62 283 5 0 0 0 - - -; +#X obj 48 263 hdl 15 1 0 9 empty empty empty 0 -6 0 8 -262144 -1 -1 +0; +#X obj 126 310 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 44 322 pdp_spigot; +#X floatatom 44 387 5 0 0 0 - - -; +#X obj 44 366 hdl 15 1 0 8 empty empty empty 0 -6 0 8 -262144 -1 -1 +0; +#X floatatom 91 386 5 0 0 0 - - -; +#X floatatom 139 386 5 0 0 0 - - -; +#X floatatom 45 407 5 0 0 0 - - -; +#X floatatom 93 406 5 0 0 0 - - -; +#X obj 141 405 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 162 405 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 44 346 pdp_spiral; +#X obj 284 309 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 202 321 pdp_spigot; +#X floatatom 201 367 5 0 0 0 - - -; +#X obj 201 343 pdp_underwatch; +#X obj 422 309 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 340 321 pdp_spigot; +#X obj 562 310 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 480 322 pdp_spigot; +#X obj 696 312 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 617 323 pdp_spigot; +#X obj 339 342 pdp_vertigo; +#X floatatom 338 365 5 0 0 0 - - -; +#X floatatom 381 365 5 0 0 0 - - -; +#X floatatom 480 369 5 0 0 0 - - -; +#X obj 480 346 pdp_warhol; +#X floatatom 530 369 5 0 0 0 - - -; +#X obj 480 388 hdl 15 1 0 9 empty empty empty 0 -6 0 8 -262144 -1 -1 +0; +#X floatatom 481 407 5 0 0 0 - - -; +#X floatatom 527 407 5 0 0 0 - - -; +#X floatatom 572 407 5 0 0 0 - - -; +#X obj 618 365 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X floatatom 638 366 5 0 0 0 - - -; +#X obj 618 345 pdp_warp; +#X obj 811 315 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 732 326 pdp_spigot; +#X floatatom 482 7 5 0 0 0 - - -; +#X floatatom 474 596 5 0 0 0 - - -; +#X msg 567 520 open /tmp/output.mov; +#X msg 568 543 start; +#X msg 567 565 stop; +#X obj 286 642 pdp_xv; +#X msg 202 641 cursor \$1; +#X obj 214 620 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 19 544 pdp_zoom; +#X floatatom 68 500 5 0 0 0 - - -; +#X obj 152 436 hsl 300 15 0.01 100 1 1 empty empty empty -2 -6 0 8 +-262144 -1 -1 15004 1; +#X floatatom 122 547 5 0 0 0 - - -; +#X obj 146 487 hsl 300 15 0.01 100 1 1 empty empty empty -2 -6 0 8 +-262144 -1 -1 14200 1; +#X msg 165 522 zoomx \$1; +#X msg 164 548 zoomy \$1; +#X floatatom 124 523 5 0 0 0 - - -; +#X obj 150 460 hsl 300 15 0.01 100 1 1 empty empty empty -2 -6 0 8 +-262144 -1 -1 14800 1; +#X msg 278 588 centerx \$1; +#X floatatom 281 562 5 0 0 0 - - -; +#X floatatom 363 560 5 0 0 0 - - -; +#X msg 360 586 centery \$1; +#X obj 289 508 hsl 128 15 -1 1 0 1 empty empty empty -2 -6 0 8 -262144 +-1 -1 6900 1; +#X obj 307 527 hsl 128 15 -1 1 0 1 empty empty empty -2 -6 0 8 -262144 +-1 -1 7300 1; +#X msg 17 453 center 0 0; +#X obj 731 350 pdp_cycle; +#X obj 729 373 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 758 374 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 783 374 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 917 315 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 838 326 pdp_spigot; +#X obj 837 350 pdp_transform; +#X obj 838 375 hdl 15 1 0 6 empty empty empty 0 -6 0 8 -262144 -1 -1 +0; +#X obj 970 207 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 891 218 pdp_spigot; +#X obj 890 242 pdp_shagadelic; +#X floatatom 892 266 5 0 0 0 - - -; +#X obj 941 266 * 100; +#X obj 896 106 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 817 117 pdp_spigot; +#X floatatom 818 165 5 0 0 0 - - -; +#X obj 816 141 pdp_dice; +#X obj 889 403 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 810 414 pdp_spigot; +#X floatatom 883 441 5 0 0 0 - - -; +#X obj 809 438 pdp_puzzle; +#X msg 813 464 up; +#X msg 845 464 down; +#X msg 885 464 left; +#X msg 925 464 right; +#X obj 848 492 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 848 544 pdp_control; +#X msg 848 517 thread \$1; +#X floatatom 848 605 5 0 0 0 - - -; +#X obj 848 576 route pdp_drop; +#X msg 568 588 framerate 10; +#X obj 225 88 dac~; +#X floatatom 312 21 5 0 0 0 - - -; +#X obj 740 404 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 661 415 pdp_spigot; +#X obj 660 439 pdp_ascii; +#X floatatom 730 439 5 0 0 0 - - -; +#X floatatom 580 272 5 0 0 0 - - -; +#X floatatom 829 266 5 0 0 0 - - -; +#X obj 313 44 t b f; +#X obj 490 524 adc~; +#X obj 760 211 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 678 223 pdp_spigot; +#X floatatom 726 273 5 0 0 0 - - -; +#X obj 679 248 pdp_noquark; +#X floatatom 678 272 5 0 0 0 - - -; +#X floatatom 625 272 5 0 0 0 - - -; +#X obj 284 617 pdp_affine; +#X floatatom 372 616 5 0 0 0 - - -; +#X floatatom 422 616 5 0 0 0 - - -; +#X msg 487 625 display 81.66.163.16:0; +#X obj 474 568 pdp_rec~; +#X obj 321 686 pdp_ffmpeg~; +#X msg 20 693 feed http://localhost:8090/feed1.ffm; +#X msg 421 687 starve; +#X connect 0 0 8 0; +#X connect 1 0 9 0; +#X connect 2 0 1 0; +#X connect 3 0 9 0; +#X connect 4 0 3 0; +#X connect 5 0 4 0; +#X connect 6 0 8 1; +#X connect 7 0 8 0; +#X connect 8 0 9 0; +#X connect 9 0 16 0; +#X connect 9 3 170 0; +#X connect 9 4 170 1; +#X connect 10 0 16 0; +#X connect 11 0 10 0; +#X connect 12 0 11 0; +#X connect 13 0 11 0; +#X connect 14 0 10 0; +#X connect 15 0 16 1; +#X connect 16 0 20 0; +#X connect 16 1 23 0; +#X connect 19 0 20 1; +#X connect 20 0 27 0; +#X connect 20 1 24 0; +#X connect 21 0 23 1; +#X connect 22 0 23 2; +#X connect 23 0 20 0; +#X connect 24 0 27 0; +#X connect 25 0 24 1; +#X connect 26 0 27 1; +#X connect 27 0 30 0; +#X connect 27 1 28 0; +#X connect 28 0 30 0; +#X connect 29 0 30 1; +#X connect 30 0 35 0; +#X connect 30 1 33 0; +#X connect 31 0 33 1; +#X connect 32 0 33 2; +#X connect 33 0 35 0; +#X connect 34 0 35 1; +#X connect 35 0 43 0; +#X connect 35 1 36 0; +#X connect 36 0 43 0; +#X connect 37 0 36 1; +#X connect 38 0 36 2; +#X connect 39 0 36 3; +#X connect 40 0 36 4; +#X connect 41 0 36 5; +#X connect 42 0 43 1; +#X connect 43 0 153 0; +#X connect 43 1 45 0; +#X connect 44 0 45 1; +#X connect 45 0 153 0; +#X connect 46 0 45 2; +#X connect 47 0 48 1; +#X connect 48 0 181 0; +#X connect 48 1 49 0; +#X connect 49 0 181 0; +#X connect 50 0 49 1; +#X connect 51 0 52 1; +#X connect 52 0 55 0; +#X connect 52 1 53 0; +#X connect 53 0 55 0; +#X connect 54 0 55 1; +#X connect 55 0 61 0; +#X connect 55 1 57 0; +#X connect 56 0 57 2; +#X connect 57 0 61 0; +#X connect 58 0 57 1; +#X connect 59 0 57 3; +#X connect 60 0 61 1; +#X connect 61 0 68 0; +#X connect 61 1 66 0; +#X connect 62 0 66 1; +#X connect 63 0 66 2; +#X connect 64 0 66 3; +#X connect 65 0 66 4; +#X connect 66 0 68 0; +#X connect 67 0 68 1; +#X connect 68 0 75 0; +#X connect 68 1 71 0; +#X connect 69 0 71 2; +#X connect 70 0 71 1; +#X connect 71 0 75 0; +#X connect 72 0 71 3; +#X connect 73 0 71 4; +#X connect 74 0 75 1; +#X connect 75 0 80 0; +#X connect 75 1 76 0; +#X connect 76 0 80 0; +#X connect 77 0 76 1; +#X connect 78 0 76 2; +#X connect 79 0 80 1; +#X connect 80 0 91 0; +#X connect 80 1 89 0; +#X connect 81 0 89 2; +#X connect 82 0 89 1; +#X connect 83 0 89 3; +#X connect 84 0 89 4; +#X connect 85 0 89 5; +#X connect 86 0 89 6; +#X connect 87 0 89 7; +#X connect 88 0 89 8; +#X connect 89 0 91 0; +#X connect 90 0 91 1; +#X connect 91 0 95 0; +#X connect 91 1 93 0; +#X connect 92 0 93 1; +#X connect 93 0 95 0; +#X connect 94 0 95 1; +#X connect 95 0 97 0; +#X connect 95 1 100 0; +#X connect 96 0 97 1; +#X connect 97 0 99 0; +#X connect 97 1 104 0; +#X connect 98 0 99 1; +#X connect 99 0 114 0; +#X connect 99 1 112 0; +#X connect 100 0 97 0; +#X connect 101 0 100 1; +#X connect 102 0 100 2; +#X connect 103 0 104 1; +#X connect 104 0 99 0; +#X connect 105 0 104 2; +#X connect 106 0 104 3; +#X connect 107 0 104 4; +#X connect 108 0 104 5; +#X connect 109 0 104 6; +#X connect 110 0 112 1; +#X connect 111 0 112 2; +#X connect 112 0 114 0; +#X connect 113 0 114 1; +#X connect 114 0 144 0; +#X connect 114 1 139 0; +#X connect 115 0 11 1; +#X connect 117 0 190 0; +#X connect 118 0 190 0; +#X connect 119 0 190 0; +#X connect 121 0 120 0; +#X connect 122 0 121 0; +#X connect 123 0 186 0; +#X connect 124 0 123 1; +#X connect 125 0 124 0; +#X connect 126 0 129 0; +#X connect 127 0 126 0; +#X connect 128 0 123 0; +#X connect 129 0 123 0; +#X connect 130 0 128 0; +#X connect 131 0 130 0; +#X connect 132 0 123 0; +#X connect 133 0 132 0; +#X connect 134 0 135 0; +#X connect 135 0 123 0; +#X connect 136 0 133 0; +#X connect 137 0 134 0; +#X connect 138 0 123 0; +#X connect 139 0 144 0; +#X connect 140 0 139 1; +#X connect 141 0 139 2; +#X connect 142 0 139 3; +#X connect 143 0 144 1; +#X connect 144 0 157 0; +#X connect 144 1 145 0; +#X connect 145 0 157 0; +#X connect 146 0 145 1; +#X connect 147 0 148 1; +#X connect 148 0 48 0; +#X connect 148 1 149 0; +#X connect 149 0 48 0; +#X connect 150 0 151 0; +#X connect 151 0 149 1; +#X connect 152 0 153 1; +#X connect 153 0 148 0; +#X connect 153 1 155 0; +#X connect 154 0 155 1; +#X connect 155 0 148 0; +#X connect 156 0 157 1; +#X connect 157 0 173 0; +#X connect 157 1 159 0; +#X connect 158 0 159 1; +#X connect 159 0 173 0; +#X connect 160 0 159 0; +#X connect 161 0 159 0; +#X connect 162 0 159 0; +#X connect 163 0 159 0; +#X connect 164 0 166 0; +#X connect 165 0 168 0; +#X connect 166 0 165 0; +#X connect 168 0 167 0; +#X connect 169 0 190 0; +#X connect 171 0 178 0; +#X connect 172 0 173 1; +#X connect 173 0 123 0; +#X connect 173 1 174 0; +#X connect 174 0 123 0; +#X connect 175 0 174 1; +#X connect 176 0 53 1; +#X connect 177 0 49 2; +#X connect 178 0 9 0; +#X connect 178 1 9 1; +#X connect 179 0 190 0; +#X connect 179 1 190 1; +#X connect 180 0 181 1; +#X connect 181 0 52 0; +#X connect 181 1 183 0; +#X connect 182 0 183 2; +#X connect 183 0 52 0; +#X connect 184 0 183 1; +#X connect 185 0 53 2; +#X connect 186 0 120 0; +#X connect 186 0 190 0; +#X connect 186 0 191 0; +#X connect 187 0 186 1; +#X connect 188 0 186 2; +#X connect 189 0 120 0; +#X connect 190 0 116 0; +#X connect 192 0 191 0; +#X connect 193 0 191 0; diff --git a/doc/help_pdp_ffmpeg~.pd b/doc/help_pdp_ffmpeg~.pd new file mode 100644 index 0000000..86710c0 --- /dev/null +++ b/doc/help_pdp_ffmpeg~.pd @@ -0,0 +1,79 @@ +#N canvas 84 12 763 664 10; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X obj 322 276 pdp_v4l; +#X obj 331 245 metro 70; +#X obj 376 211 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 333 212 stop; +#X msg 418 243 open /dev/video; +#X obj 252 167 pdp_yqt; +#X obj 606 530 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 606 582 pdp_control; +#X msg 606 555 thread \$1; +#X floatatom 606 643 5 0 0; +#X obj 606 614 route pdp_drop; +#X text 82 562 written by Yves Degoyon (ydegoyon@free.fr); +#X text 579 359 Set and open the feed; +#X msg 316 359 feed http://localhost:8090/feed1.ffm; +#X floatatom 193 439 5 0 0; +#X text 241 440 Streaming status; +#X floatatom 229 462 5 0 0; +#X text 272 462 Number of video frames emitted; +#X text 319 320 BEWARE : All the stream parameters must be set in ffserver +configuration file.; +#X msg 318 387 starve; +#X text 377 389 Close the current feed; +#X floatatom 267 482 5 0 0; +#X text 311 483 Number of video frames dropped; +#X obj 96 269 adc~; +#X text 79 624 PDP cannot guarantee that the audio will be sent on +time; +#X text 78 598 NOTE : although there is an experimental audio support +here \,; +#X text 78 611 you'd better stream with mp3cast~ because; +#X obj 193 413 pdp_ffmpeg~; +#X text 81 547 pdp_ffmeg~ : streams video & audio towards an ffmpeg +server; +#X connect 0 0 9 0; +#X connect 1 0 15 0; +#X connect 2 0 1 0; +#X connect 3 0 15 0; +#X connect 4 0 3 0; +#X connect 5 0 4 0; +#X connect 6 0 9 1; +#X connect 7 0 9 0; +#X connect 8 0 6 0; +#X connect 9 0 15 0; +#X connect 10 0 37 0; +#X connect 11 0 10 0; +#X connect 12 0 11 0; +#X connect 13 0 11 0; +#X connect 14 0 10 0; +#X connect 15 0 37 0; +#X connect 15 3 37 0; +#X connect 15 4 37 1; +#X connect 16 0 18 0; +#X connect 17 0 20 0; +#X connect 18 0 17 0; +#X connect 20 0 19 0; +#X connect 23 0 37 0; +#X connect 29 0 37 0; +#X connect 33 0 37 0; +#X connect 33 1 37 1; +#X connect 37 0 24 0; +#X connect 37 1 26 0; +#X connect 37 2 31 0; diff --git a/doc/help_pdp_form.pd b/doc/help_pdp_form.pd new file mode 100644 index 0000000..8fd8871 --- /dev/null +++ b/doc/help_pdp_form.pd @@ -0,0 +1,96 @@ +#N canvas 84 12 763 664 10; +#X obj 92 608 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0 0 - - -; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X obj 346 203 pdp_v4l; +#X obj 355 172 metro 70; +#X obj 400 138 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 357 139 stop; +#X msg 442 170 open /dev/video; +#X obj 252 167 pdp_yqt; +#X obj 606 530 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 606 582 pdp_control; +#X msg 606 555 thread \$1; +#X floatatom 606 643 5 0 0 0 - - -; +#X obj 606 614 route pdp_drop; +#X text 222 631 written by Yves Degoyon (ydegoyon@free.fr); +#X obj 189 362 hdl 15 1 0 10 empty empty empty 0 -6 0 8 -262144 -1 +-1 0; +#X floatatom 207 388 5 0 0 0 - - -; +#X floatatom 223 412 5 0 0 0 - - -; +#X floatatom 266 479 5 0 0 0 - - -; +#X floatatom 284 499 5 0 0 0 - - -; +#X floatatom 304 519 5 0 0 0 - - -; +#X text 314 478 R component; +#X text 332 498 G component; +#X text 352 518 B component; +#X msg 29 352 clear; +#X msg 30 387 delete 1; +#X msg 30 421 resize 20; +#X text 222 619 this is useful for video composition; +#X text 349 361 Select current form ( 10 items by default ); +#X text 252 387 X1 coordinate; +#X text 271 411 Y1 coordinate; +#X floatatom 236 434 5 0 0 0 - - -; +#X floatatom 244 456 5 0 0 0 - - -; +#X text 284 282 Add a line; +#X text 388 333 Add an ellipse; +#X msg 144 282 line 24 56 134 200; +#X text 377 305 Add a rectangle ( but in red ); +#X text 281 433 X2 coordinate or ray for ellipse; +#X text 292 455 Y2 coordinate or ray for ellipse; +#X text 143 261 line|rectangle|ellipse x1 y1 x2|r y2|r [ r g b angle +]; +#X msg 163 304 rectangle 56 45 123 78 255 0 0; +#X msg 179 333 ellipse 89 120 56 78 0 255 0; +#X text 222 605 pdp_form : geometric forms addition in PDP; +#X obj 144 562 pdp_form -----------------; +#X connect 1 0 10 0; +#X connect 2 0 16 0; +#X connect 3 0 2 0; +#X connect 4 0 16 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 10 1; +#X connect 8 0 10 0; +#X connect 9 0 7 0; +#X connect 10 0 16 0; +#X connect 11 0 51 0; +#X connect 12 0 11 0; +#X connect 13 0 12 0; +#X connect 14 0 12 0; +#X connect 15 0 11 0; +#X connect 16 0 51 0; +#X connect 17 0 19 0; +#X connect 18 0 21 0; +#X connect 19 0 18 0; +#X connect 21 0 20 0; +#X connect 23 0 51 1; +#X connect 24 0 51 2; +#X connect 25 0 51 3; +#X connect 26 0 51 6; +#X connect 27 0 51 7; +#X connect 28 0 51 8; +#X connect 32 0 51 0; +#X connect 33 0 51 0; +#X connect 34 0 51 0; +#X connect 39 0 51 4; +#X connect 40 0 51 5; +#X connect 43 0 51 0; +#X connect 48 0 51 0; +#X connect 49 0 51 0; +#X connect 51 0 0 0; diff --git a/doc/help_pdp_imgloader.pd b/doc/help_pdp_imgloader.pd new file mode 100644 index 0000000..0817af1 --- /dev/null +++ b/doc/help_pdp_imgloader.pd @@ -0,0 +1,70 @@ +#N canvas 518 15 712 664 10; +#X obj 375 116 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 221 148 loop \$1; +#X obj 222 126 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 1 +1; +#X msg 249 95 open \$1; +#X obj 248 71 openpanel; +#X obj 249 45 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 338 114 stop; +#X obj 355 147 metro 70; +#X obj 488 158 pdp_v4l; +#X obj 497 127 metro 70; +#X obj 542 93 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 499 94 stop; +#X msg 584 125 open /dev/video; +#X obj 350 179 pdp_yqt; +#X obj 469 381 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 469 433 pdp_control; +#X msg 469 406 thread \$1; +#X floatatom 469 494 5 0 0 0 - - -; +#X obj 469 465 route pdp_drop; +#X floatatom 289 321 5 0 0 0 - - -; +#X text 289 303 X Offset; +#X floatatom 347 321 5 0 0 0 - - -; +#X text 347 303 Y Offset; +#X obj 64 301 openpanel; +#X obj 64 274 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X text 78 482 pdp_imgloader : load an image and blend it with a video +; +#X text 78 498 written by Yves Degoyon ( ydegoyon@free.fr ); +#X obj 198 397 pdp_xv; +#X msg 66 363 clear; +#X msg 64 325 load \$1 64 32; +#X text 27 241 load <name> <x offset> <y offset>; +#X text 28 228 Load an image ( types supported by imlib2 ); +#X obj 198 354 pdp_imgloader; +#X obj 413 321 hsl 128 15 0 1 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X text 412 304 Blending factor; +#X connect 0 0 7 0; +#X connect 1 0 13 0; +#X connect 2 0 1 0; +#X connect 3 0 13 0; +#X connect 4 0 3 0; +#X connect 5 0 4 0; +#X connect 6 0 7 0; +#X connect 7 0 13 0; +#X connect 8 0 32 0; +#X connect 9 0 8 0; +#X connect 10 0 9 0; +#X connect 11 0 9 0; +#X connect 12 0 8 0; +#X connect 13 0 32 0; +#X connect 14 0 16 0; +#X connect 15 0 18 0; +#X connect 16 0 15 0; +#X connect 18 0 17 0; +#X connect 19 0 32 1; +#X connect 21 0 32 2; +#X connect 23 0 29 0; +#X connect 24 0 23 0; +#X connect 28 0 32 0; +#X connect 29 0 32 0; +#X connect 32 0 27 0; +#X connect 33 0 32 3; diff --git a/doc/help_pdp_imgsaver.pd b/doc/help_pdp_imgsaver.pd new file mode 100644 index 0000000..0a58f22 --- /dev/null +++ b/doc/help_pdp_imgsaver.pd @@ -0,0 +1,54 @@ +#N canvas 518 15 712 664 10; +#X obj 375 116 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 221 148 loop \$1; +#X obj 222 126 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 1 +1; +#X msg 249 95 open \$1; +#X obj 248 71 openpanel; +#X obj 249 45 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 338 114 stop; +#X obj 355 147 metro 70; +#X obj 488 158 pdp_v4l; +#X obj 497 127 metro 70; +#X obj 542 93 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 499 94 stop; +#X msg 584 125 open /dev/video; +#X obj 350 179 pdp_yqt; +#X obj 469 381 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 469 433 pdp_control; +#X msg 469 406 thread \$1; +#X floatatom 469 494 5 0 0 0 - - -; +#X obj 469 465 route pdp_drop; +#X text 77 511 written by Yves Degoyon ( ydegoyon@free.fr ); +#X obj 198 397 pdp_xv; +#X text 28 228 Save a snapshot of the current frame; +#X text 78 482 pdp_imgsaver : save a snapshot as an image; +#X msg 48 300 save /tmp/capture.jpg; +#X text 27 241 save <name>; +#X text 77 497 The image type is determined by extension; +#X obj 198 354 pdp_imgsaver; +#X text 28 255 With my imlib2 \, only jpg works !!; +#X connect 0 0 7 0; +#X connect 1 0 13 0; +#X connect 2 0 1 0; +#X connect 3 0 13 0; +#X connect 4 0 3 0; +#X connect 5 0 4 0; +#X connect 6 0 7 0; +#X connect 7 0 13 0; +#X connect 8 0 26 0; +#X connect 9 0 8 0; +#X connect 10 0 9 0; +#X connect 11 0 9 0; +#X connect 12 0 8 0; +#X connect 13 0 26 0; +#X connect 14 0 16 0; +#X connect 15 0 18 0; +#X connect 16 0 15 0; +#X connect 18 0 17 0; +#X connect 23 0 26 0; +#X connect 26 0 20 0; diff --git a/doc/help_pdp_intrusion.pd b/doc/help_pdp_intrusion.pd new file mode 100644 index 0000000..cd0291b --- /dev/null +++ b/doc/help_pdp_intrusion.pd @@ -0,0 +1,63 @@ +#N canvas 237 21 712 664 10; +#X obj 218 367 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X msg 322 263 bang; +#X obj 366 241 metro 100; +#X msg 349 208 bang; +#X msg 395 210 stop; +#X floatatom 330 300 5 0 0; +#X text 380 299 Threshold [0 \, 255 ] default 10; +#X obj 217 299 pdp_intrusion; +#X text 363 263 Set background to start comparing; +#X obj 252 167 pdp_yqt; +#X obj 491 157 pdp_v4l; +#X obj 500 126 metro 70; +#X obj 545 92 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 502 93 stop; +#X msg 587 124 open /dev/video; +#X obj 414 352 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 414 404 pdp_control; +#X msg 414 377 thread \$1; +#X floatatom 414 465 5 0 0; +#X obj 414 436 route pdp_drop; +#X connect 1 0 10 0; +#X connect 2 0 19 0; +#X connect 3 0 2 0; +#X connect 4 0 19 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 10 1; +#X connect 8 0 10 0; +#X connect 9 0 7 0; +#X connect 10 0 19 0; +#X connect 11 0 17 1; +#X connect 12 0 11 0; +#X connect 13 0 12 0; +#X connect 14 0 12 0; +#X connect 15 0 17 2; +#X connect 17 0 0 0; +#X connect 19 0 17 0; +#X connect 20 0 17 0; +#X connect 21 0 20 0; +#X connect 22 0 21 0; +#X connect 23 0 21 0; +#X connect 24 0 20 0; +#X connect 25 0 27 0; +#X connect 26 0 29 0; +#X connect 27 0 26 0; +#X connect 29 0 28 0; diff --git a/doc/help_pdp_juxta.pd b/doc/help_pdp_juxta.pd new file mode 100644 index 0000000..cb685ee --- /dev/null +++ b/doc/help_pdp_juxta.pd @@ -0,0 +1,122 @@ +#N canvas 121 -18 828 668 10; +#X obj 370 477 pdp_xv; +#X obj 227 97 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 46 138 open \$1; +#X obj 45 114 openpanel; +#X obj 30 97 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 184 98 stop; +#X obj 187 135 metro 70; +#X obj 124 175 pdp_yqt; +#X obj 251 168 pdp_v4l; +#X obj 260 137 metro 70; +#X obj 305 103 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 262 104 stop; +#X obj 566 513 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 566 565 pdp_control; +#X msg 566 538 thread \$1; +#X floatatom 566 626 5 0 0 0 - - -; +#X obj 566 597 route pdp_drop; +#X obj 217 299 pdp_juxta; +#X obj 556 97 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 452 136 loop \$1; +#X obj 453 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 375 138 open \$1; +#X obj 374 114 openpanel; +#X obj 359 97 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 513 98 stop; +#X obj 516 135 metro 70; +#X obj 453 175 pdp_yqt; +#X obj 580 168 pdp_v4l; +#X obj 589 137 metro 70; +#X obj 634 103 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 591 104 stop; +#X text 35 604 written by Yves Degoyon ( ydegoyon@free.fr ); +#X text 35 618 idea suggested by liz; +#X text 34 589 pdp_juxta : frames juxtaposition; +#X obj 370 442 pdp_scale 320 240; +#X obj 566 275 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 462 314 loop \$1; +#X obj 463 292 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 385 316 open \$1; +#X obj 384 292 openpanel; +#X obj 369 275 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 523 276 stop; +#X obj 526 313 metro 70; +#X obj 463 353 pdp_yqt; +#X obj 590 346 pdp_v4l; +#X obj 599 315 metro 70; +#X obj 644 281 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 601 282 stop; +#X obj 370 408 pdp_juxta; +#X msg 671 123 connect \$1; +#X obj 671 52 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 671 74 openpanel; +#X obj 672 167 pdp_live~; +#X obj 671 98 makefilename file://%s; +#X connect 1 0 8 0; +#X connect 2 0 9 0; +#X connect 3 0 2 0; +#X connect 4 0 9 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 8 0; +#X connect 8 0 9 0; +#X connect 9 0 19 0; +#X connect 10 0 19 0; +#X connect 11 0 10 0; +#X connect 12 0 11 0; +#X connect 13 0 11 0; +#X connect 14 0 16 0; +#X connect 15 0 18 0; +#X connect 16 0 15 0; +#X connect 18 0 17 0; +#X connect 19 0 50 0; +#X connect 20 0 27 0; +#X connect 21 0 28 0; +#X connect 22 0 21 0; +#X connect 23 0 28 0; +#X connect 24 0 23 0; +#X connect 25 0 24 0; +#X connect 26 0 27 0; +#X connect 27 0 28 0; +#X connect 28 0 19 1; +#X connect 29 0 19 1; +#X connect 30 0 29 0; +#X connect 31 0 30 0; +#X connect 32 0 30 0; +#X connect 36 0 0 0; +#X connect 37 0 44 0; +#X connect 38 0 45 0; +#X connect 39 0 38 0; +#X connect 40 0 45 0; +#X connect 41 0 40 0; +#X connect 42 0 41 0; +#X connect 43 0 44 0; +#X connect 44 0 45 0; +#X connect 45 0 50 1; +#X connect 46 0 50 1; +#X connect 47 0 46 0; +#X connect 48 0 47 0; +#X connect 49 0 47 0; +#X connect 50 0 36 0; +#X connect 51 0 54 0; +#X connect 52 0 53 0; +#X connect 53 0 55 0; +#X connect 54 0 19 1; +#X connect 55 0 51 0; diff --git a/doc/help_pdp_lens.pd b/doc/help_pdp_lens.pd new file mode 100644 index 0000000..c99f126 --- /dev/null +++ b/doc/help_pdp_lens.pd @@ -0,0 +1,67 @@ +#N canvas 237 21 712 664 10; +#X obj 218 367 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X obj 217 299 pdp_lens; +#X floatatom 301 207 5 0 0; +#X floatatom 315 229 5 0 0; +#X text 347 205 X coordinate of lens upper left corner; +#X text 358 229 Y coordinate of lens upper left corner; +#X floatatom 328 250 5 0 0; +#X text 375 250 Lens size; +#X floatatom 344 268 5 0 0; +#X text 391 268 Zoom factor; +#X obj 355 297 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X text 378 296 Mode ( 0=static 1=inspecting ); +#X obj 252 167 pdp_yqt; +#X obj 421 166 pdp_v4l; +#X obj 430 135 metro 70; +#X obj 475 101 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 432 102 stop; +#X msg 517 133 open /dev/video; +#X obj 414 352 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 414 404 pdp_control; +#X msg 414 377 thread \$1; +#X floatatom 414 465 5 0 0; +#X obj 414 436 route pdp_drop; +#X connect 1 0 10 0; +#X connect 2 0 22 0; +#X connect 3 0 2 0; +#X connect 4 0 22 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 10 1; +#X connect 8 0 10 0; +#X connect 9 0 7 0; +#X connect 10 0 22 0; +#X connect 11 0 0 0; +#X connect 12 0 11 1; +#X connect 13 0 11 2; +#X connect 16 0 11 3; +#X connect 18 0 11 4; +#X connect 20 0 11 5; +#X connect 22 0 11 0; +#X connect 23 0 11 0; +#X connect 24 0 23 0; +#X connect 25 0 24 0; +#X connect 26 0 24 0; +#X connect 27 0 23 0; +#X connect 28 0 30 0; +#X connect 29 0 32 0; +#X connect 30 0 29 0; +#X connect 32 0 31 0; diff --git a/doc/help_pdp_live~.pd b/doc/help_pdp_live~.pd new file mode 100644 index 0000000..a12f862 --- /dev/null +++ b/doc/help_pdp_live~.pd @@ -0,0 +1,15 @@ +#N canvas 259 178 509 391 10; +#X obj 128 113 rs_pdp_live~; +#X obj 156 158 dac~; +#X text 51 321 written by Yves Degoyon (ydegoyon@free.fr); +#X text 51 308 ( at least from ffserver ); +#X text 51 295 pdp_live~ : decodes a live video stream; +#X text 236 112 <-- everything is in this box; +#X text 265 127 where the block size is redefined; +#X text 265 142 this is necessary for an; +#X text 266 154 ( acceptable? ) audio decoding; +#X obj 395 221 loadbang; +#X msg 395 251 \; pd dsp 1; +#X connect 0 0 1 0; +#X connect 0 1 1 1; +#X connect 9 0 10 0; diff --git a/doc/help_pdp_lumafilt.pd b/doc/help_pdp_lumafilt.pd new file mode 100644 index 0000000..400b4c1 --- /dev/null +++ b/doc/help_pdp_lumafilt.pd @@ -0,0 +1,75 @@ +#N canvas 237 21 712 664 10; +#X obj 118 358 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0 0 - - -; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 283 243 dac~; +#X obj 257 135 metro 70; +#X obj 252 167 pdp_yqt; +#X obj 421 166 pdp_v4l; +#X obj 430 135 metro 70; +#X obj 475 101 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 432 102 stop; +#X msg 517 133 open /dev/video; +#X obj 553 382 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 553 434 pdp_control; +#X msg 553 407 thread \$1; +#X floatatom 553 495 5 0 0 0 - - -; +#X obj 553 466 route pdp_drop; +#X text 56 407 pdp_lumafilt : luminosity filter; +#X text 57 420 useful to isolate some objects; +#X text 56 433 written by Yves Degoyon ( ydegoyon@free.fr ); +#X text 407 271 Filter this level of luminosity; +#X floatatom 362 272 5 0 0 0 - - -; +#X msg 283 296 filter \$1 0; +#X floatatom 361 298 5 0 0 0 - - -; +#X msg 284 270 filter \$1 1; +#X text 406 297 Unfilter this level of luminosity; +#X text 405 321 Mass filter these levels of luminosity [ 0 - 200 ] +; +#X text 406 344 Mass unfilter these levels of luminosity [ 0 - 200 +]; +#X msg 284 346 mfilter 0 200 0; +#X obj 117 290 pdp_lumafilt; +#X msg 283 323 mfilter 0 200 1; +#X connect 1 0 11 0; +#X connect 2 0 12 0; +#X connect 3 0 2 0; +#X connect 4 0 12 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 11 1; +#X connect 8 0 11 0; +#X connect 9 0 7 0; +#X connect 11 0 12 0; +#X connect 12 0 35 0; +#X connect 12 3 10 0; +#X connect 12 4 10 1; +#X connect 13 0 35 0; +#X connect 14 0 13 0; +#X connect 15 0 14 0; +#X connect 16 0 14 0; +#X connect 17 0 13 0; +#X connect 18 0 20 0; +#X connect 19 0 22 0; +#X connect 20 0 19 0; +#X connect 22 0 21 0; +#X connect 27 0 30 0; +#X connect 28 0 35 0; +#X connect 29 0 28 0; +#X connect 30 0 35 0; +#X connect 34 0 35 0; +#X connect 35 0 0 0; +#X connect 36 0 35 0; diff --git a/doc/help_pdp_mgrid.pd b/doc/help_pdp_mgrid.pd new file mode 100644 index 0000000..1063020 --- /dev/null +++ b/doc/help_pdp_mgrid.pd @@ -0,0 +1,77 @@ +#N canvas 237 21 712 664 10; +#X obj 176 482 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0 0 - - -; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 283 243 dac~; +#X obj 257 135 metro 70; +#X obj 215 350 pdp_mgrid; +#X obj 252 167 pdp_yqt; +#X obj 421 166 pdp_v4l; +#X obj 430 135 metro 70; +#X obj 475 101 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 432 102 stop; +#X msg 517 133 open /dev/video; +#X floatatom 309 279 5 0 0 0 - - -; +#X floatatom 318 300 5 0 0 0 - - -; +#X text 363 299 Grid dimension (X); +#X floatatom 335 321 5 0 0 0 - - -; +#X floatatom 353 345 5 0 0 0 - - -; +#X floatatom 235 433 5 0 0 0 - - -; +#X floatatom 280 399 5 0 0 0 - - -; +#X text 332 405 Y coordinate of cell where motion has been detected +; +#X text 288 533 written by Yves Degoyon ( ydegoyon@free.fr ); +#X text 289 516 pdp_mgrid : grid-based motion detection; +#X text 355 279 Threshold ( pixel average distance within a cell ) +; +#X text 380 320 Grid dimension (Y); +#X text 401 344 Grid visibility; +#X text 288 433 X coordinate of cell where motion has been detected +; +#X obj 70 498 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X obj 70 550 pdp_control; +#X msg 70 523 thread \$1; +#X floatatom 70 611 5 0 0 0 - - -; +#X obj 70 582 route pdp_drop; +#X connect 1 0 11 0; +#X connect 2 0 13 0; +#X connect 3 0 2 0; +#X connect 4 0 13 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 11 1; +#X connect 8 0 11 0; +#X connect 9 0 7 0; +#X connect 11 0 13 0; +#X connect 12 0 0 0; +#X connect 12 1 24 0; +#X connect 12 2 25 0; +#X connect 13 0 12 0; +#X connect 13 3 10 0; +#X connect 13 4 10 1; +#X connect 14 0 12 0; +#X connect 15 0 14 0; +#X connect 16 0 15 0; +#X connect 17 0 15 0; +#X connect 18 0 14 0; +#X connect 19 0 12 1; +#X connect 20 0 12 2; +#X connect 22 0 12 3; +#X connect 23 0 12 4; +#X connect 33 0 35 0; +#X connect 34 0 37 0; +#X connect 35 0 34 0; +#X connect 37 0 36 0; diff --git a/doc/help_pdp_mosaic.pd b/doc/help_pdp_mosaic.pd new file mode 100644 index 0000000..fd5ada8 --- /dev/null +++ b/doc/help_pdp_mosaic.pd @@ -0,0 +1,60 @@ +#N canvas 237 21 721 664 10; +#X obj 248 367 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 283 243 dac~; +#X obj 257 135 metro 70; +#X obj 252 167 pdp_yqt; +#X msg 340 272 bang; +#X obj 262 314 pdp_mosaic; +#X floatatom 359 299 5 0 0; +#X text 381 274 Set background; +#X text 406 297 Censorship level; +#X obj 421 166 pdp_v4l; +#X obj 430 135 metro 70; +#X obj 475 101 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 432 102 stop; +#X msg 517 133 open /dev/video; +#X obj 414 352 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 414 404 pdp_control; +#X msg 414 377 thread \$1; +#X floatatom 414 465 5 0 0; +#X obj 414 436 route pdp_drop; +#X connect 1 0 11 0; +#X connect 2 0 12 0; +#X connect 3 0 2 0; +#X connect 4 0 12 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 11 1; +#X connect 8 0 11 0; +#X connect 9 0 7 0; +#X connect 11 0 12 0; +#X connect 12 0 14 0; +#X connect 12 3 10 0; +#X connect 12 4 10 1; +#X connect 13 0 14 1; +#X connect 14 0 0 0; +#X connect 15 0 14 2; +#X connect 18 0 14 0; +#X connect 19 0 18 0; +#X connect 20 0 19 0; +#X connect 21 0 19 0; +#X connect 22 0 18 0; +#X connect 23 0 25 0; +#X connect 24 0 27 0; +#X connect 25 0 24 0; +#X connect 27 0 26 0; diff --git a/doc/help_pdp_nervous.pd b/doc/help_pdp_nervous.pd new file mode 100644 index 0000000..e611718 --- /dev/null +++ b/doc/help_pdp_nervous.pd @@ -0,0 +1,61 @@ +#N canvas 237 21 712 664 10; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X obj 346 203 pdp_v4l; +#X obj 355 172 metro 70; +#X obj 400 138 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 357 139 stop; +#X msg 442 170 open /dev/video; +#X obj 212 314 pdp_nervous; +#X text 371 299 Mode; +#X obj 252 167 pdp_yqt; +#X obj 283 243 dac~; +#X obj 350 300 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 414 352 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 414 404 pdp_control; +#X msg 414 377 thread \$1; +#X floatatom 414 465 5 0 0; +#X obj 414 436 route pdp_drop; +#X floatatom 322 275 5 0 0; +#X text 370 273 Number of frames; +#X obj 211 358 pdp_xv; +#X connect 0 0 9 0; +#X connect 1 0 17 0; +#X connect 2 0 1 0; +#X connect 3 0 17 0; +#X connect 4 0 3 0; +#X connect 5 0 4 0; +#X connect 6 0 9 1; +#X connect 7 0 9 0; +#X connect 8 0 6 0; +#X connect 9 0 17 0; +#X connect 10 0 15 0; +#X connect 11 0 10 0; +#X connect 12 0 11 0; +#X connect 13 0 11 0; +#X connect 14 0 10 0; +#X connect 15 0 27 0; +#X connect 17 0 15 0; +#X connect 17 3 18 0; +#X connect 17 4 18 1; +#X connect 19 0 15 2; +#X connect 20 0 22 0; +#X connect 21 0 24 0; +#X connect 22 0 21 0; +#X connect 24 0 23 0; +#X connect 25 0 15 1; diff --git a/doc/help_pdp_noquark.pd b/doc/help_pdp_noquark.pd new file mode 100644 index 0000000..30b17b8 --- /dev/null +++ b/doc/help_pdp_noquark.pd @@ -0,0 +1,74 @@ +#N canvas 237 21 712 664 10; +#X obj 176 476 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X obj 346 203 pdp_v4l; +#X obj 355 172 metro 70; +#X obj 400 138 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 357 139 stop; +#X msg 442 170 open /dev/video; +#X obj 252 167 pdp_yqt; +#X obj 283 243 dac~; +#X obj 414 352 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 414 404 pdp_control; +#X msg 414 377 thread \$1; +#X floatatom 414 465 5 0 0; +#X obj 414 436 route pdp_drop; +#X floatatom 290 282 5 0 0; +#X text 336 281 Number of frames; +#X floatatom 330 304 5 0 0; +#X text 376 304 Tolerance; +#X obj 212 314 pdp_noquark; +#X obj 149 348 pdp_affine; +#X floatatom 247 402 5 0 0; +#X floatatom 265 373 5 0 0; +#X msg 320 419 open /tmp/mo.mov; +#X obj 290 478 pdp_rec~; +#X msg 325 439 start; +#X msg 355 464 stop; +#X connect 1 0 10 0; +#X connect 2 0 16 0; +#X connect 3 0 2 0; +#X connect 4 0 16 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 10 1; +#X connect 8 0 10 0; +#X connect 9 0 7 0; +#X connect 10 0 16 0; +#X connect 11 0 27 0; +#X connect 12 0 11 0; +#X connect 13 0 12 0; +#X connect 14 0 12 0; +#X connect 15 0 11 0; +#X connect 16 0 27 0; +#X connect 16 3 17 0; +#X connect 16 4 17 1; +#X connect 18 0 20 0; +#X connect 19 0 22 0; +#X connect 20 0 19 0; +#X connect 22 0 21 0; +#X connect 23 0 27 1; +#X connect 25 0 27 2; +#X connect 27 0 28 0; +#X connect 28 0 0 0; +#X connect 28 0 32 0; +#X connect 29 0 28 1; +#X connect 30 0 28 2; +#X connect 31 0 32 0; +#X connect 33 0 32 0; +#X connect 34 0 32 0; diff --git a/doc/help_pdp_puzzle.pd b/doc/help_pdp_puzzle.pd new file mode 100644 index 0000000..98b2674 --- /dev/null +++ b/doc/help_pdp_puzzle.pd @@ -0,0 +1,66 @@ +#N canvas 84 12 712 664 10; +#X obj 197 398 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 1 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X obj 346 203 pdp_v4l; +#X obj 355 172 metro 70; +#X obj 400 138 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 357 139 stop; +#X msg 442 170 open /dev/video; +#X obj 252 167 pdp_yqt; +#X obj 283 243 dac~; +#X obj 198 354 pdp_puzzle; +#X obj 469 381 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 469 433 pdp_control; +#X msg 469 406 thread \$1; +#X floatatom 469 494 5 0 0; +#X obj 469 465 route pdp_drop; +#X msg 49 276 up; +#X msg 84 276 down; +#X msg 125 277 left; +#X msg 168 278 right; +#X floatatom 327 278 5 0 0; +#X text 104 257 Movement; +#X text 327 260 Number of blocks; +#X connect 1 0 10 0; +#X connect 2 0 16 0; +#X connect 3 0 2 0; +#X connect 4 0 16 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 10 1; +#X connect 8 0 10 0; +#X connect 9 0 7 0; +#X connect 10 0 16 0; +#X connect 11 0 18 0; +#X connect 12 0 11 0; +#X connect 13 0 12 0; +#X connect 14 0 12 0; +#X connect 15 0 11 0; +#X connect 16 0 18 0; +#X connect 16 3 17 0; +#X connect 16 4 17 1; +#X connect 18 0 0 0; +#X connect 19 0 21 0; +#X connect 20 0 23 0; +#X connect 21 0 20 0; +#X connect 23 0 22 0; +#X connect 24 0 18 0; +#X connect 25 0 18 0; +#X connect 26 0 18 0; +#X connect 27 0 18 0; +#X connect 28 0 18 1; diff --git a/doc/help_pdp_quark.pd b/doc/help_pdp_quark.pd new file mode 100644 index 0000000..5c4fb7b --- /dev/null +++ b/doc/help_pdp_quark.pd @@ -0,0 +1,60 @@ +#N canvas 237 21 712 664 10; +#X obj 211 358 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X obj 346 203 pdp_v4l; +#X obj 355 172 metro 70; +#X obj 400 138 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 357 139 stop; +#X msg 442 170 open /dev/video; +#X obj 212 314 pdp_quark; +#X obj 252 167 pdp_yqt; +#X obj 283 243 dac~; +#X obj 414 352 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 414 404 pdp_control; +#X msg 414 377 thread \$1; +#X floatatom 414 465 5 0 0; +#X obj 414 436 route pdp_drop; +#X floatatom 290 282 5 0 0; +#X text 336 281 Number of frames; +#X floatatom 302 302 5 0 0; +#X text 348 302 Tolerance; +#X connect 1 0 10 0; +#X connect 2 0 17 0; +#X connect 3 0 2 0; +#X connect 4 0 17 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 10 1; +#X connect 8 0 10 0; +#X connect 9 0 7 0; +#X connect 10 0 17 0; +#X connect 11 0 16 0; +#X connect 12 0 11 0; +#X connect 13 0 12 0; +#X connect 14 0 12 0; +#X connect 15 0 11 0; +#X connect 16 0 0 0; +#X connect 17 0 16 0; +#X connect 17 3 18 0; +#X connect 17 4 18 1; +#X connect 19 0 21 0; +#X connect 20 0 23 0; +#X connect 21 0 20 0; +#X connect 23 0 22 0; +#X connect 24 0 16 1; +#X connect 26 0 16 2; diff --git a/doc/help_pdp_radioactiv.pd b/doc/help_pdp_radioactiv.pd new file mode 100644 index 0000000..25864f4 --- /dev/null +++ b/doc/help_pdp_radioactiv.pd @@ -0,0 +1,74 @@ +#N canvas 237 21 712 664 10; +#X obj 267 415 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X floatatom 374 310 5 0 0; +#X obj 346 203 pdp_v4l; +#X obj 355 172 metro 70; +#X obj 400 138 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 357 139 stop; +#X msg 442 170 open /dev/video; +#X obj 267 359 pdp_radioactiv; +#X obj 341 285 hdl 15 1 0 4 empty empty empty 0 -6 0 8 -262144 -1 -1 +0; +#X text 412 283 Mode; +#X obj 252 167 pdp_yqt; +#X floatatom 408 332 5 0 0; +#X obj 283 243 dac~; +#X text 421 310 Snap time; +#X text 458 331 Snap interval; +#X floatatom 374 310 5 0 0; +#X obj 267 359 pdp_radioactiv; +#X obj 341 285 hdl 15 1 0 4 empty empty empty 0 -6 0 8 -262144 -1 -1 +0; +#X text 412 283 Mode; +#X floatatom 408 332 5 0 0; +#X text 421 310 Snap time; +#X obj 423 373 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 423 425 pdp_control; +#X msg 423 398 thread \$1; +#X floatatom 423 486 5 0 0; +#X obj 423 457 route pdp_drop; +#X connect 1 0 10 0; +#X connect 2 0 20 0; +#X connect 3 0 2 0; +#X connect 4 0 20 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 10 1; +#X connect 8 0 10 0; +#X connect 9 0 7 0; +#X connect 10 0 20 0; +#X connect 11 0 17 2; +#X connect 12 0 17 0; +#X connect 13 0 12 0; +#X connect 14 0 13 0; +#X connect 15 0 13 0; +#X connect 16 0 12 0; +#X connect 17 0 0 0; +#X connect 18 0 17 1; +#X connect 20 0 17 0; +#X connect 20 3 22 0; +#X connect 20 4 22 1; +#X connect 21 0 17 3; +#X connect 25 0 26 2; +#X connect 27 0 26 1; +#X connect 29 0 26 3; +#X connect 31 0 33 0; +#X connect 32 0 35 0; +#X connect 33 0 32 0; +#X connect 35 0 34 0; diff --git a/doc/help_pdp_rec~.pd b/doc/help_pdp_rec~.pd new file mode 100644 index 0000000..ae82d44 --- /dev/null +++ b/doc/help_pdp_rec~.pd @@ -0,0 +1,113 @@ +#N canvas 5 16 986 661 10; +#X obj 255 34 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 117 65 loop \$1; +#X obj 117 40 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1 +; +#X msg 280 33 open \$1; +#X obj 342 33 openpanel; +#X obj 412 34 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 303 69 5 0 0; +#X msg 212 35 stop; +#X obj 216 84 metro 70; +#X obj 18 245 pdp_v4l; +#X obj 27 214 metro 70; +#X obj 72 180 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 29 181 stop; +#X msg 92 215 open /dev/video; +#X text 113 637 written by Yves Degoyon ( ydegoyon@free.fr ); +#X msg 281 217 stop; +#X msg 280 191 start; +#X text 432 167 Open a file before any operations; +#X text 322 192 Start recording; +#X msg 280 165 open /tmp/output.mov; +#X floatatom 159 534 5 0 0; +#X obj 217 111 pdp_yqt; +#X text 328 621 using YUV420P color model ( hard-coded); +#X text 112 621 it records in quicktime format; +#X msg 283 347 jpeg \$1; +#X floatatom 346 348 5 0 0; +#X text 395 346 JPEG quality factor ( if using jpeg compressor ); +#X msg 281 372 framerate \$1; +#X floatatom 378 372 5 0 0; +#X text 427 371 Frame rate : if not set \, it will be calculated; +#X text 388 325 Set a compressor supported by libquicktime ( 0.9.1 +); +#X msg 281 270 symbol jpeg; +#X msg 282 324 compressor \$1; +#X msg 281 294 symbol raw; +#X msg 361 293 symbol divx; +#X msg 449 294 symbol dv; +#X msg 369 270 symbol yuv2; +#X text 319 225 ( u need to do that to have a useable movie ); +#X text 322 212 Stop recording; +#X obj 832 499 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 832 551 pdp_control; +#X msg 832 524 thread \$1; +#X floatatom 832 612 5 0 0; +#X obj 832 583 route pdp_drop; +#X text 113 605 pdp_rec~ : records video and audio output to file; +#X obj 119 300 adc~; +#X text 273 125 <---- audio connections; +#X text 281 147 ==== ACTIONS ========; +#X text 282 250 ==== VIDEOS SETTINGS ========; +#X text 390 450 Set a compressor supported by libquicktime ( 0.9.1 +); +#X text 285 399 ==== AUDIO SETTINGS ========; +#X msg 284 449 acompressor \$1; +#X msg 284 423 symbol twos; +#X obj 139 109 pdp_xv; +#X text 283 475 NOTE : pdp_rec~ will record 2 channels \, 8 bits audio +at the samplerate of PD; +#X msg 375 423 symbol raw; +#X obj 159 505 pdp_rec~; +#X obj 21 385 pdp_affine; +#X floatatom 52 340 5 0 0; +#X obj 26 440 pdp_xv; +#X connect 0 0 8 0; +#X connect 1 0 21 0; +#X connect 2 0 1 0; +#X connect 3 0 21 0; +#X connect 4 0 3 0; +#X connect 5 0 4 0; +#X connect 6 0 8 1; +#X connect 7 0 8 0; +#X connect 8 0 21 0; +#X connect 9 0 57 0; +#X connect 10 0 9 0; +#X connect 11 0 10 0; +#X connect 12 0 10 0; +#X connect 13 0 9 0; +#X connect 15 0 56 0; +#X connect 16 0 56 0; +#X connect 19 0 56 0; +#X connect 21 0 53 0; +#X connect 21 0 56 0; +#X connect 21 3 56 0; +#X connect 21 4 56 1; +#X connect 24 0 56 0; +#X connect 25 0 24 0; +#X connect 27 0 56 0; +#X connect 28 0 27 0; +#X connect 31 0 32 0; +#X connect 32 0 56 0; +#X connect 33 0 32 0; +#X connect 34 0 32 0; +#X connect 35 0 32 0; +#X connect 36 0 32 0; +#X connect 39 0 41 0; +#X connect 40 0 43 0; +#X connect 41 0 40 0; +#X connect 43 0 42 0; +#X connect 45 0 56 0; +#X connect 45 1 56 1; +#X connect 51 0 56 0; +#X connect 52 0 51 0; +#X connect 55 0 51 0; +#X connect 56 0 20 0; +#X connect 57 0 59 0; +#X connect 57 0 56 0; +#X connect 58 0 57 1; diff --git a/doc/help_pdp_rev.pd b/doc/help_pdp_rev.pd new file mode 100644 index 0000000..62a3c0d --- /dev/null +++ b/doc/help_pdp_rev.pd @@ -0,0 +1,66 @@ +#N canvas 237 21 712 664 10; +#X obj 248 367 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 283 243 dac~; +#X obj 257 135 metro 70; +#X obj 252 167 pdp_yqt; +#X floatatom 336 274 5 0 0; +#X floatatom 358 299 5 0 0; +#X floatatom 372 321 5 0 0; +#X floatatom 389 344 5 0 0; +#X obj 249 323 pdp_rev; +#X text 411 297 Line Space default=6; +#X text 387 274 Grab Time [ 1 \, ... ] default=1; +#X text 423 318 Scale [ 1 \, ... ] default=50; +#X text 439 343 Line color default=0xffff; +#X obj 421 166 pdp_v4l; +#X obj 430 135 metro 70; +#X obj 475 101 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 432 102 stop; +#X msg 517 133 open /dev/video; +#X obj 480 394 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 480 446 pdp_control; +#X msg 480 419 thread \$1; +#X floatatom 480 507 5 0 0; +#X obj 480 478 route pdp_drop; +#X connect 1 0 11 0; +#X connect 2 0 12 0; +#X connect 3 0 2 0; +#X connect 4 0 12 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 11 1; +#X connect 8 0 11 0; +#X connect 9 0 7 0; +#X connect 11 0 12 0; +#X connect 12 0 17 0; +#X connect 12 3 10 0; +#X connect 12 4 10 1; +#X connect 13 0 17 1; +#X connect 14 0 17 2; +#X connect 15 0 17 3; +#X connect 16 0 17 4; +#X connect 17 0 0 0; +#X connect 22 0 17 0; +#X connect 23 0 22 0; +#X connect 24 0 23 0; +#X connect 25 0 23 0; +#X connect 26 0 22 0; +#X connect 27 0 29 0; +#X connect 28 0 31 0; +#X connect 29 0 28 0; +#X connect 31 0 30 0; diff --git a/doc/help_pdp_ripple.pd b/doc/help_pdp_ripple.pd new file mode 100644 index 0000000..6deadbc --- /dev/null +++ b/doc/help_pdp_ripple.pd @@ -0,0 +1,67 @@ +#N canvas 237 21 712 664 10; +#X obj 248 367 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 283 243 dac~; +#X obj 257 135 metro 70; +#X obj 252 167 pdp_yqt; +#X msg 384 260 bang; +#X obj 367 235 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 249 323 pdp_ripple; +#X text 389 234 Mode ( 0=raindrops \, 1=motion detection ); +#X floatatom 403 287 5 0 0; +#X text 454 287 Motion detection threshold; +#X text 425 262 Reset; +#X floatatom 422 310 5 0 0; +#X text 473 309 Rain density evolution speed; +#X obj 421 166 pdp_v4l; +#X obj 430 135 metro 70; +#X obj 475 101 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 432 102 stop; +#X msg 517 133 open /dev/video; +#X obj 406 378 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 406 430 pdp_control; +#X msg 406 403 thread \$1; +#X floatatom 406 491 5 0 0; +#X obj 406 462 route pdp_drop; +#X connect 1 0 11 0; +#X connect 2 0 12 0; +#X connect 3 0 2 0; +#X connect 4 0 12 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 11 1; +#X connect 8 0 11 0; +#X connect 9 0 7 0; +#X connect 11 0 12 0; +#X connect 12 0 15 0; +#X connect 12 3 10 0; +#X connect 12 4 10 1; +#X connect 13 0 15 2; +#X connect 14 0 15 1; +#X connect 15 0 0 0; +#X connect 17 0 15 3; +#X connect 20 0 15 4; +#X connect 22 0 15 0; +#X connect 23 0 22 0; +#X connect 24 0 23 0; +#X connect 25 0 23 0; +#X connect 26 0 22 0; +#X connect 27 0 29 0; +#X connect 28 0 31 0; +#X connect 29 0 28 0; +#X connect 31 0 30 0; diff --git a/doc/help_pdp_segsnd~.pd b/doc/help_pdp_segsnd~.pd new file mode 100644 index 0000000..ca275fd --- /dev/null +++ b/doc/help_pdp_segsnd~.pd @@ -0,0 +1,13 @@ +#N canvas 259 178 509 391 10; +#X obj 156 158 dac~; +#X text 51 321 written by Yves Degoyon (ydegoyon@free.fr); +#X text 236 112 <-- everything is in this box; +#X text 265 127 where the block size is redefined; +#X obj 395 221 loadbang; +#X msg 395 251 \; pd dsp 1; +#X obj 128 113 rs_pdp_segsnd~; +#X text 51 295 pdp_segsnd~ : turns a segment into sound; +#X text 51 308 ( only use luminosity ); +#X connect 4 0 5 0; +#X connect 6 0 0 0; +#X connect 6 0 0 1; diff --git a/doc/help_pdp_shagadelic.pd b/doc/help_pdp_shagadelic.pd new file mode 100644 index 0000000..12d6f32 --- /dev/null +++ b/doc/help_pdp_shagadelic.pd @@ -0,0 +1,59 @@ +#N canvas 84 12 712 664 10; +#X obj 263 378 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 1 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X obj 346 203 pdp_v4l; +#X obj 355 172 metro 70; +#X obj 400 138 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 357 139 stop; +#X msg 442 170 open /dev/video; +#X obj 252 167 pdp_yqt; +#X obj 283 243 dac~; +#X obj 264 334 pdp_shagadelic; +#X obj 469 381 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 469 433 pdp_control; +#X msg 469 406 thread \$1; +#X floatatom 469 494 5 0 0; +#X obj 469 465 route pdp_drop; +#X floatatom 397 277 5 0 0; +#X text 396 257 Mask; +#X obj 373 301 * 100; +#X connect 1 0 10 0; +#X connect 2 0 16 0; +#X connect 3 0 2 0; +#X connect 4 0 16 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 10 1; +#X connect 8 0 10 0; +#X connect 9 0 7 0; +#X connect 10 0 16 0; +#X connect 11 0 18 0; +#X connect 12 0 11 0; +#X connect 13 0 12 0; +#X connect 14 0 12 0; +#X connect 15 0 11 0; +#X connect 16 0 18 0; +#X connect 16 3 17 0; +#X connect 16 4 17 1; +#X connect 18 0 0 0; +#X connect 19 0 21 0; +#X connect 20 0 23 0; +#X connect 21 0 20 0; +#X connect 23 0 22 0; +#X connect 24 0 26 0; +#X connect 26 0 18 1; diff --git a/doc/help_pdp_simura.pd b/doc/help_pdp_simura.pd new file mode 100644 index 0000000..59ac77a --- /dev/null +++ b/doc/help_pdp_simura.pd @@ -0,0 +1,65 @@ +#N canvas 237 21 712 664 10; +#X obj 218 367 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 283 243 dac~; +#X obj 257 135 metro 70; +#X obj 217 299 pdp_simura; +#X floatatom 344 275 5 0 0; +#X obj 252 167 pdp_yqt; +#X text 445 257 Color 0<c<65535; +#X obj 386 316 hdl 15 1 0 9 empty empty empty 0 -6 0 8 -262144 -1 -1 +0; +#X text 388 298 Mode; +#X msg 442 282 56987; +#X msg 425 221 16733; +#X obj 421 166 pdp_v4l; +#X obj 430 135 metro 70; +#X obj 475 101 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 432 102 stop; +#X msg 517 133 open /dev/video; +#X obj 406 378 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 406 430 pdp_control; +#X msg 406 403 thread \$1; +#X floatatom 406 491 5 0 0; +#X obj 406 462 route pdp_drop; +#X connect 1 0 11 0; +#X connect 2 0 14 0; +#X connect 3 0 2 0; +#X connect 4 0 14 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 11 1; +#X connect 8 0 11 0; +#X connect 9 0 7 0; +#X connect 11 0 14 0; +#X connect 12 0 0 0; +#X connect 13 0 12 1; +#X connect 14 0 12 0; +#X connect 14 3 10 0; +#X connect 14 4 10 1; +#X connect 16 0 12 2; +#X connect 18 0 13 0; +#X connect 19 0 13 0; +#X connect 20 0 12 0; +#X connect 21 0 20 0; +#X connect 22 0 21 0; +#X connect 23 0 21 0; +#X connect 24 0 20 0; +#X connect 25 0 27 0; +#X connect 26 0 29 0; +#X connect 27 0 26 0; +#X connect 29 0 28 0; diff --git a/doc/help_pdp_smuck.pd b/doc/help_pdp_smuck.pd new file mode 100644 index 0000000..38a5bf3 --- /dev/null +++ b/doc/help_pdp_smuck.pd @@ -0,0 +1,57 @@ +#N canvas 84 12 712 664 10; +#X obj 263 378 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 1 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0 0 - - -; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X obj 346 203 pdp_v4l; +#X obj 355 172 metro 70; +#X obj 400 138 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 357 139 stop; +#X msg 442 170 open /dev/video; +#X obj 252 167 pdp_yqt; +#X obj 283 243 dac~; +#X obj 469 381 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 469 433 pdp_control; +#X msg 469 406 thread \$1; +#X floatatom 469 494 5 0 0 0 - - -; +#X obj 469 465 route pdp_drop; +#X floatatom 344 318 5 0 0 0 - - -; +#X text 339 300 Set transformation factor ( default = 30 ); +#X obj 264 334 pdp_smuck; +#X connect 1 0 10 0; +#X connect 2 0 16 0; +#X connect 3 0 2 0; +#X connect 4 0 16 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 10 1; +#X connect 8 0 10 0; +#X connect 9 0 7 0; +#X connect 10 0 16 0; +#X connect 11 0 25 0; +#X connect 12 0 11 0; +#X connect 13 0 12 0; +#X connect 14 0 12 0; +#X connect 15 0 11 0; +#X connect 16 0 25 0; +#X connect 16 3 17 0; +#X connect 16 4 17 1; +#X connect 18 0 20 0; +#X connect 19 0 22 0; +#X connect 20 0 19 0; +#X connect 22 0 21 0; +#X connect 23 0 25 1; +#X connect 25 0 0 0; diff --git a/doc/help_pdp_spigot.pd b/doc/help_pdp_spigot.pd new file mode 100644 index 0000000..0642f72 --- /dev/null +++ b/doc/help_pdp_spigot.pd @@ -0,0 +1,52 @@ +#N canvas 237 21 712 664 10; +#X obj 263 491 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 305 466 5 0 0; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X obj 252 167 pdp_yqt; +#X obj 421 166 pdp_v4l; +#X obj 430 135 metro 70; +#X obj 475 101 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 432 102 stop; +#X msg 517 133 open /dev/video; +#X obj 305 272 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X text 330 273 Route to outlet 0 or 1; +#X obj 217 299 pdp_spigot; +#X obj 175 371 pdp_edge; +#X obj 319 373 pdp_quark; +#X connect 1 0 11 0; +#X connect 2 0 12 0; +#X connect 3 0 2 0; +#X connect 4 0 12 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 0 1; +#X connect 8 0 11 1; +#X connect 9 0 11 0; +#X connect 10 0 8 0; +#X connect 11 0 12 0; +#X connect 12 0 20 0; +#X connect 13 0 20 0; +#X connect 14 0 13 0; +#X connect 15 0 14 0; +#X connect 16 0 14 0; +#X connect 17 0 13 0; +#X connect 18 0 20 1; +#X connect 20 0 21 0; +#X connect 20 1 22 0; +#X connect 21 0 0 0; +#X connect 22 0 0 0; diff --git a/doc/help_pdp_spiral.pd b/doc/help_pdp_spiral.pd new file mode 100644 index 0000000..c0a60e5 --- /dev/null +++ b/doc/help_pdp_spiral.pd @@ -0,0 +1,82 @@ +#N canvas 237 21 712 664 10; +#X obj 193 497 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X floatatom 391 277 5 0 0; +#X obj 346 203 pdp_v4l; +#X obj 355 172 metro 70; +#X obj 400 138 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 357 139 stop; +#X msg 442 170 open /dev/video; +#X obj 194 453 pdp_spiral ---------------------; +#X obj 358 252 hdl 15 1 0 8 empty empty empty 0 -6 0 8 -262144 -1 -1 +0; +#X text 488 252 Mode; +#X obj 252 167 pdp_yqt; +#X text 438 277 Focus X; +#X floatatom 425 299 5 0 0; +#X text 472 299 Focus Y; +#X floatatom 442 326 5 0 0; +#X text 489 326 Depth Shift; +#X floatatom 453 354 5 0 0; +#X text 499 355 Focus interval; +#X text 511 384 Focus increment; +#X floatatom 463 383 5 0 0; +#X text 511 384 Focus increment; +#X obj 481 407 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 495 430 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X text 508 409 Toggle XOR; +#X text 519 431 Animate Focus; +#X obj 283 243 dac~; +#X obj 410 486 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 410 538 pdp_control; +#X msg 410 511 thread \$1; +#X floatatom 410 599 5 0 0; +#X obj 410 570 route pdp_drop; +#X connect 1 0 10 0; +#X connect 2 0 20 0; +#X connect 3 0 2 0; +#X connect 4 0 20 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 10 1; +#X connect 8 0 10 0; +#X connect 9 0 7 0; +#X connect 10 0 20 0; +#X connect 11 0 17 2; +#X connect 12 0 17 0; +#X connect 13 0 12 0; +#X connect 14 0 13 0; +#X connect 15 0 13 0; +#X connect 16 0 12 0; +#X connect 17 0 0 0; +#X connect 18 0 17 1; +#X connect 20 0 17 0; +#X connect 20 3 35 0; +#X connect 20 4 35 1; +#X connect 22 0 17 3; +#X connect 24 0 17 4; +#X connect 26 0 17 5; +#X connect 29 0 17 6; +#X connect 31 0 17 7; +#X connect 32 0 17 8; +#X connect 36 0 38 0; +#X connect 37 0 40 0; +#X connect 38 0 37 0; +#X connect 40 0 39 0; diff --git a/doc/help_pdp_streaming.pd b/doc/help_pdp_streaming.pd new file mode 100644 index 0000000..9615b13 --- /dev/null +++ b/doc/help_pdp_streaming.pd @@ -0,0 +1,83 @@ +#N canvas 88 8 772 635 10; +#X obj 149 535 pdp_xv; +#X obj 263 66 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 165 92 loop \$1; +#X obj 166 70 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1 +; +#X msg 150 45 open \$1; +#X obj 149 21 openpanel; +#X obj 134 4 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 287 66 5 0 0; +#X msg 227 66 stop; +#X obj 233 92 metro 70; +#X text 386 588 written by Yves Degoyon ( ydegoyon@free.fr ); +#X obj 169 156 pdp_yqt; +#X obj 160 315 pdp_o; +#X msg 267 154 connect localhost 4578; +#X msg 267 179 disconnect; +#X msg 267 202 start; +#X msg 267 227 stop; +#X floatatom 203 492 5 0 0; +#X obj 145 443 pdp_i 4578; +#X floatatom 180 512 5 0 0; +#X text 229 512 Connection state; +#X text 249 492 Number of frames received; +#X symbolatom 220 470 10 0 0; +#X text 301 472 Address of the emitter; +#X msg 267 253 refresh; +#X msg 267 279 framerate \$1; +#X floatatom 366 280 5 0 0; +#X text 411 280 Emission frame rate; +#X floatatom 136 406 5 0 0; +#X text 188 407 Connection state; +#X floatatom 165 386 7 0 0; +#X text 223 384 Frames emitted; +#X floatatom 190 362 7 0 0; +#X text 250 360 Frames dropped; +#X obj 571 390 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 571 442 pdp_control; +#X msg 571 415 thread \$1; +#X floatatom 571 503 5 0 0; +#X obj 571 474 route pdp_drop; +#X text 385 569 pdp_o/pdp_i : PDP packets streaming; +#X floatatom 366 302 5 0 0; +#X msg 267 301 smoothing \$1; +#X text 411 302 Smoothing factor; +#X text 413 242 The bandwidth used can be controlled; +#X text 413 255 by changing these two parameters :; +#X floatatom 207 341 5 0 0; +#X text 259 340 Bandwidth (in kb); +#X connect 1 0 9 0; +#X connect 2 0 11 0; +#X connect 3 0 2 0; +#X connect 4 0 11 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 9 1; +#X connect 8 0 9 0; +#X connect 9 0 11 0; +#X connect 11 0 12 0; +#X connect 12 0 28 0; +#X connect 12 1 30 0; +#X connect 12 2 32 0; +#X connect 12 3 45 0; +#X connect 13 0 12 0; +#X connect 14 0 12 0; +#X connect 15 0 12 0; +#X connect 16 0 12 0; +#X connect 18 0 0 0; +#X connect 18 1 19 0; +#X connect 18 2 17 0; +#X connect 18 3 22 0; +#X connect 24 0 12 0; +#X connect 25 0 12 0; +#X connect 26 0 25 0; +#X connect 34 0 36 0; +#X connect 35 0 38 0; +#X connect 36 0 35 0; +#X connect 38 0 37 0; +#X connect 40 0 41 0; +#X connect 41 0 12 0; diff --git a/doc/help_pdp_text.pd b/doc/help_pdp_text.pd new file mode 100644 index 0000000..dd03714 --- /dev/null +++ b/doc/help_pdp_text.pd @@ -0,0 +1,118 @@ +#N canvas 84 12 763 664 10; +#X obj 92 608 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0 0 - - -; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X obj 346 203 pdp_v4l; +#X obj 355 172 metro 70; +#X obj 400 138 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 357 139 stop; +#X msg 442 170 open /dev/video; +#X obj 252 167 pdp_yqt; +#X obj 606 530 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 606 582 pdp_control; +#X msg 606 555 thread \$1; +#X floatatom 606 643 5 0 0 0 - - -; +#X obj 606 614 route pdp_drop; +#X text 221 617 pdp_text : text rendering in PDP; +#X text 222 631 written by Yves Degoyon (ydegoyon@free.fr); +#X msg 144 282 text moshi-moshi 34 58; +#X msg 163 304 text on%32air!! 150 78; +#X msg 186 384 text %34%48%49:37:58%34 20 220; +#X msg 177 359 text "01:37:58" 230 220; +#X msg 171 330 text a%32hundred%32%% 120 128 255 0 0; +#X obj 204 425 hdl 15 1 0 10 empty empty empty 0 -6 0 8 -262144 -1 +-1 0; +#X text 364 424 Select current text ( 10 items by default ); +#X text 308 282 Add a simple text; +#X text 330 304 Add a text with special characters; +#X text 438 330 Add a real percent now ( but in red ); +#X text 355 359 Have to put a quote (%34) before starting numbers; +#X text 409 384 This time \, it's real quotes ( tricky \, hey?? ); +#X floatatom 219 451 5 0 0 0 - - -; +#X text 267 450 X coordinate; +#X floatatom 240 472 5 0 0 0 - - -; +#X floatatom 265 493 5 0 0 0 - - -; +#X floatatom 283 513 5 0 0 0 - - -; +#X floatatom 303 533 5 0 0 0 - - -; +#X text 288 471 Y coordinate; +#X text 313 492 R component; +#X text 331 512 G component; +#X text 351 532 B component; +#X msg 445 203 dim 800 600; +#X msg 29 352 clear; +#X msg 30 387 delete 1; +#X msg 30 421 resize 20; +#X msg 30 489 font helmetr/14; +#X obj 155 585 pdp_text -----------------; +#X text 139 254 text <text> x y [ r g b angle ]; +#X floatatom 331 554 5 0 0 0 - - -; +#X text 379 553 Angle; +#X msg 61 516 dither \$1; +#X floatatom 13 518 5 0 0 0 - - -; +#X floatatom 14 541 5 0 0 0 - - -; +#X msg 63 540 blend \$1; +#X floatatom 14 562 5 0 0 0 - - -; +#X msg 64 560 antialias \$1; +#X msg 29 458 font helmetr/5; +#X floatatom 365 577 5 0 0 0 - - -; +#X text 411 577 Scroll; +#X connect 1 0 10 0; +#X connect 2 0 16 0; +#X connect 3 0 2 0; +#X connect 4 0 16 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 10 1; +#X connect 8 0 10 0; +#X connect 9 0 7 0; +#X connect 10 0 16 0; +#X connect 11 0 51 0; +#X connect 12 0 11 0; +#X connect 13 0 12 0; +#X connect 14 0 12 0; +#X connect 15 0 11 0; +#X connect 16 0 51 0; +#X connect 17 0 19 0; +#X connect 18 0 21 0; +#X connect 19 0 18 0; +#X connect 21 0 20 0; +#X connect 24 0 51 0; +#X connect 25 0 51 0; +#X connect 26 0 51 0; +#X connect 27 0 51 0; +#X connect 28 0 51 0; +#X connect 29 0 51 1; +#X connect 36 0 51 2; +#X connect 38 0 51 3; +#X connect 39 0 51 4; +#X connect 40 0 51 5; +#X connect 41 0 51 6; +#X connect 46 0 11 0; +#X connect 47 0 51 0; +#X connect 48 0 51 0; +#X connect 49 0 51 0; +#X connect 50 0 51 0; +#X connect 51 0 0 0; +#X connect 53 0 51 7; +#X connect 55 0 51 0; +#X connect 56 0 55 0; +#X connect 57 0 58 0; +#X connect 58 0 51 0; +#X connect 59 0 60 0; +#X connect 60 0 51 0; +#X connect 61 0 51 0; +#X connect 62 0 51 8; diff --git a/doc/help_pdp_transform.pd b/doc/help_pdp_transform.pd new file mode 100644 index 0000000..9a207db --- /dev/null +++ b/doc/help_pdp_transform.pd @@ -0,0 +1,58 @@ +#N canvas 84 12 712 664 10; +#X obj 263 378 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X obj 346 203 pdp_v4l; +#X obj 355 172 metro 70; +#X obj 400 138 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 357 139 stop; +#X msg 442 170 open /dev/video; +#X obj 252 167 pdp_yqt; +#X obj 283 243 dac~; +#X obj 264 334 pdp_transform; +#X obj 469 381 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 469 433 pdp_control; +#X msg 469 406 thread \$1; +#X floatatom 469 494 5 0 0; +#X obj 469 465 route pdp_drop; +#X obj 343 304 hdl 15 1 0 6 empty empty empty 0 -6 0 8 -262144 -1 -1 +0; +#X text 346 281 Choose transformation; +#X connect 1 0 10 0; +#X connect 2 0 16 0; +#X connect 3 0 2 0; +#X connect 4 0 16 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 10 1; +#X connect 8 0 10 0; +#X connect 9 0 7 0; +#X connect 10 0 16 0; +#X connect 11 0 18 0; +#X connect 12 0 11 0; +#X connect 13 0 12 0; +#X connect 14 0 12 0; +#X connect 15 0 11 0; +#X connect 16 0 18 0; +#X connect 16 3 17 0; +#X connect 16 4 17 1; +#X connect 18 0 0 0; +#X connect 19 0 21 0; +#X connect 20 0 23 0; +#X connect 21 0 20 0; +#X connect 23 0 22 0; +#X connect 24 0 18 1; diff --git a/doc/help_pdp_transition.pd b/doc/help_pdp_transition.pd new file mode 100644 index 0000000..7e6e871 --- /dev/null +++ b/doc/help_pdp_transition.pd @@ -0,0 +1,116 @@ +#N canvas 324 0 828 668 10; +#X obj 275 452 pdp_xv; +#X obj 227 97 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 46 138 open \$1; +#X obj 45 114 openpanel; +#X obj 30 97 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 184 98 stop; +#X obj 187 135 metro 70; +#X obj 124 175 pdp_yqt; +#X obj 251 168 pdp_v4l; +#X obj 260 137 metro 70; +#X obj 305 103 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 262 104 stop; +#X obj 587 463 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X msg 587 488 thread \$1; +#X floatatom 587 576 5 0 0 0 - - -; +#X obj 587 547 route pdp_drop; +#X obj 556 97 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 452 136 loop \$1; +#X obj 453 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 375 138 open \$1; +#X obj 374 114 openpanel; +#X obj 359 97 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 513 98 stop; +#X obj 516 135 metro 70; +#X obj 453 175 pdp_yqt; +#X obj 580 168 pdp_v4l; +#X obj 589 137 metro 70; +#X obj 634 103 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 591 104 stop; +#X text 42 572 written by Yves Degoyon ( ydegoyon@free.fr ); +#X text 144 538 between 2 video sources; +#X text 40 526 pdp_transition : alternate transitions; +#X msg 177 328 circle 5; +#X msg 177 306 circle 1; +#X obj 587 515 pdp_control; +#X msg 443 301 wipelr 5 0; +#X text 524 302 Wipe transition left to right : <speed> <randomness> +; +#X msg 443 321 wipelr 5 40; +#X text 523 321 The same with randomness; +#X msg 443 342 wiperl 5 0; +#X text 520 341 Wipe transition right to left : <speed> <randomness> +; +#X text 520 359 Multi wipe : <speed> <randomness>; +#X msg 443 360 mwipe 5 0; +#X text 521 378 Wipe top down : <speed> <randomness>; +#X msg 444 379 wipetd 5 0; +#X text 520 398 Wipe bottom up : <speed> <randomness>; +#X msg 443 399 wipebu 5 30; +#X msg 177 349 random 5; +#X text 6 350 Random transition : <speed>; +#X msg 176 368 melt 5; +#X text 5 369 Melt transition : <speed>; +#X text 6 308 Slow circle transition; +#X text 6 329 Faster circle transition; +#X text 5 402 <speed> <randomness>; +#X text 5 391 Blend transition :; +#X msg 176 391 blend 5 30; +#X text 175 560 "melt" \, "blend"; +#X text 40 549 existing transition : "circle" \, "wipe" \, "random" +\,; +#X obj 275 395 pdp_transition; +#X connect 1 0 8 0; +#X connect 2 0 9 0; +#X connect 3 0 2 0; +#X connect 4 0 9 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 8 0; +#X connect 8 0 9 0; +#X connect 9 0 60 1; +#X connect 10 0 60 1; +#X connect 11 0 10 0; +#X connect 12 0 11 0; +#X connect 13 0 11 0; +#X connect 14 0 15 0; +#X connect 15 0 36 0; +#X connect 17 0 16 0; +#X connect 18 0 25 0; +#X connect 19 0 26 0; +#X connect 20 0 19 0; +#X connect 21 0 26 0; +#X connect 22 0 21 0; +#X connect 23 0 22 0; +#X connect 24 0 25 0; +#X connect 25 0 26 0; +#X connect 26 0 60 2; +#X connect 27 0 60 2; +#X connect 28 0 27 0; +#X connect 29 0 28 0; +#X connect 30 0 28 0; +#X connect 34 0 60 0; +#X connect 35 0 60 0; +#X connect 36 0 17 0; +#X connect 37 0 60 0; +#X connect 39 0 60 0; +#X connect 41 0 60 0; +#X connect 44 0 60 0; +#X connect 46 0 60 0; +#X connect 48 0 60 0; +#X connect 49 0 60 0; +#X connect 51 0 60 0; +#X connect 57 0 60 0; +#X connect 60 0 0 0; diff --git a/doc/help_pdp_underwatch.pd b/doc/help_pdp_underwatch.pd new file mode 100644 index 0000000..f845aac --- /dev/null +++ b/doc/help_pdp_underwatch.pd @@ -0,0 +1,79 @@ +#N canvas 207 18 712 664 10; +#X obj 218 367 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X floatatom 340 264 5 0 0; +#X text 393 265 Strip size 0 \, <height> default=10; +#X obj 217 299 pdp_underwatch; +#X obj 257 135 metro 50; +#X obj 582 161 pdp_control; +#X msg 582 134 thread \$1; +#X floatatom 582 222 5 0 0; +#X obj 582 193 route pdp_drop; +#X obj 582 161 pdp_control; +#X msg 582 134 thread \$1; +#X floatatom 582 222 5 0 0; +#X obj 582 193 route pdp_drop; +#X obj 582 161 pdp_control; +#X msg 582 134 thread \$1; +#X floatatom 582 222 5 0 0; +#X obj 582 193 route pdp_drop; +#X text 262 226 Set the rate so that no packets are lost -->; +#X obj 583 108 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 252 167 pdp_yqt; +#X obj 376 173 pdp_v4l; +#X obj 385 142 metro 70; +#X obj 430 108 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 387 109 stop; +#X msg 433 172 open /dev/video; +#X obj 445 321 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 445 373 pdp_control; +#X msg 445 346 thread \$1; +#X floatatom 445 434 5 0 0; +#X obj 445 405 route pdp_drop; +#X connect 1 0 13 0; +#X connect 2 0 28 0; +#X connect 3 0 2 0; +#X connect 4 0 28 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 13 1; +#X connect 8 0 13 0; +#X connect 9 0 7 0; +#X connect 10 0 12 1; +#X connect 12 0 0 0; +#X connect 13 0 28 0; +#X connect 14 0 17 0; +#X connect 15 0 14 0; +#X connect 17 0 16 0; +#X connect 18 0 21 0; +#X connect 19 0 18 0; +#X connect 21 0 20 0; +#X connect 22 0 25 0; +#X connect 23 0 22 0; +#X connect 25 0 24 0; +#X connect 27 0 23 0; +#X connect 28 0 12 0; +#X connect 29 0 12 0; +#X connect 30 0 29 0; +#X connect 31 0 30 0; +#X connect 32 0 30 0; +#X connect 33 0 29 0; +#X connect 34 0 36 0; +#X connect 35 0 38 0; +#X connect 36 0 35 0; +#X connect 38 0 37 0; diff --git a/doc/help_pdp_vertigo.pd b/doc/help_pdp_vertigo.pd new file mode 100644 index 0000000..ed1c09c --- /dev/null +++ b/doc/help_pdp_vertigo.pd @@ -0,0 +1,57 @@ +#N canvas 237 21 712 664 10; +#X obj 218 367 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X obj 224 248 pdp_vertigo; +#X floatatom 294 193 5 0 0; +#X floatatom 322 221 5 0 0; +#X text 356 192 Phase increment; +#X text 374 219 Zoom rate; +#X obj 252 167 pdp_yqt; +#X obj 421 166 pdp_v4l; +#X obj 430 135 metro 70; +#X obj 475 101 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 432 102 stop; +#X msg 517 133 open /dev/video; +#X obj 445 321 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 445 373 pdp_control; +#X msg 445 346 thread \$1; +#X floatatom 445 434 5 0 0; +#X obj 445 405 route pdp_drop; +#X connect 1 0 10 0; +#X connect 2 0 16 0; +#X connect 3 0 2 0; +#X connect 4 0 16 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 10 1; +#X connect 8 0 10 0; +#X connect 9 0 7 0; +#X connect 10 0 16 0; +#X connect 11 0 0 0; +#X connect 12 0 11 1; +#X connect 13 0 11 2; +#X connect 16 0 11 0; +#X connect 17 0 11 0; +#X connect 18 0 17 0; +#X connect 19 0 18 0; +#X connect 20 0 18 0; +#X connect 21 0 17 0; +#X connect 22 0 24 0; +#X connect 23 0 26 0; +#X connect 24 0 23 0; +#X connect 26 0 25 0; diff --git a/doc/help_pdp_warhol.pd b/doc/help_pdp_warhol.pd new file mode 100644 index 0000000..3038997 --- /dev/null +++ b/doc/help_pdp_warhol.pd @@ -0,0 +1,75 @@ +#N canvas 237 21 712 664 10; +#X obj 272 495 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 257 135 metro 70; +#X floatatom 339 275 5 0 0; +#X obj 346 203 pdp_v4l; +#X obj 400 138 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 357 139 stop; +#X msg 442 170 open /dev/video; +#X obj 284 435 pdp_warhol; +#X obj 252 167 pdp_yqt; +#X floatatom 373 297 5 0 0; +#X obj 283 243 dac~; +#X text 386 275 X Divider; +#X text 423 296 Y Divider; +#X obj 389 318 hdl 15 1 0 9 empty empty empty 0 -6 0 8 -262144 -1 -1 +0; +#X text 579 320 Color to modify; +#X floatatom 412 340 5 0 0; +#X floatatom 438 361 5 0 0; +#X floatatom 464 386 5 0 0; +#X text 459 340 Y component; +#X text 487 360 U component; +#X text 510 385 V component; +#X obj 355 172 metro 70; +#X floatatom 526 319 5 0 0; +#X obj 475 431 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 475 483 pdp_control; +#X msg 475 456 thread \$1; +#X floatatom 475 544 5 0 0; +#X obj 475 513 route pdp_drop; +#X connect 1 0 10 0; +#X connect 2 0 17 0; +#X connect 3 0 2 0; +#X connect 4 0 17 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 10 1; +#X connect 8 0 10 0; +#X connect 9 0 7 0; +#X connect 10 0 17 0; +#X connect 11 0 16 1; +#X connect 12 0 16 0; +#X connect 13 0 30 0; +#X connect 14 0 30 0; +#X connect 15 0 12 0; +#X connect 16 0 0 0; +#X connect 17 0 16 0; +#X connect 17 3 19 0; +#X connect 17 4 19 1; +#X connect 18 0 16 2; +#X connect 22 0 16 3; +#X connect 22 0 31 0; +#X connect 24 0 16 4; +#X connect 25 0 16 5; +#X connect 26 0 16 6; +#X connect 30 0 12 0; +#X connect 32 0 34 0; +#X connect 33 0 36 0; +#X connect 34 0 33 0; +#X connect 36 0 35 0; diff --git a/doc/help_pdp_warp.pd b/doc/help_pdp_warp.pd new file mode 100644 index 0000000..edde415 --- /dev/null +++ b/doc/help_pdp_warp.pd @@ -0,0 +1,61 @@ +#N canvas 237 21 712 664 10; +#X obj 248 367 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 283 243 dac~; +#X obj 257 135 metro 70; +#X obj 252 167 pdp_yqt; +#X obj 339 262 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X text 361 260 Mode ( 0=manual \, 1=auto ); +#X floatatom 339 292 5 0 0; +#X text 386 292 Manual control; +#X obj 249 323 pdp_warp; +#X obj 421 166 pdp_v4l; +#X obj 430 135 metro 70; +#X obj 475 101 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 432 102 stop; +#X msg 517 133 open /dev/video; +#X obj 422 335 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 422 387 pdp_control; +#X msg 422 360 thread \$1; +#X floatatom 422 448 5 0 0; +#X obj 422 417 route pdp_drop; +#X connect 1 0 11 0; +#X connect 2 0 12 0; +#X connect 3 0 2 0; +#X connect 4 0 12 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 11 1; +#X connect 8 0 11 0; +#X connect 9 0 7 0; +#X connect 11 0 12 0; +#X connect 12 0 17 0; +#X connect 12 3 10 0; +#X connect 12 4 10 1; +#X connect 13 0 17 1; +#X connect 15 0 17 2; +#X connect 17 0 0 0; +#X connect 18 0 17 0; +#X connect 19 0 18 0; +#X connect 20 0 19 0; +#X connect 21 0 19 0; +#X connect 22 0 18 0; +#X connect 23 0 25 0; +#X connect 24 0 27 0; +#X connect 25 0 24 0; +#X connect 27 0 26 0; diff --git a/doc/help_pdp_yvu2rgb.pd b/doc/help_pdp_yvu2rgb.pd new file mode 100644 index 0000000..b8665aa --- /dev/null +++ b/doc/help_pdp_yvu2rgb.pd @@ -0,0 +1,54 @@ +#N canvas 0 0 712 664 10; +#X obj 218 367 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 283 243 dac~; +#X obj 257 135 metro 70; +#X obj 200 297 pdp_yvu2rgb; +#X obj 252 167 pdp_yqt; +#X obj 421 166 pdp_v4l; +#X obj 430 135 metro 70; +#X obj 475 101 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 432 102 stop; +#X msg 517 133 open /dev/video; +#X obj 422 335 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 422 387 pdp_control; +#X msg 422 360 thread \$1; +#X floatatom 422 448 5 0 0; +#X obj 422 417 route pdp_drop; +#X connect 1 0 11 0; +#X connect 2 0 13 0; +#X connect 3 0 2 0; +#X connect 4 0 13 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 11 1; +#X connect 8 0 11 0; +#X connect 9 0 7 0; +#X connect 11 0 13 0; +#X connect 12 0 0 0; +#X connect 13 0 12 0; +#X connect 13 3 10 0; +#X connect 13 4 10 1; +#X connect 14 0 12 0; +#X connect 15 0 14 0; +#X connect 16 0 15 0; +#X connect 17 0 15 0; +#X connect 18 0 14 0; +#X connect 19 0 21 0; +#X connect 20 0 23 0; +#X connect 21 0 20 0; +#X connect 23 0 22 0; diff --git a/doc/help_sobel_edge.pd b/doc/help_sobel_edge.pd new file mode 100644 index 0000000..011a781 --- /dev/null +++ b/doc/help_sobel_edge.pd @@ -0,0 +1,54 @@ +#N canvas 237 21 712 664 10; +#X obj 218 367 pdp_xv; +#X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 123 136 loop \$1; +#X obj 124 114 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +1; +#X msg 370 44 open \$1; +#X obj 369 20 openpanel; +#X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 316 99 5 0 0; +#X msg 225 65 stop; +#X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 283 243 dac~; +#X obj 257 135 metro 70; +#X obj 252 167 pdp_yqt; +#X obj 421 166 pdp_v4l; +#X obj 430 135 metro 70; +#X obj 475 101 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 432 102 stop; +#X msg 517 133 open /dev/video; +#X obj 217 299 pdp_conv_sobel_edge; +#X obj 422 335 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 422 387 pdp_control; +#X msg 422 360 thread \$1; +#X floatatom 422 448 5 0 0; +#X obj 422 417 route pdp_drop; +#X connect 1 0 11 0; +#X connect 2 0 12 0; +#X connect 3 0 2 0; +#X connect 4 0 12 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 11 1; +#X connect 8 0 11 0; +#X connect 9 0 7 0; +#X connect 11 0 12 0; +#X connect 12 0 18 0; +#X connect 12 3 10 0; +#X connect 12 4 10 1; +#X connect 13 0 18 0; +#X connect 14 0 13 0; +#X connect 15 0 14 0; +#X connect 16 0 14 0; +#X connect 17 0 13 0; +#X connect 18 0 0 0; +#X connect 19 0 21 0; +#X connect 20 0 23 0; +#X connect 21 0 20 0; +#X connect 23 0 22 0; diff --git a/doc/pdp_affine.pd b/doc/pdp_affine.pd new file mode 100644 index 0000000..831d8ae --- /dev/null +++ b/doc/pdp_affine.pd @@ -0,0 +1,15 @@ +#N canvas 600 556 450 300 10; +#X obj 47 39 inlet; +#X obj 111 39 inlet; +#X obj 170 38 inlet; +#X obj 98 151 pdp_cheby; +#X obj 63 205 outlet; +#X text 26 7 for patch compatibility with older versions of pdp; +#X msg 119 98 coef 1 \$1; +#X msg 197 97 coef 0 \$1; +#X connect 0 0 3 0; +#X connect 1 0 6 0; +#X connect 2 0 7 0; +#X connect 3 0 4 0; +#X connect 6 0 3 0; +#X connect 7 0 3 0; diff --git a/doc/rs_pdp_live~.pd b/doc/rs_pdp_live~.pd new file mode 100644 index 0000000..33bda01 --- /dev/null +++ b/doc/rs_pdp_live~.pd @@ -0,0 +1,53 @@ +#N canvas 168 29 842 529 10; +#X text 460 551 written by Yves Degoyon (ydegoyon@free.fr); +#X floatatom 226 441 5 0 0 0 - - -; +#X text 272 440 Streaming status; +#X floatatom 221 419 5 0 0 0 - - -; +#X obj 36 449 pdp_xv; +#X text 526 79 Connect to a live stream; +#X text 325 118 Disconnect from the current stream; +#X msg 247 116 disconnect; +#X text 270 420 Number of video frames decoded; +#X text 457 527 ( at least from ffserver ); +#X text 23 547 NOTE : as for pdp_ffmpeg~ \, transmitting audio; +#X text 22 565 with the video stream produces some unsteady sound; +#X text 23 580 a prefered solution would be to use mp3cast~/mp3amp~ +; +#X msg 246 335 priority \$1; +#X floatatom 335 336 5 0 0 0 - - -; +#X text 385 357 ( optional \, if you know what you're doing ); +#X obj 70 493 outlet~; +#X obj 146 486 outlet~; +#X text 387 342 ([-20 \, 20 ] default : 0 ); +#X text 390 329 Set the priority of decoding thread; +#X obj 65 60 block~ 4096; +#X msg 247 225 connect \$1; +#X msg 246 78 connect http://localhost:8090/test1.mpg; +#X text 460 513 pdp_live~ : decodes a live video stream; +#X text 458 539 and reads most common files ( avi \, mpg \, .... ) +; +#X text 325 175 Read video file; +#X obj 247 154 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 247 176 openpanel; +#X msg 248 296 audio \$1; +#X obj 317 298 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X text 348 298 Activate decoding of audio ( default : off ); +#X obj 113 390 pdp_live~; +#X obj 247 200 makefilename file://%s; +#X connect 7 0 31 0; +#X connect 13 0 31 0; +#X connect 14 0 13 0; +#X connect 21 0 31 0; +#X connect 22 0 31 0; +#X connect 26 0 27 0; +#X connect 27 0 32 0; +#X connect 28 0 31 0; +#X connect 29 0 28 0; +#X connect 31 0 4 0; +#X connect 31 1 16 0; +#X connect 31 2 17 0; +#X connect 31 3 1 0; +#X connect 31 4 3 0; +#X connect 32 0 21 0; diff --git a/doc/rs_pdp_segsnd~.pd b/doc/rs_pdp_segsnd~.pd new file mode 100644 index 0000000..724b952 --- /dev/null +++ b/doc/rs_pdp_segsnd~.pd @@ -0,0 +1,99 @@ +#N canvas 234 119 905 538 10; +#X obj 255 34 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 117 65 loop \$1; +#X obj 117 40 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 1 1 +; +#X msg 280 33 open \$1; +#X obj 342 33 openpanel; +#X obj 412 34 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 303 69 5 0 0; +#X msg 212 35 stop; +#X obj 216 84 metro 70; +#X obj 262 174 pdp_v4l; +#X obj 271 143 metro 70; +#X obj 316 109 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 273 110 stop; +#X msg 336 144 open /dev/video; +#X text 113 410 written by Yves Degoyon ( ydegoyon@free.fr ); +#X obj 217 111 pdp_yqt; +#X obj 559 306 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 559 358 pdp_control; +#X msg 559 331 thread \$1; +#X floatatom 559 419 5 0 0; +#X obj 559 390 route pdp_drop; +#X text 113 393 pdp_segsnd~ : turn pixels from a segment into sound +; +#X obj 210 311 pdp_xv; +#X floatatom 237 243 5 0 0; +#X floatatom 284 244 5 0 0; +#X floatatom 333 244 5 0 0; +#X floatatom 385 244 5 0 0; +#X text 263 214 Segment coordinates :; +#X text 251 228 X1; +#X text 294 228 Y1; +#X text 341 228 X2; +#X text 395 228 Y2; +#X obj 41 207 block~ 128; +#X obj 407 361 outlet~; +#X obj 332 274 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X text 351 274 Random mode; +#X text 263 304 Output is; +#X text 264 317 scaled to; +#X text 267 330 [-1 \, 1 ]; +#X obj 407 332 tabread4~ \$0-music; +#X obj 407 305 *~ 1; +#X obj 487 145 soundfiler; +#X msg 482 34 bang; +#X msg 486 123 read -resize \$1 \$2; +#X msg 559 43 bang; +#X obj 633 142 table \$0-music; +#X obj 488 97 pack s s; +#X obj 559 66 f \$0; +#X obj 559 91 makefilename %d-music; +#X obj 482 60 opanel; +#X text 531 23 Step 2 : load a sample; +#X text 345 11 Step 1 : load a movie; +#X text 143 13 Step 3 : start playing; +#X obj 209 281 pdp_segsnd~; +#X connect 0 0 8 0; +#X connect 1 0 15 0; +#X connect 2 0 1 0; +#X connect 3 0 15 0; +#X connect 4 0 3 0; +#X connect 5 0 4 0; +#X connect 6 0 8 1; +#X connect 7 0 8 0; +#X connect 8 0 15 0; +#X connect 9 0 53 0; +#X connect 10 0 9 0; +#X connect 11 0 10 0; +#X connect 12 0 10 0; +#X connect 13 0 9 0; +#X connect 15 0 53 0; +#X connect 16 0 18 0; +#X connect 17 0 20 0; +#X connect 18 0 17 0; +#X connect 20 0 19 0; +#X connect 23 0 53 1; +#X connect 24 0 53 2; +#X connect 25 0 53 3; +#X connect 26 0 53 4; +#X connect 34 0 53 5; +#X connect 39 0 33 0; +#X connect 40 0 39 0; +#X connect 41 0 40 1; +#X connect 42 0 49 0; +#X connect 43 0 41 0; +#X connect 44 0 47 0; +#X connect 46 0 43 0; +#X connect 47 0 48 0; +#X connect 48 0 46 1; +#X connect 49 0 44 0; +#X connect 49 0 46 0; +#X connect 53 0 22 0; +#X connect 53 1 40 0; diff --git a/fonts/helmetr.ttf b/fonts/helmetr.ttf Binary files differnew file mode 100644 index 0000000..7f17c31 --- /dev/null +++ b/fonts/helmetr.ttf diff --git a/include/charmaps.h b/include/charmaps.h new file mode 100644 index 0000000..9caed3a --- /dev/null +++ b/include/charmaps.h @@ -0,0 +1,1292 @@ +#ifndef __bitmaps_h__ +#define __bitmaps_h__ + +#define CHARWIDTH 5 +#define CHARHEIGHT 8 +#define NBCHARS 128 + +typedef char charmap[CHARWIDTH*CHARHEIGHT]; + +static charmap charmaps[NBCHARS] = { +{ +0,0,0,0,0, +0,0,1,0,0, +0,1,1,1,0, +1,1,1,1,0, +0,1,1,1,0, +0,0,1,0,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,1,0,0, +0,0,1,0,0, +1,1,0,1,1, +0,1,0,1,0, +0,0,1,0,0, +0,1,0,1,0, +0,0,1,0,0, +}, +{ +0,0,0,0,0, +0,0,1,0,0, +0,1,0,1,0, +0,1,0,1,0, +0,1,1,1,0, +0,0,0,0,0, +1,0,0,1,0, +1,0,0,1,0, +}, +{ +0,0,0,0,0, +0,0,1,0,0, +1,1,1,1,0, +0,0,0,1,0, +1,1,1,1,0, +0,0,1,0,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,1,0,0, +0,1,0,1,0, +0,0,1,0,0, +0,1,0,1,0, +0,0,1,0,0, +0,1,0,1,0, +0,0,1,0,0, +}, +{ +0,1,0,1,0, +0,1,0,1,0, +0,1,1,1,0, +0,1,0,1,0, +0,1,0,1,0, +0,0,1,1,0, +0,0,0,1,0, +0,0,0,1,0, +}, +{ +1,1,1,0,0, +1,0,0,0,0, +1,1,0,0,0, +1,0,1,1,0, +1,0,1,0,0, +0,0,1,1,0, +0,0,1,0,0, +0,0,1,0,0, +}, +{ +0,1,1,0,0, +1,0,0,0,0, +0,1,1,0,0, +0,0,0,0,0, +0,0,1,1,0, +0,0,1,0,0, +0,0,1,1,0, +0,0,1,0,0, +}, +{ +1,0,0,0,0, +1,0,0,0,0, +1,0,0,0,0, +1,1,1,1,0, +0,0,1,1,0, +0,0,1,0,0, +0,0,1,1,0, +0,0,1,0,0, +}, +{ +0,0,0,0,0, +0,1,1,1,0, +0,1,0,1,0, +0,1,0,1,0, +0,1,1,1,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,1,0,0, +0,1,1,1,0, +0,0,1,0,0, +0,0,0,0,0, +0,1,1,1,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +1,0,0,1,0, +1,1,0,1,0, +1,0,1,1,0, +1,0,0,1,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,1,0, +}, +{ +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,1,0,0,0, +0,0,1,1,0, +0,0,0,1,0, +0,0,0,1,0, +0,0,0,1,0, +}, +{ +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +1,1,1,1,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +1,1,1,1,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,1,1,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +}, +{ +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,1,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +1,1,1,1,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +}, +{ +0,0,0,0,0, +0,1,1,1,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,1,1,1,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,1,1,1,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,1,1,1,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,1,1,1,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,1,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +}, +{ +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +1,1,1,1,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +}, +{ +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +1,1,1,1,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +1,1,1,1,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +}, +{ +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +}, +{ +0,0,0,0,0, +0,0,0,1,0, +0,0,1,0,0, +0,1,0,0,0, +0,0,1,0,0, +0,0,0,1,0, +0,1,1,1,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,0,0,0, +0,0,1,0,0, +0,0,0,1,0, +0,0,1,0,0, +0,1,0,0,0, +0,1,1,1,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,1,1,1,0, +0,1,0,1,0, +0,1,0,1,0, +0,1,0,1,0, +0,1,0,1,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,1,0, +1,1,1,1,0, +0,0,1,0,0, +1,1,1,1,0, +0,1,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,1,1,0, +0,1,0,0,0, +1,1,1,1,0, +0,1,0,0,0, +0,1,1,1,0, +1,1,0,1,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,1,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,0,0,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,0,1,0,0, +1,1,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,1,1,0,0, +1,0,1,0,0, +0,0,0,0,0, +}, +{ +0,1,0,0,0, +0,1,0,0,0, +1,0,1,0,0, +0,1,0,0,0, +0,0,1,0,0, +1,0,1,0,0, +0,1,0,0,0, +0,1,0,0,0, +}, +{ +0,0,0,0,0, +1,0,1,0,0, +0,0,1,0,0, +0,1,0,0,0, +0,1,0,0,0, +1,0,0,0,0, +1,0,1,0,0, +0,0,0,0,0, +}, +{ +0,1,0,0,0, +1,0,1,0,0, +0,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,1,0,0,0, +0,1,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,1,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,0,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,0,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +1,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,0,1,0,0, +0,1,0,0,0, +1,1,1,0,0, +0,1,0,0,0, +1,0,1,0,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +1,1,1,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +1,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +1,1,1,1,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,1,0,0, +0,0,1,0,0, +0,1,0,0,0, +0,1,0,0,0, +1,0,0,0,0, +1,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,0,0,0, +1,0,1,0,0, +1,1,1,1,0, +1,0,1,0,0, +1,0,1,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,0,0,0, +1,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +1,1,1,1,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,0,0,0, +1,0,1,0,0, +0,0,1,0,0, +0,1,0,0,0, +1,0,0,0,0, +1,1,1,1,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,1,1,1,0, +0,0,1,0,0, +0,1,0,0,0, +0,0,1,0,0, +1,0,1,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,1,0,0, +0,1,1,0,0, +1,0,1,0,0, +1,1,1,1,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,1,1,1,0, +1,0,0,0,0, +1,1,0,0,0, +0,0,1,0,0, +1,0,1,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,1,0,0, +1,0,0,0,0, +1,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,1,1,1,0, +0,0,1,0,0, +0,0,1,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,0,0,0, +1,0,1,0,0, +0,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,1,1,0,0, +0,0,1,0,0, +1,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,1,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,1,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,1,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,1,0,0,0, +1,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,0,1,0,0, +0,1,0,0,0, +1,0,0,0,0, +0,1,0,0,0, +0,0,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +1,1,1,1,0, +0,0,0,0,0, +1,1,1,1,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +1,0,0,0,0, +0,1,0,0,0, +0,0,1,0,0, +0,1,0,0,0, +1,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,0,0,0, +1,0,1,0,0, +0,0,1,0,0, +0,1,0,0,0, +0,0,0,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,0,0,0, +1,0,0,0,0, +0,1,1,0,0, +0,0,0,0,0, +}, +{ +0,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,1,1,1,0, +1,0,1,0,0, +1,0,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,1,0,0,0, +1,0,1,0,0, +1,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,0,0,0, +1,0,1,0,0, +1,0,0,0,0, +1,0,0,0,0, +1,0,1,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,1,1,1,0, +1,0,0,0,0, +1,1,1,1,0, +1,0,0,0,0, +1,0,0,0,0, +1,1,1,1,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,1,1,1,0, +1,0,0,0,0, +1,1,1,1,0, +1,0,0,0,0, +1,0,0,0,0, +1,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,0,0,0, +1,0,1,0,0, +1,0,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,1,1,1,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,1,1,1,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +1,1,1,1,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +1,0,1,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,0,0,0,0, +1,0,0,0,0, +1,0,0,0,0, +1,0,0,0,0, +1,0,0,0,0, +1,1,1,1,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,0,1,0,0, +1,1,1,1,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,1,0,0, +1,0,1,0,0, +1,1,1,1,0, +1,1,1,1,0, +1,0,1,0,0, +1,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,1,0,0,0, +1,0,0,0,0, +1,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,1,0,0,0, +0,1,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,0,0,0, +1,0,1,0,0, +0,1,0,0,0, +0,0,1,0,0, +1,0,1,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,1,1,1,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,1,1,1,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,1,1,1,0, +1,0,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,1,1,1,0, +0,0,1,0,0, +0,1,0,0,0, +0,1,0,0,0, +1,0,0,0,0, +1,1,1,1,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,1,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,0,0,0,0, +1,0,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +1,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,0,0,0, +1,0,1,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +1,1,1,1,0, +}, +{ +0,0,0,0,0, +1,0,0,0,0, +0,1,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +1,1,0,0,0, +0,0,1,0,0, +0,1,1,0,0, +1,0,1,0,0, +0,1,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +1,0,0,0,0, +1,0,0,0,0, +1,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,1,1,0,0, +1,0,0,0,0, +1,0,0,0,0, +1,0,0,0,0, +0,1,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,1,0,0, +0,0,1,0,0, +0,1,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,1,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,1,0,0,0, +1,0,1,0,0, +1,1,1,1,0, +1,0,0,0,0, +0,1,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,1,0,0, +0,1,0,0,0, +1,1,1,1,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,1,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,1,1,0,0, +0,0,1,0,0, +1,1,0,0,0, +}, +{ +0,0,0,0,0, +1,0,0,0,0, +1,0,0,0,0, +1,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,0,0,0, +0,0,0,0,0, +1,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +1,1,1,1,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,1,0,0, +0,0,0,0,0, +0,1,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +1,1,0,0,0, +}, +{ +0,0,0,0,0, +1,0,0,0,0, +1,0,0,0,0, +1,0,1,0,0, +1,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +1,0,1,0,0, +1,1,1,1,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +1,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +1,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,1,0,0,0, +1,0,0,0,0, +1,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,1,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,1,1,0,0, +0,0,1,0,0, +0,0,1,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,1,1,0,0, +1,0,0,0,0, +1,0,0,0,0, +1,0,0,0,0, +1,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +0,1,1,0,0, +1,0,0,0,0, +0,1,0,0,0, +0,0,1,0,0, +1,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +1,1,1,1,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,1,1,1,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,1,1,1,0, +1,0,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,1,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +1,0,1,0,0, +1,0,1,0,0, +1,0,1,0,0, +0,1,1,0,0, +0,0,1,0,0, +1,1,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +1,1,1,1,0, +0,0,1,0,0, +0,1,0,0,0, +1,0,0,0,0, +1,1,1,1,0, +0,0,0,0,0, +}, +{ +0,0,1,0,0, +0,1,0,0,0, +0,1,0,0,0, +1,0,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,0,1,0,0, +0,0,0,0,0, +}, +{ +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,0,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,0,0,0,0, +}, +{ +1,0,0,0,0, +0,1,0,0,0, +0,1,0,0,0, +0,0,1,0,0, +0,1,0,0,0, +0,1,0,0,0, +1,0,0,0,0, +0,0,0,0,0, +}, +{ +0,0,0,0,0, +0,0,0,0,0, +1,1,0,0,0, +0,1,1,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +} +}; + +#endif diff --git a/include/pdp_streaming.h b/include/pdp_streaming.h new file mode 100644 index 0000000..648c0c6 --- /dev/null +++ b/include/pdp_streaming.h @@ -0,0 +1,34 @@ +/* + * pdp_streaming.h : structure and defines for PDP packet streaming + * Copyright (C) 2001-2002 Yves Degoyon + * + */ + +/* + * this is the format of how a packet is transmitted + * between pdp_o and pdp_i + * it starts with a tag to recognize the beginning + * of a packet, then header informations ( width, height, timestamp ) + * and, finally, the bz2 compressed data + */ + +#include <time.h> +#include <sys/time.h> + +#define TAG_LENGTH 8 + +#define PDP_PACKET_START "SPDP" +#define PDP_PACKET_TAG PDP_PACKET_START"PAC" +#define PDP_PACKET_DIFF PDP_PACKET_START"DIF" +#define REGULAR 0 +#define HUFFMAN 1 + +typedef struct _hpacket +{ + char tag[TAG_LENGTH]; + int encoding; + int width; + int height; + struct timeval etime; // valid until 2038 + unsigned int clength; +} t_hpacket; diff --git a/include/yuv.h b/include/yuv.h new file mode 100644 index 0000000..554553d --- /dev/null +++ b/include/yuv.h @@ -0,0 +1,31 @@ +/* + * EffecTV - Realtime Digital Video Effector + * Copyright (C) 2001-2002 FUKUCHI Kentaro + * + * yuv.c: YUV(YCbCr) color system utilities + * + */ + +#include <math.h> + +/* + * conversion from YUV to RGB + * r = 1.164*(y-16) + 1.596*(v-128); + * g = 1.164*(y-16) - 0.813*(v-128) - 0.391*(u-128); + * b = 1.164*(y-16) + 2.018*(u-128); + * conversion from RGB to YUV + * y = 0.257*r + 0.504*g + 0.098*b + 16 + * u = -0.148*r - 0.291*g + 0.439*b + 128 + * v = 0.439*r - 0.368*g - 0.071*b + 128 + */ + +int yuv_init(void); +unsigned char yuv_RGBtoY(int rgb); +unsigned char yuv_RGBtoU(int rgb); +unsigned char yuv_RGBtoV(int rgb); +unsigned char yuv_YUVtoR(unsigned char y, unsigned char u, unsigned char v); +unsigned char yuv_YUVtoG(unsigned char y, unsigned char u, unsigned char v); +unsigned char yuv_YUVtoB(unsigned char y, unsigned char u, unsigned char v); +int yuv_YUVtoRGB(unsigned char y, unsigned char u, unsigned char v); +void yuv_Y122RGB( short int* packet, unsigned int *rgb, int width, int height ); +void yuv_RGB2Y12( unsigned int *rgb, short int* packet, int width, int height ); diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..e9de238 --- /dev/null +++ b/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/modules/Makefile b/modules/Makefile new file mode 100644 index 0000000..996f668 --- /dev/null +++ b/modules/Makefile @@ -0,0 +1,18 @@ +current: all_modules + +include ../Makefile + +OBJECTS = pdp_intrusion.o pdp_yqt.o pdp_simura.o pdp_underwatch.o \ + pdp_vertigo.o pdp_yvu2rgb.o pdp_lens.o pdp_baltan.o \ + pdp_aging.o pdp_ripple.o pdp_warp.o pdp_rev.o \ + pdp_mosaic.o pdp_edge.o pdp_spiral.o pdp_radioactiv.o \ + pdp_warhol.o pdp_nervous.o pdp_quark.o pdp_spigot.o \ + pdp_rec~.o pdp_o.o pdp_i.o pdp_mgrid.o pdp_ctrack.o \ + pdp_cycle.o pdp_transform.o pdp_shagadelic.o \ + pdp_dice.o pdp_puzzle.o pdp_text.o pdp_form.o \ + pdp_compose.o pdp_cmap.o pdp_aa.o pdp_ascii.o \ + pdp_ffmpeg~.o pdp_live~.o pdp_segsnd~.o pdp_noquark.o \ + pdp_juxta.o pdp_capture.o pdp_smuck.o pdp_lumafilt.o \ + pdp_transition.o pdp_imgloader.o pdp_imgsaver.o + +all_modules: $(OBJECTS) diff --git a/modules/Makefile.in b/modules/Makefile.in new file mode 100644 index 0000000..996f668 --- /dev/null +++ b/modules/Makefile.in @@ -0,0 +1,18 @@ +current: all_modules + +include ../Makefile + +OBJECTS = pdp_intrusion.o pdp_yqt.o pdp_simura.o pdp_underwatch.o \ + pdp_vertigo.o pdp_yvu2rgb.o pdp_lens.o pdp_baltan.o \ + pdp_aging.o pdp_ripple.o pdp_warp.o pdp_rev.o \ + pdp_mosaic.o pdp_edge.o pdp_spiral.o pdp_radioactiv.o \ + pdp_warhol.o pdp_nervous.o pdp_quark.o pdp_spigot.o \ + pdp_rec~.o pdp_o.o pdp_i.o pdp_mgrid.o pdp_ctrack.o \ + pdp_cycle.o pdp_transform.o pdp_shagadelic.o \ + pdp_dice.o pdp_puzzle.o pdp_text.o pdp_form.o \ + pdp_compose.o pdp_cmap.o pdp_aa.o pdp_ascii.o \ + pdp_ffmpeg~.o pdp_live~.o pdp_segsnd~.o pdp_noquark.o \ + pdp_juxta.o pdp_capture.o pdp_smuck.o pdp_lumafilt.o \ + pdp_transition.o pdp_imgloader.o pdp_imgsaver.o + +all_modules: $(OBJECTS) diff --git a/modules/pdp_aa.c b/modules/pdp_aa.c new file mode 100644 index 0000000..ee159f9 --- /dev/null +++ b/modules/pdp_aa.c @@ -0,0 +1,324 @@ +/* + * PiDiP module + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is an interface to aalib ( http://aa-project.sourceforge.net/aalib/ ) + * converting an image to ASCII art + * Written by Yves Degoyon ( ydegoyon@free.fr ) + */ + + +#include "pdp.h" +#include "yuv.h" +#include <math.h> +#include <aalib.h> + +#define MAX_OPTIONS 20 +#define MAX_OPTION_LENGTH 20 + +static char *pdp_aa_version = "pdp_aa: version 0.1, ASCII art output written by ydegoyon@free.fr "; + +typedef struct pdp_aa_struct +{ + t_object x_obj; + t_float x_f; + + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_outlet *x_outlet0; + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + /* aalib structures */ + aa_context *x_context; // a lot of things and image data + aa_renderparams x_renderparams; // rendering parameters + char* x_driver; // name of driver + t_int x_render; // rendering option + + char **x_aa_options; // aa options passed as arguments + t_int x_nb_options; // number of aa options + +} t_pdp_aa; + +static void pdp_aa_allocate(t_pdp_aa *x) +{ + if ( !strcmp( x->x_driver, "X11" ) ) + { + x->x_context = aa_init(&X11_d, &aa_defparams, NULL); + } + else if ( !strcmp( x->x_driver, "slang" ) ) + { + x->x_context = aa_init(&slang_d, &aa_defparams, NULL); + } + else if ( !strcmp( x->x_driver, "stdout" ) ) + { + x->x_context = aa_init(&stdout_d, &aa_defparams, NULL); + } + else if ( !strcmp( x->x_driver, "stderr" ) ) + { + x->x_context = aa_init(&stderr_d, &aa_defparams, NULL); + } + else + { + post( "pdp_aa : unsupported driver : %s : using X11", x->x_driver ); + strcpy( x->x_driver, "X11" ); + pdp_aa_allocate( x ); + return; + } + + if (x->x_context == NULL) + { + post("pdp_aa : severe error : cannot initialize aalib !!!"); + return; + } + else + { + post("pdp_aa : initialized context"); + } + aa_setfont( x->x_context, &aa_font8 ); +} + +static void pdp_aa_free_ressources(t_pdp_aa *x) +{ + // if ( x->x_context ) aa_close( x->x_context ); // this crashes unfortunately +} + +static void pdp_aa_render(t_pdp_aa *x, t_floatarg frender) +{ + if ( ((int)frender == 0) || ((int)frender == 1) ) + { + x->x_render = (int)frender; + } +} + +static void pdp_aa_driver(t_pdp_aa *x, t_symbol *sdriver) +{ + if ( ( !strcmp( sdriver->s_name, "X11" ) ) || + ( !strcmp( sdriver->s_name, "slang" ) ) || + ( !strcmp( sdriver->s_name, "stdout" ) ) || + ( !strcmp( sdriver->s_name, "stderr" ) ) ) + { + strcpy( x->x_driver, sdriver->s_name ); + } + else + { + post( "pdp_aa : unsupported driver : %s : using X11", sdriver->s_name ); + strcpy( x->x_driver, "X11" ); + } + pdp_aa_free_ressources(x); + pdp_aa_allocate(x); +} + +static void pdp_aa_process_yv12(t_pdp_aa *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + t_int i, pixsum; + t_int px, py, ppx, ppy; + t_int hratio, wratio; + + if ( ( (int)header->info.image.width != x->x_vwidth ) || + ( (int)header->info.image.height != x->x_vheight ) ) + { + pdp_aa_free_ressources( x ); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_aa_allocate( x ); + } + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + if ( aa_imgwidth(x->x_context) < x->x_vwidth ) + { + wratio = x->x_vwidth / aa_imgwidth(x->x_context); + } + else + { + wratio = 1; + } + if ( aa_imgheight(x->x_context) < x->x_vheight ) + { + hratio = x->x_vheight / aa_imgheight(x->x_context); + } + else + { + hratio = 1; + } + + for(py=1; py<x->x_vheight; py+=hratio) + { + for(px=0; px<x->x_vwidth; px+=wratio) + { + pixsum = 0; + for ( ppy=0; ppy<hratio; ppy++ ) + { + for ( ppx=0; ppx<wratio; ppx++ ) + { + pixsum += (data[(py+ppy)*x->x_vwidth + (px+ppx)]>>7); + } + } + aa_putpixel(x->x_context, px/wratio, py/hratio, pixsum/(wratio*hratio)); + } + } + + if ( x->x_render ) + { + aa_fastrender(x->x_context, 0, 0, aa_scrwidth(x->x_context), aa_scrheight(x->x_context)); + aa_flush( x->x_context ); + } + + // post( "pdp_aa : ascii text : %s", x->x_context->textbuffer ); + + memcpy( newdata, data, (x->x_vsize+(x->x_vsize>>1))<<1 ); + + return; +} + +static void pdp_aa_sendpacket(t_pdp_aa *x) +{ + /* delete source packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_aa_process(t_pdp_aa *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_aa_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding) + { + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_aa_process_yv12, pdp_aa_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_aa_process */ + break; + + } + } + +} + +static void pdp_aa_input_0(t_pdp_aa *x, t_symbol *s, t_floatarg f) +{ + + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + { + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + } + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)) + { + /* add the process method and callback to the process queue */ + pdp_aa_process(x); + } + +} + +static void pdp_aa_free(t_pdp_aa *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); + pdp_aa_free_ressources(x); + for (i=0; i<MAX_OPTIONS; i++) + { + if (x->x_aa_options[ i ]) freebytes( x->x_aa_options[ i ], MAX_OPTION_LENGTH ); + } + if (x->x_aa_options) freebytes( x->x_aa_options, MAX_OPTIONS*sizeof(char*) ); + if (x->x_driver) freebytes( x->x_driver, MAX_OPTION_LENGTH ); +} + +t_class *pdp_aa_class; + +void *pdp_aa_new(void) +{ + int i; + + t_pdp_aa *x = (t_pdp_aa *)pd_new(pdp_aa_class); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + x->x_driver = (char*) getbytes( MAX_OPTION_LENGTH ); + strcpy( x->x_driver, "X11" ); + x->x_render = 1; + + // aa_setsupported( x->x_context, AA_EXTENDED ); + x->x_aa_options = (char **) getbytes( MAX_OPTIONS*sizeof(char*) ); + for (i=0; i<MAX_OPTIONS; i++) + { + x->x_aa_options[ i ] = (char*) getbytes( MAX_OPTION_LENGTH ); + } + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_aa_setup(void) +{ + post( pdp_aa_version ); + pdp_aa_class = class_new(gensym("pdp_aa"), (t_newmethod)pdp_aa_new, + (t_method)pdp_aa_free, sizeof(t_pdp_aa), 0, A_NULL); + + class_addmethod(pdp_aa_class, (t_method)pdp_aa_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_aa_class, (t_method)pdp_aa_driver, gensym("driver"), A_SYMBOL, A_NULL); + class_addmethod(pdp_aa_class, (t_method)pdp_aa_render, gensym("render"), A_FLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_aging.c b/modules/pdp_aging.c new file mode 100644 index 0000000..f2317b2 --- /dev/null +++ b/modules/pdp_aging.c @@ -0,0 +1,380 @@ +/* + * PiDiP module + * Copyright (c) by Yves Degoyon ( ydegoyon@free.fr ) + * + * 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. + * + */ + +/* This object is an adaptation of aging effect from effectv + * Originally written by Fukuchi Kentaro & others + * Pd-fication by Yves Degoyon + */ + + + +#include "pdp.h" +#include <math.h> + +static char *pdp_aging_version = "pdp_aging: version 0.1, port of aging from effectv( Fukuchi Kentaro ) adapted by Yves Degoyon (ydegoyon@free.fr)"; + +#define PDP_AGING_MAX_SCRATCHES 100 +static unsigned int fastrand_val; +#define inline_fastrand() (fastrand_val=fastrand_val*1103515245+12345) + +typedef struct _scratch +{ + t_int life; + t_int x; + t_int dx; + t_int init; +} scratch; + +typedef struct pdp_aging_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + t_int x_area_scale; + t_int x_nb_scratches; + t_int x_dust_interval; + t_int x_pits_interval; + scratch x_scratches[PDP_AGING_MAX_SCRATCHES]; + +} t_pdp_aging; + +static void pdp_aging_area_scale(t_pdp_aging *x, t_floatarg fscale ) +{ + if ( (int) fscale > 1 ) + { + x->x_area_scale = (int)fscale; + } +} + +static void pdp_aging_scratches(t_pdp_aging *x, t_floatarg fscratches ) +{ + if ( ( (int)fscratches < PDP_AGING_MAX_SCRATCHES ) && ( (int)fscratches>=0) ) + { + x->x_nb_scratches = (int)fscratches; + } +} + +static void pdp_aging_coloraging(t_pdp_aging *x, short int *src, short int *dest) +{ + short int a, b; + int i; + + for(i=0; i<x->x_vsize; i++) + { + a = *src++; + b = (a & 0xfcfc)>>2; + *dest++ = a - b + 0x1818 + ((inline_fastrand()>>8)&0x1010); + } + // set all to b&w + for(i=x->x_vsize; i<( x->x_vsize + (x->x_vsize>>1) ); i++) + { + *dest++ = 0; + } +} + +static void pdp_aging_scratching(t_pdp_aging *x, short int *dest) +{ + int i, y, y1, y2; + short int *p, a, b; + const int width = x->x_vwidth; + const int height = x->x_vheight; + + for(i=0; i<x->x_nb_scratches; i++) + { + if(x->x_scratches[i].life) + { + x->x_scratches[i].x = x->x_scratches[i].x + x->x_scratches[i].dx; + if(x->x_scratches[i].x < 0 || x->x_scratches[i].x > width*256) + { + x->x_scratches[i].life = 0; + break; + } + p = dest + (x->x_scratches[i].x>>8); + if(x->x_scratches[i].init) + { + y1 = x->x_scratches[i].init; + x->x_scratches[i].init = 0; + } + else + { + y1 = 0; + } + x->x_scratches[i].life--; + if(x->x_scratches[i].life) + { + y2 = height; + } + else + { + y2 = inline_fastrand() % height; + } + for(y=y1; y<y2; y++) + { + a = *p & 0xfeff; + a += 0x2020; + b = a & 0x10100; + *p = a | (b - (b>>8)); + p += width; + } + } + else + { + if((inline_fastrand()&0xf0000000) == 0) + { + x->x_scratches[i].life = 2 + (inline_fastrand()>>27); + x->x_scratches[i].x = inline_fastrand() % (width * 256); + x->x_scratches[i].dx = ((int)inline_fastrand())>>23; + x->x_scratches[i].init = (inline_fastrand() % (height-1))+1; + } + } + } +} + +static void pdp_aging_dusts(t_pdp_aging *x, short int *dest) +{ + int dx[8] = { 1, 1, 0, -1, -1, -1, 0, 1}; + int dy[8] = { 0, -1, -1, -1, 0, 1, 1, 1}; + int i, j; + int dnum; + int d, len; + int px, py; + const int width = x->x_vwidth; + const int height = x->x_vheight; + + if(x->x_dust_interval == 0) + { + if((inline_fastrand()&0xf0000000) == 0) { + x->x_dust_interval = inline_fastrand()>>29; + } + return; + } + + dnum = x->x_area_scale*4 + (inline_fastrand()>>27); + for(i=0; i<dnum; i++) + { + px = inline_fastrand()%width; + py = inline_fastrand()%height; + d = inline_fastrand()>>29; + len = inline_fastrand()%x->x_area_scale + 5; + for(j=0; j<len; j++) { + dest[py*width + px] = 0x1010; + py += dy[d]; + px += dx[d]; + if(px<0 || px>=width) break; + if(py<0 || py>=height) break; + d = (d + inline_fastrand()%3 - 1) & 7; + } + } + x->x_dust_interval--; +} + +static void pdp_aging_pits(t_pdp_aging *x, short int *dest) +{ + int i, j; + int pnum, size, pnumscale; + int px, py; + const int width = x->x_vwidth; + const int height = x->x_vheight; + + pnumscale = x->x_area_scale * 2; + if(x->x_pits_interval) + { + pnum = pnumscale + (inline_fastrand()%pnumscale); + x->x_pits_interval--; + } + else + { + pnum = inline_fastrand()%pnumscale; + if((inline_fastrand()&0xf8000000) == 0) + { + x->x_pits_interval = (inline_fastrand()>>28) + 20; + } + } + for(i=0; i<pnum; i++) + { + px = inline_fastrand()%(width-1); + py = inline_fastrand()%(height-1); + size = inline_fastrand()>>28; + for(j=0; j<size; j++) + { + px = px + inline_fastrand()%3-1; + py = py + inline_fastrand()%3-1; + if(px<0 || px>=width) break; + if(py<0 || py>=height) break; + dest[py*width + px] = 0xc0c0; + } + } +} + +static void pdp_aging_process_yv12(t_pdp_aging *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + int i; + + unsigned int totalnbpixels; + unsigned int u_offset; + unsigned int v_offset; + unsigned int totnbpixels; + short int *poy, *pou, *pov, *pny, *pnu, *pnv; + int px, py; + int noy, pos, nox; + int *p; + + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + + totalnbpixels = x->x_vsize; + u_offset = x->x_vsize; + v_offset = x->x_vsize + (x->x_vsize>>2); + totnbpixels = x->x_vsize + (x->x_vsize>>1); + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + pdp_aging_coloraging( x, data, newdata ); + pdp_aging_scratching( x, newdata ); + pdp_aging_pits( x, newdata ); + if ( x->x_area_scale > 1 ) pdp_aging_dusts( x, newdata ); + + return; +} + +static void pdp_aging_sendpacket(t_pdp_aging *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_aging_process(t_pdp_aging *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_aging_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_aging_process_yv12, pdp_aging_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // pdp_aging_process_packet(x); + break; + + default: + /* don't know the type, so dont pdp_aging_process */ + break; + + } + } + +} + +static void pdp_aging_input_0(t_pdp_aging *x, t_symbol *s, t_floatarg f) +{ + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_aging_process(x); + + } + +} + +static void pdp_aging_free(t_pdp_aging *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); + +} + +t_class *pdp_aging_class; + +void *pdp_aging_new(void) +{ + int i; + + t_pdp_aging *x = (t_pdp_aging *)pd_new(pdp_aging_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("area_scale")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("scratches")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_nb_scratches = 7; + x->x_area_scale=5; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_aging_setup(void) +{ +// post( pdp_aging_version ); + pdp_aging_class = class_new(gensym("pdp_aging"), (t_newmethod)pdp_aging_new, + (t_method)pdp_aging_free, sizeof(t_pdp_aging), 0, A_NULL); + + class_addmethod(pdp_aging_class, (t_method)pdp_aging_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_aging_class, (t_method)pdp_aging_area_scale, gensym("area_scale"), A_FLOAT, A_NULL); + class_addmethod(pdp_aging_class, (t_method)pdp_aging_scratches, gensym("scratches"), A_FLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_aging.c~ b/modules/pdp_aging.c~ new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/modules/pdp_aging.c~ diff --git a/modules/pdp_ascii.c b/modules/pdp_ascii.c new file mode 100644 index 0000000..5d2dc50 --- /dev/null +++ b/modules/pdp_ascii.c @@ -0,0 +1,258 @@ +/* + * PiDiP module + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is an ASCII art object replacing blocks with ASCII characters + * Written by Yves Degoyon ( ydegoyon@free.fr ) + */ + + +#include "pdp.h" +#include "yuv.h" +#include "charmaps.h" +#include <math.h> + +static char *pdp_ascii_version = "pdp_ascii: version 0.1, ASCII art output written by ydegoyon@free.fr"; + +typedef struct pdp_ascii_struct +{ + t_object x_obj; + t_float x_f; + + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_outlet *x_outlet0; + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + t_int x_color; // rendering color option + t_int x_brightness; // added value for brightness + t_float x_ratio; // character to pixel ratio + +} t_pdp_ascii; + +static void pdp_ascii_color(t_pdp_ascii *x, t_floatarg fcolor) +{ + if ( ((int)fcolor == 0) || ((int)fcolor == 1) ) + { + x->x_color = (int)fcolor; + } +} + +static void pdp_ascii_ratio(t_pdp_ascii *x, t_floatarg fratio) +{ + if ( ( fratio > 0) && ( x->x_ratio < x->x_vwidth/2 ) ) + { + x->x_ratio = fratio; + } +} + +static void pdp_ascii_brightness(t_pdp_ascii *x, t_floatarg fbrightness) +{ + if ( ((int)fbrightness > 0) && ((int)fbrightness < 255) ) + { + x->x_brightness = (int)fbrightness; + } +} + +static void pdp_ascii_process_yv12(t_pdp_ascii *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + t_int i, pixsum; + t_int px, py, ppx, ppy; + t_int rank, value; + t_int pwidth, pheight; + + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + memset( newdata, 0x00, (x->x_vsize+(x->x_vsize>>1))<<1 ); + + pwidth = (int) CHARWIDTH*x->x_ratio; + if (pwidth==0) pwidth=1; + if (pwidth>x->x_vwidth) return; + pheight = (int) CHARHEIGHT*x->x_ratio; + if (pheight==0) pheight=1; + if (pheight>x->x_vheight) return; + + for(py=1; py<x->x_vheight; py+=pheight) + { + for(px=0; px<x->x_vwidth; px+=pwidth) + { + pixsum = 0; + for ( ppy=0; ppy<pheight; ppy++ ) + { + for ( ppx=0; ppx<pwidth; ppx++ ) + { + pixsum += (data[(py+ppy)*x->x_vwidth + (px+ppx)]>>7); + } + } + rank = (pixsum/(pheight*pwidth))/2; // set the chosen character + for ( ppy=0; ppy<pheight; ppy++ ) + { + for ( ppx=0; ppx<pwidth; ppx++ ) + { + if ( ( px+ppx > x->x_vwidth ) || + ( py+ppy > x->x_vheight ) ) + { + break; + } + if ( charmaps[rank][((int)(ppy/x->x_ratio))*CHARWIDTH+((int)(ppx/x->x_ratio))] ) + { + value = ( (2*rank+x->x_brightness) > 255 ) ? 255 : (2*rank+x->x_brightness); + newdata[(py+ppy)*x->x_vwidth+(px+ppx)] = (value)<<7; + if ( x->x_color ) + { + newdata[x->x_vsize+((py+ppy)>>1)*(x->x_vwidth>>1)+((px+ppx)>>1)] = + data[x->x_vsize+((py+ppy)>>1)*(x->x_vwidth>>1)+((px+ppx)>>1)]; + newdata[x->x_vsize+(x->x_vsize>>2)+((py+ppy)>>1)*(x->x_vwidth>>1)+((px+ppx)>>1)] = + data[x->x_vsize+(x->x_vsize>>2)+((py+ppy)>>1)*(x->x_vwidth>>1)+((px+ppx)>>1)]; + } + } + } + } + } + } + + return; +} + +static void pdp_ascii_sendpacket(t_pdp_ascii *x) +{ + /* delete source packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_ascii_process(t_pdp_ascii *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_ascii_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding) + { + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_ascii_process_yv12, pdp_ascii_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_ascii_process */ + break; + + } + } + +} + +static void pdp_ascii_input_0(t_pdp_ascii *x, t_symbol *s, t_floatarg f) +{ + + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + { + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + } + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)) + { + /* add the process method and callback to the process queue */ + pdp_ascii_process(x); + } + +} + +static void pdp_ascii_free(t_pdp_ascii *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); +} + +t_class *pdp_ascii_class; + +void *pdp_ascii_new(void) +{ + int i; + + t_pdp_ascii *x = (t_pdp_ascii *)pd_new(pdp_ascii_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ratio")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + x->x_color = 1; + x->x_ratio = 1.; + x->x_brightness = 25; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_ascii_setup(void) +{ + post( pdp_ascii_version ); + pdp_ascii_class = class_new(gensym("pdp_ascii"), (t_newmethod)pdp_ascii_new, + (t_method)pdp_ascii_free, sizeof(t_pdp_ascii), 0, A_NULL); + + class_addmethod(pdp_ascii_class, (t_method)pdp_ascii_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_ascii_class, (t_method)pdp_ascii_color, gensym("color"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_ascii_class, (t_method)pdp_ascii_brightness, gensym("brightness"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_ascii_class, (t_method)pdp_ascii_ratio, gensym("ratio"), A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_baltan.c b/modules/pdp_baltan.c new file mode 100644 index 0000000..b75c074 --- /dev/null +++ b/modules/pdp_baltan.c @@ -0,0 +1,232 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is an adaptation of baltan effect from freej + * Originally written by Fukuchi Kentarou + * Adapted by Yves Degoyon + * Do not expect it to behave like effectv : well, it does things .... + */ + + + +#include "pdp.h" +#include <math.h> + +#define PLANES 32 + +#define STRIDE 8 + +typedef struct pdp_baltan_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_int *x_planebuf; + t_int x_plane; + t_int x_pixels; + t_int x_dfts; /* the factor */ + +} t_pdp_baltan; + +static void pdp_baltan_process_yv12(t_pdp_baltan *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + + unsigned int w = header->info.image.width; + unsigned int h = header->info.image.height; + + unsigned int size = w*h; + unsigned int totalnbpixels = size; + unsigned int u_offset = size; + unsigned int v_offset = size + (size>>2); + unsigned int totnbpixels = size + (size>>1); + + t_int i, cf; + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = w; + newheader->info.image.height = h; + + /* allocate buffers if necessary */ + if ( ( x->x_planebuf == NULL ) || ( (int)size != x->x_pixels ) ) + { + if ( x->x_planebuf ) freebytes( x->x_planebuf, x->x_pixels*PLANES*sizeof(t_int) ); + + x->x_pixels = size; + x->x_planebuf = (t_int*)getbytes(x->x_pixels*PLANES*sizeof(t_int)); + post("pdp_baltan : allocated plane buffer (size=%d)", x->x_pixels*PLANES*sizeof(t_int) ); + bzero(x->x_planebuf, x->x_pixels*PLANES*sizeof(t_int)); + x->x_plane = 0; + if ( !x->x_planebuf ) + { + post( "pdp_baltan : serious error : unable to allocate buffers " ) ; + return; + } + } + + /* process data packet */ + for(i=0; i<x->x_pixels; i++) + { + *(x->x_planebuf+x->x_plane*x->x_pixels+i) = (data[i] & x->x_dfts)>>2; + } + + cf = x->x_plane & (STRIDE-1); + + for(i=0; i<x->x_pixels; i++) { + newdata[i] = *(x->x_planebuf+cf*x->x_pixels+i) + + *(x->x_planebuf+((cf+STRIDE)*x->x_pixels)+i) + + *(x->x_planebuf+((cf+2*STRIDE)*x->x_pixels)+i) + + *(x->x_planebuf+((cf+3*STRIDE)*x->x_pixels)+i); + *(x->x_planebuf+x->x_plane*x->x_pixels+i) = (newdata[i]&x->x_dfts)>>2; + } + + x->x_plane++; + x->x_plane = x->x_plane & (PLANES-1); + + /* leave the colors unchanged */ + for( i=size; i<(int)totnbpixels; i++) + { + newdata[i] = data[i]; + } + + return; +} + +static void pdp_baltan_sendpacket(t_pdp_baltan *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_baltan_process(t_pdp_baltan *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_baltan_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_baltan_process_yv12, pdp_baltan_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // pdp_baltan_process_packet(x); + break; + + default: + /* don't know the type, so dont pdp_baltan_process */ + break; + + } + } +} + +static void pdp_baltan_input_0(t_pdp_baltan *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_baltan_process(x); + + } +} + +static void pdp_baltan_dfts(t_pdp_baltan *x, t_floatarg fdfts ) +{ + x->x_dfts = (t_int)fdfts; +} + +static void pdp_baltan_free(t_pdp_baltan *x) +{ + if ( x->x_planebuf ) freebytes( x->x_planebuf, x->x_pixels*PLANES*sizeof(t_int) ); + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); +} + +t_class *pdp_baltan_class; + +void *pdp_baltan_new(void) +{ + int i; + + t_pdp_baltan *x = (t_pdp_baltan *)pd_new(pdp_baltan_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("dfts")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_planebuf = NULL; + x->x_pixels = 0; + x->x_dfts = 0xfcfcfc; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_baltan_setup(void) +{ + + + pdp_baltan_class = class_new(gensym("pdp_baltan"), (t_newmethod)pdp_baltan_new, + (t_method)pdp_baltan_free, sizeof(t_pdp_baltan), 0, A_NULL); + + class_addmethod(pdp_baltan_class, (t_method)pdp_baltan_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_baltan_class, (t_method)pdp_baltan_dfts, gensym("dfts"), A_DEFFLOAT, A_NULL); + + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_capture.c b/modules/pdp_capture.c new file mode 100644 index 0000000..f7e9292 --- /dev/null +++ b/modules/pdp_capture.c @@ -0,0 +1,938 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object lets you capture a portion of the screen + * and turn it into pdp packets + * ( inspired by ImageMagick code ) + */ + +#include "pdp.h" +#include "yuv.h" +#include <math.h> +#include <assert.h> +#include <X11/Xlib.h> +#include <X11/Xatom.h> +#include <magick/api.h> +#include <magick/magick.h> +#include <magick/xwindow.h> + +#define PDP_DISPLAY_LENGTH 1024 + +static char *pdp_capture_version = "pdp_capture: version 0.1, capture of screen written by Yves Degoyon (ydegoyon@free.fr)"; + +typedef struct pdp_capture_struct +{ + t_object x_obj; + + t_outlet *x_outlet0; + t_int x_packet0; + short int *x_data; + t_pdp *x_header; + t_int x_displayopen; + + char *x_display; + t_int x_screen; + t_int x_x; + t_int x_y; + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + Image *x_Ximage; + Display *x_dpy; +} t_pdp_capture; + +/***********************************************/ +/* this code is borrowed from ImageMagick */ +/* but not exported, sorry, guys and girls, */ +/* i only need that */ +/***********************************************/ + +static Window XMyGetSubwindow(t_pdp_capture *o, Display *display, Window window, int x, int y) +{ + Window source_window, target_window; + int status, x_offset, y_offset; + + assert(display != (Display *) NULL); + source_window=XRootWindow(display, o->x_screen); + if (window == (Window) NULL) + { + return(source_window); + } + target_window=window; + for ( ; ; ) + { + status=XTranslateCoordinates(display,source_window,window,x,y, &x_offset,&y_offset,&target_window); + if (status != 1) + { + break; + } + if (target_window == (Window) NULL) + { + break; + } + source_window=window; + window=target_window; + x=x_offset; + y=y_offset; + } + if (target_window == (Window) NULL) + { + target_window=window; + } + return(target_window); +} + +static Window XMyClientWindow(t_pdp_capture *o, Display *display,Window target_window) +{ + Atom state, type; + int format, status; + unsigned char *data; + unsigned long after, number_items; + Window client_window; + + assert(display != (Display *) NULL); + state=XInternAtom(display,"WM_STATE",1); + if (state == (Atom) NULL) + { + return(target_window); + } + type=(Atom) NULL; + status=XGetWindowProperty(display,target_window,state,0L,0L,0, (Atom) AnyPropertyType,&type,&format,&number_items,&after,&data); + if ((status == Success) && (type != (Atom) NULL)) + { + return(target_window); + } + client_window=XWindowByProperty(display,target_window,state); + if (client_window == (Window) NULL) + { + return(target_window); + } + return(client_window); +} + +static Image *XMyGetWindowImage(t_pdp_capture *o, Display *display,const Window window, const unsigned int level) +{ + typedef struct _ColormapInfo + { + Colormap colormap; + XColor *colors; + struct _ColormapInfo *next; + } ColormapInfo; + + typedef struct _WindowInfo + { + Window window, parent; + Visual *visual; + Colormap colormap; + XSegment bounds; + RectangleInfo crop_info; + } WindowInfo; + + IndexPacket index; + int display_height, display_width, id, status, x_offset, y_offset; + RectangleInfo crop_info; + register IndexPacket *indexes; + register int i; + static ColormapInfo *colormap_info = (ColormapInfo *) NULL; + static int max_windows = 0, number_windows = 0; + static WindowInfo *window_info; + Window child, root_window; + XWindowAttributes window_attributes; + + assert(display != (Display *) NULL); + status=XGetWindowAttributes(display,window,&window_attributes); + if ((status == 0) || (window_attributes.map_state != IsViewable)) + { + return((Image *) NULL); + } + root_window=XRootWindow(display, o->x_screen ); + (void) XTranslateCoordinates(display,window,root_window,0,0,&x_offset, &y_offset,&child); + crop_info.x=x_offset; + crop_info.y=y_offset; + crop_info.width=window_attributes.width; + crop_info.height=window_attributes.height; + if (crop_info.x < 0) + { + crop_info.width+=crop_info.x; + crop_info.x=0; + } + if (crop_info.y < 0) + { + crop_info.height+=crop_info.y; + crop_info.y=0; + } + display_width=XDisplayWidth(display, o->x_screen); + if ((int) (crop_info.x+crop_info.width) > display_width) + { + crop_info.width=display_width-crop_info.x; + } + display_height=XDisplayHeight(display, o->x_screen); + if ((int) (crop_info.y+crop_info.height) > display_height) + { + crop_info.height=display_height-crop_info.y; + } + if (number_windows >= max_windows) + { + max_windows+=1024; + if (window_info == (WindowInfo *) NULL) + { + window_info=(WindowInfo *) AcquireMemory(max_windows*sizeof(WindowInfo)); + } + else + { + ReacquireMemory((void **) &window_info,max_windows*sizeof(WindowInfo)); + } + } + if (window_info == (WindowInfo *) NULL) + { + post("pdp_capture : MemoryAllocationFailed : UnableToReadXImage"); + return((Image *) NULL); + } + id=number_windows++; + window_info[id].window=window; + window_info[id].visual=window_attributes.visual; + window_info[id].colormap=window_attributes.colormap; + window_info[id].bounds.x1=(short) crop_info.x; + window_info[id].bounds.y1=(short) crop_info.y; + window_info[id].bounds.x2=(short) (crop_info.x+(int) crop_info.width-1); + window_info[id].bounds.y2=(short) (crop_info.y+(int) crop_info.height-1); + crop_info.x-=x_offset; + crop_info.y-=y_offset; + + window_info[id].crop_info=crop_info; + if (level != 0) + { + unsigned int number_children; + Window *children; + + status=XQueryTree(display,window,&root_window,&window_info[id].parent, &children,&number_children); + for (i=0; i < id; i++) + { + if ((window_info[i].window == window_info[id].parent) && + (window_info[i].visual == window_info[id].visual) && + (window_info[i].colormap == window_info[id].colormap)) + { + if ((window_info[id].bounds.x1 <= window_info[i].bounds.x1) || + (window_info[id].bounds.x1 >= window_info[i].bounds.x2) || + (window_info[id].bounds.y1 <= window_info[i].bounds.y1) || + (window_info[id].bounds.y1 >= window_info[i].bounds.y2)) + { + number_windows--; + break; + } + } + } + if ((status == 1) && (number_children != 0)) + { + (void) XFree((void *) children); + } + } + if (level <= 1) + { + ColormapInfo *next; + Image *composite_image, *image; + int y; + register int j, x; + register PixelPacket *q; + register unsigned long pixel; + unsigned int import, number_colors; + XColor *colors; + XImage *ximage; + + image=(Image *) NULL; + for (id=0; id < number_windows; id++) + { + import=(window_info[id].bounds.x2 >= window_info[0].bounds.x1) && + (window_info[id].bounds.x1 <= window_info[0].bounds.x2) && + (window_info[id].bounds.y2 >= window_info[0].bounds.y1) && + (window_info[id].bounds.y1 <= window_info[0].bounds.y2); + for (j=0; j < id; j++) + { + if ((window_info[id].visual == window_info[j].visual) && + (window_info[id].colormap == window_info[j].colormap) && + (window_info[id].bounds.x1 >= window_info[j].bounds.x1) && + (window_info[id].bounds.y1 >= window_info[j].bounds.y1) && + (window_info[id].bounds.x2 <= window_info[j].bounds.x2) && + (window_info[id].bounds.y2 <= window_info[j].bounds.y2)) + { + import=0; + } + else + { + if ((window_info[id].visual != window_info[j].visual) || + (window_info[id].colormap != window_info[j].colormap)) + { + if ((window_info[id].bounds.x2 > window_info[j].bounds.x1) && + (window_info[id].bounds.x1 < window_info[j].bounds.x2) && + (window_info[id].bounds.y2 > window_info[j].bounds.y1) && + (window_info[id].bounds.y1 < window_info[j].bounds.y2)) + { + import=1; + } + } + } + } + if (!import) + { + continue; + } + // post( "pdp_capture : get image : %ld [%d,%d,%d,%d]", window_info[id].window, + // (int) window_info[id].crop_info.x, + // (int) window_info[id].crop_info.y, + // (unsigned int) window_info[id].crop_info.width, + // (unsigned int) window_info[id].crop_info.height ); + ximage=XGetImage(display,window_info[id].window, + (int) window_info[id].crop_info.x,(int) window_info[id].crop_info.y, + (unsigned int) window_info[id].crop_info.width, + (unsigned int) window_info[id].crop_info.height,AllPlanes,ZPixmap); + if (ximage == (XImage *) NULL) + { + continue; + } + number_colors=0; + colors=(XColor *) NULL; + if (window_info[id].colormap != (Colormap) NULL) + { + ColormapInfo *p; + + number_colors=window_info[id].visual->map_entries; + for (p=colormap_info; p != (ColormapInfo *) NULL; p=p->next) + { + if (p->colormap == window_info[id].colormap) + { + break; + } + } + if (p == (ColormapInfo *) NULL) + { + colors=(XColor *) AcquireMemory(number_colors*sizeof(XColor)); + if (colors == (XColor *) NULL) + { + XDestroyImage(ximage); + return((Image *) NULL); + } + if ((window_info[id].visual->storage_class != DirectColor) && + (window_info[id].visual->storage_class != TrueColor)) + { + for (i=0; i < (int) number_colors; i++) + { + colors[i].pixel=i; + colors[i].pad=0; + } + } + else + { + unsigned long blue, blue_bit, green, green_bit, red, red_bit; + + red=0; + green=0; + blue=0; + red_bit=window_info[id].visual->red_mask & + (~(window_info[id].visual->red_mask)+1); + green_bit=window_info[id].visual->green_mask & + (~(window_info[id].visual->green_mask)+1); + blue_bit=window_info[id].visual->blue_mask & + (~(window_info[id].visual->blue_mask)+1); + for (i=0; i < (int) number_colors; i++) + { + colors[i].pixel=red | green | blue; + colors[i].pad=0; + red+=red_bit; + if (red > window_info[id].visual->red_mask) + red=0; + green+=green_bit; + if (green > window_info[id].visual->green_mask) + green=0; + blue+=blue_bit; + if (blue > window_info[id].visual->blue_mask) + blue=0; + } + } + (void) XQueryColors(display,window_info[id].colormap,colors, (int) number_colors); + p=(ColormapInfo *) AcquireMemory(sizeof(ColormapInfo)); + if (p == (ColormapInfo *) NULL) + return((Image *) NULL); + p->colormap=window_info[id].colormap; + p->colors=colors; + p->next=colormap_info; + colormap_info=p; + } + colors=p->colors; + } + composite_image=AllocateImage((ImageInfo *) NULL); + if (composite_image == (Image *) NULL) + { + XDestroyImage(ximage); + return((Image *) NULL); + } + if ((window_info[id].visual->storage_class != TrueColor) && + (window_info[id].visual->storage_class != DirectColor)) + { + composite_image->storage_class=PseudoClass; + } + composite_image->columns=ximage->width; + composite_image->rows=ximage->height; + switch (composite_image->storage_class) + { + case DirectClass: + default: + { + register unsigned long color, index; + unsigned long blue_mask, blue_shift, green_mask, green_shift, red_mask, red_shift; + + red_mask=window_info[id].visual->red_mask; + red_shift=0; + while ((red_mask & 0x01) == 0) + { + red_mask>>=1; + red_shift++; + } + green_mask=window_info[id].visual->green_mask; + green_shift=0; + while ((green_mask & 0x01) == 0) + { + green_mask>>=1; + green_shift++; + } + blue_mask=window_info[id].visual->blue_mask; + blue_shift=0; + while ((blue_mask & 0x01) == 0) + { + blue_mask>>=1; + blue_shift++; + } + if ((number_colors != 0) && + (window_info[id].visual->storage_class == DirectColor)) + { + for (y=0; y < (long) composite_image->rows; y++) + { + q=SetImagePixels(composite_image,0,y, + composite_image->columns,1); + if (q == (PixelPacket *) NULL) + break; + for (x=0; x < (long) composite_image->columns; x++) + { + pixel=XGetPixel(ximage,x,y); + index=(pixel >> red_shift) & red_mask; + q->red=ScaleShortToQuantum(colors[index].red); + index=(pixel >> green_shift) & green_mask; + q->green=ScaleShortToQuantum(colors[index].green); + index=(pixel >> blue_shift) & blue_mask; + q->blue=ScaleShortToQuantum(colors[index].blue); + q++; + } + if (!SyncImagePixels(composite_image)) + break; + } + } + else + { + for (y=0; y < (long) composite_image->rows; y++) + { + q=SetImagePixels(composite_image,0,y, + composite_image->columns,1); + if (q == (PixelPacket *) NULL) + break; + for (x=0; x < (long) composite_image->columns; x++) + { + pixel=XGetPixel(ximage,x,y); + color=(pixel >> red_shift) & red_mask; + q->red=ScaleShortToQuantum((65535L*color)/red_mask); + color=(pixel >> green_shift) & green_mask; + q->green=ScaleShortToQuantum((65535L*color)/green_mask); + color=(pixel >> blue_shift) & blue_mask; + q->blue=ScaleShortToQuantum((65535L*color)/blue_mask); + q++; + } + if (!SyncImagePixels(composite_image)) + { + break; + } + } + } + break; + } + case PseudoClass: + { + if (!AllocateImageColormap(composite_image,number_colors)) + { + XDestroyImage(ximage); + DestroyImage(composite_image); + return((Image *) NULL); + } + for (i=0; i < (int) composite_image->colors; i++) + { + composite_image->colormap[colors[i].pixel].red= + ScaleShortToQuantum(colors[i].red); + composite_image->colormap[colors[i].pixel].green= + ScaleShortToQuantum(colors[i].green); + composite_image->colormap[colors[i].pixel].blue= + ScaleShortToQuantum(colors[i].blue); + } + for (y=0; y < (long) composite_image->rows; y++) + { + q=SetImagePixels(composite_image,0,y,composite_image->columns,1); + if (q == (PixelPacket *) NULL) + break; + indexes=GetIndexes(composite_image); + for (x=0; x < (long) composite_image->columns; x++) + { + index=(IndexPacket) XGetPixel(ximage,x,y); + indexes[x]=index; + *q++=composite_image->colormap[index]; + } + if (!SyncImagePixels(composite_image)) + { + break; + } + } + break; + } + } + XDestroyImage(ximage); + if (image == (Image *) NULL) + { + image=composite_image; + continue; + } + (void) XTranslateCoordinates(display,window_info[id].window,window,0,0, &x_offset,&y_offset,&child); + x_offset-=(int) crop_info.x; + if (x_offset < 0) + { + x_offset=0; + } + y_offset-=(int) crop_info.y; + if (y_offset < 0) + { + y_offset=0; + } + (void) CompositeImage(image,CopyCompositeOp,composite_image, x_offset,y_offset); + } + while (colormap_info != (ColormapInfo *) NULL) + { + next=colormap_info->next; + LiberateMemory((void **) &colormap_info->colors); + LiberateMemory((void **) &colormap_info); + colormap_info=next; + } + /* + Free resources and restore initial state. + */ + LiberateMemory((void **) &window_info); + window_info=(WindowInfo *) NULL; + max_windows=0; + number_windows=0; + colormap_info=(ColormapInfo *) NULL; + return(image); + } + return((Image *) NULL); +} + +/*************************************************/ +/* this code is adapted from ImageMagick */ +/* mainly because i don't want user interactions */ +/* and i want to chose the screen also */ +/*************************************************/ + +static void pdp_capture_do_capture(t_pdp_capture *x) +{ + Colormap *colormaps; + Image *image; + int number_colormaps, number_windows, status, X, Y; + RectangleInfo crop_info; + Window *children, client, prior_target, root, target; + XTextProperty window_name; + Window child; + XWindowAttributes window_attributes; + + /* + Open X server connection. + */ + if (!x->x_displayopen) + { + post( "pdp_capture : display not open : no capture" ); + return; + } + (void) XSetErrorHandler(XError); + crop_info.x=x->x_x; + crop_info.y=x->x_y; + crop_info.width=x->x_vwidth; + crop_info.height=x->x_vheight; + root=XRootWindow(x->x_dpy, x->x_screen); + target=(Window) NULL; + prior_target=target; + + target = XMyGetSubwindow(x, x->x_dpy,root,x->x_x,x->x_y); + + client=target; /* obsolete */ + if (target != root) + { + unsigned int d; + status=XGetGeometry(x->x_dpy,target,&root,&X,&X,&d,&d,&d,&d); + if (status != 0) + { + for ( ; ; ) + { + Window parent; + + status=XQueryTree(x->x_dpy,target,&root,&parent,&children,&d); + if (status && (children != (Window *) NULL)) + { + (void) XFree((char *) children); + } + if (!status || (parent == (Window) NULL) || (parent == root)) break; + target=parent; + } + client=XMyClientWindow(x, x->x_dpy, target); + target=client; + if (prior_target) target=prior_target; + } + } + status=XGetWindowAttributes(x->x_dpy,target,&window_attributes); + if (status == 0) + { + post( "pdp_capture : unable to read window attributes" ); + (void) XCloseDisplay(x->x_dpy); + return; + } + (void) XTranslateCoordinates(x->x_dpy,target,root,0,0,&X,&Y,&child); + crop_info.x=x->x_x; + crop_info.y=x->x_y; + crop_info.width=x->x_vwidth; + crop_info.height=x->x_vheight; + target=root; + + number_windows=0; + status=XGetWMColormapWindows(x->x_dpy,target,&children,&number_windows); + if ((status == 1) && (number_windows > 0)) + { + (void) XFree ((char *) children); + } + colormaps=XListInstalledColormaps(x->x_dpy,target,&number_colormaps); + if (number_colormaps > 0) + { + (void) XFree((char *) colormaps); + } + + image=XMyGetWindowImage(x, x->x_dpy, target, 1); + if (image == (Image *) NULL) + { + post( "pdp_capture : unable to read xwindow image" ); + } + else + { + Image *clone_image; + + clone_image=CloneImage(image,0,0,1,&image->exception); + if (clone_image != (Image *) NULL) + { + x->x_Ximage=CropImage(clone_image,&crop_info,&image->exception); + if (x->x_Ximage != (Image *) NULL) + { + DestroyImage(image); + DestroyImage(clone_image); + image=x->x_Ximage; + } + } + status=XGetWMName(x->x_dpy,target,&window_name); + } + return; +} + +static void pdp_capture_display(t_pdp_capture *x, t_symbol *s) +{ + if ( x->x_displayopen ) + { + if ( XCloseDisplay(x->x_dpy) == -1 ) + { + post( "pdp_capture : could not close display" ); + } + } + strcpy( x->x_display, s->s_name ); + if ( ( x->x_dpy = XOpenDisplay( x->x_display ) ) != NULL ) + { + x->x_displayopen = 1; + + x->x_vwidth=XDisplayWidth(x->x_dpy, x->x_screen); + x->x_vheight=XDisplayHeight(x->x_dpy, x->x_screen); + x->x_vsize=x->x_vwidth*x->x_vheight; + + } +} + +static void pdp_capture_screen(t_pdp_capture *x, t_floatarg fscreen) +{ + if ( (int)fscreen > 0 ) + { + x->x_screen = (int) fscreen; + } +} + +static void pdp_capture_x(t_pdp_capture *x, t_floatarg fx) +{ + t_int width; + t_int err; + + if (!x->x_displayopen) + { + post( "pdp_capture : display not open : not setting x" ); + return; + } + width = XDisplayWidth( x->x_dpy, x->x_screen ); + if ( ( (int)fx > 0 ) && ( (int)fx <= width ) ) + { + x->x_x = (int) fx; + if ( x->x_x + x->x_vwidth > width ) + { + x->x_vwidth = width - x->x_x; + x->x_vsize = x->x_vwidth * x->x_vheight; + } + } + else + { + post( "pdp_capture : x position out of range : [0, %d]", width ); + } +} + +static void pdp_capture_y(t_pdp_capture *x, t_floatarg fy) +{ + t_int height; + t_int err; + + if (!x->x_displayopen) + { + post( "pdp_capture : display not open : not setting y" ); + return; + } + height = XDisplayHeight( x->x_dpy, x->x_screen ); + if ( ( (int)fy > 0 ) && ( (int)fy <= height ) ) + { + x->x_y = (int) fy; + if ( x->x_y + x->x_vheight > height ) + { + x->x_vheight = height - x->x_y; + x->x_vsize = x->x_vwidth * x->x_vheight; + } + } + else + { + post( "pdp_capture : y position out of range : [0, %d]", height ); + } +} + +static void pdp_capture_width(t_pdp_capture *x, t_floatarg fwidth) +{ + t_int width; + t_int err; + + if (!x->x_displayopen) + { + post( "pdp_capture : display not open : not setting width" ); + return; + } + width = XDisplayWidth( x->x_dpy, x->x_screen ); + if ( ( (int)fwidth > 0 ) && ( (int)fwidth <= (width-x->x_x) ) ) + { + x->x_vwidth = (int) fwidth; + x->x_vsize = x->x_vwidth * x->x_vheight; + } + else + { + post( "pdp_capture : width out of range : [0, %d]", width-x->x_x ); + } +} + +static void pdp_capture_height(t_pdp_capture *x, t_floatarg fheight) +{ + t_int height; + t_int err; + + if (!x->x_displayopen) + { + post( "pdp_capture : display not open : not setting height" ); + return; + } + height = XDisplayWidth( x->x_dpy, x->x_screen ); + if ( ( (int)fheight > 0 ) && ( (int)fheight <= (height-x->x_y) ) ) + { + x->x_vheight = (int) fheight; + x->x_vsize = x->x_vwidth * x->x_vheight; + } + else + { + post( "pdp_capture : width out of range : [0, %d]", height-x->x_y ); + } +} + +static void pdp_capture_sendpacket(t_pdp_capture *x) +{ + /* unregister and propagate if valid dest packet */ + if (x->x_packet0 != -1 ) + { + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet0); + } +} + +static void pdp_capture_bang(t_pdp_capture *x) +{ + PixelPacket pixel; + short int *pY, *pU, *pV; + unsigned char y, u, v; + t_int px, py, r, g, b; + long number_pixels; + + // capture the image and output a PDP packet + pdp_capture_do_capture( x ); + + x->x_vwidth = x->x_Ximage->columns; + x->x_vheight = x->x_Ximage->rows; + x->x_vsize = x->x_vwidth*x->x_vheight; + + x->x_packet0 = pdp_packet_new_image_YCrCb( x->x_vwidth, x->x_vheight ); + x->x_data = (short int *)pdp_packet_data(x->x_packet0); + x->x_header = pdp_packet_header(x->x_packet0); + + x->x_header->info.image.encoding = PDP_IMAGE_YV12; + x->x_header->info.image.width = x->x_vwidth; + x->x_header->info.image.height = x->x_vheight; + + number_pixels=(long) GetPixelCacheArea(x->x_Ximage); + + // post( "pdp_capture : capture done : w=%d h=%d pixels=%ld", x->x_vwidth, x->x_vheight, number_pixels ); + + pY = x->x_data; + pV = x->x_data+x->x_vsize; + pU = x->x_data+x->x_vsize+(x->x_vsize>>2); + for ( py=0; py<x->x_vheight; py++ ) + { + for ( px=0; px<x->x_vwidth; px++ ) + { + pixel = GetOnePixel(x->x_Ximage, px, py); + // scale values + r = (pixel.red*255)/65535; + g = (pixel.green*255)/65535; + b = (pixel.blue*255)/65535; + // post( "pdp_capture : pixel : [%d, %d] : %d,%d,%d", px, py, r, g, b ); + y = yuv_RGBtoY(((r)<<16)+((g)<<8)+(b)); + u = yuv_RGBtoU(((r)<<16)+((g)<<8)+(b)); + v = yuv_RGBtoV(((r)<<16)+((g)<<8)+(b)); + + *(pY) = y<<7; + if ( (px%2==0) && (py%2==0) ) + { + *(pV) = (v-128)<<8; + *(pU) = (u-128)<<8; + } + pY++; + if ( (px%2==0) && (py%2==0) ) + { + pV++;pU++; + } + } + } + + // output the new packet + pdp_capture_sendpacket( x ); + + DestroyImage( x->x_Ximage ); +} + +static void pdp_capture_free(t_pdp_capture *x) +{ + int i; + + if ( x->x_packet0 != -1 ) + { + pdp_packet_mark_unused(x->x_packet0); + } + if ( x->x_displayopen ) + { + if ( XCloseDisplay(x->x_dpy) == -1 ) + { + post( "pdp_capture : could not close display" ); + } + } +} + +t_class *pdp_capture_class; + +void *pdp_capture_new(void) +{ + int i; + + t_pdp_capture *x = (t_pdp_capture *)pd_new(pdp_capture_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("x")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("y")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("width")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("height")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + x->x_packet0 = -1; + + x->x_display = (char *) malloc( PDP_DISPLAY_LENGTH ); + strcpy( x->x_display, ":0.0" ); + + x->x_displayopen = 0; + if ( ( x->x_dpy = XOpenDisplay( x->x_display ) ) != NULL ) + { + x->x_displayopen = 1; + + x->x_vwidth=XDisplayWidth(x->x_dpy, x->x_screen); + x->x_vheight=XDisplayWidth(x->x_dpy, x->x_screen); + x->x_vsize=x->x_vwidth*x->x_vheight; + + } + + x->x_screen = 0; + x->x_x = 0; + x->x_y = 0; + x->x_vwidth = 320; + x->x_vheight = 240; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_capture_setup(void) +{ + post( pdp_capture_version ); + pdp_capture_class = class_new(gensym("pdp_capture"), (t_newmethod)pdp_capture_new, + (t_method)pdp_capture_free, sizeof(t_pdp_capture), 0, A_NULL); + + class_addmethod(pdp_capture_class, (t_method)pdp_capture_bang, gensym("bang"), A_NULL); + class_addmethod(pdp_capture_class, (t_method)pdp_capture_display, gensym("display"), A_SYMBOL, A_NULL); + class_addmethod(pdp_capture_class, (t_method)pdp_capture_screen, gensym("screen"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_capture_class, (t_method)pdp_capture_x, gensym("x"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_capture_class, (t_method)pdp_capture_y, gensym("y"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_capture_class, (t_method)pdp_capture_width, gensym("width"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_capture_class, (t_method)pdp_capture_height, gensym("height"), A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_cmap.c b/modules/pdp_cmap.c new file mode 100644 index 0000000..3d8524f --- /dev/null +++ b/modules/pdp_cmap.c @@ -0,0 +1,539 @@ +/* + * PiDiP module + * Copyright (c) by Yves Degoyon ( ydegoyon@free.fr ) + * + * 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. + * + */ + +/* This object is a color mapper that lets you change the colors within the image + */ + +#include "pdp.h" +#include "yuv.h" +#include <math.h> +#include <stdio.h> + +struct _rtext +{ + char *x_buf; + int x_bufsize; + int x_selstart; + int x_selend; + int x_active; + int x_dragfrom; + int x_height; + int x_drawnwidth; + int x_drawnheight; + t_text *x_text; + t_glist *x_glist; + char x_tag[50]; + struct _rtext *x_next; +}; + +#define t_rtext struct _rtext + +extern int rtext_width(t_rtext *x); +extern int rtext_height(t_rtext *x); +extern t_rtext *glist_findrtext(t_glist *gl, t_text *who); + +typedef struct _color +{ + t_int on; + t_int y,u,v; + t_int oy,ou,ov; + t_int tolerance; +} t_color; + +#define COLORHEIGHT 5 +#define DEFAULT_CAPACITY 10 + +static char *pdp_cmap_version = "pdp_cmap: a color mapper version 0.1 written by Yves Degoyon (ydegoyon@free.fr)"; + +typedef struct pdp_cmap_struct +{ + t_object x_obj; + t_float x_f; + + t_int x_packet0; + t_int x_dropped; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + t_int x_capacity; // number of mapped colors + t_int x_current; // current color + t_color *x_colors; // color substitution table + + t_int x_cursor; // show cursor or not + t_int x_luminosity; // use luminosity or not + + t_int x_colorR; // setable r + t_int x_colorG; // setable g + t_int x_colorB; // setable b + + t_int x_cursX; // X coordinate of cursor + t_int x_cursY; // Y coordinate of cursor + short int *x_frame; // keep a copy of current frame for picking color + + t_outlet *x_pdp_output; // output packets + + t_canvas *x_canvas; + +} t_pdp_cmap; + +static void pdp_cmap_draw_color(t_pdp_cmap *x, t_int r, t_int g, t_int b) +{ + t_int width, height; + char color[32]; + + sprintf( color, "#%.2X%.2X%.2X", r, g, b ); + width = rtext_width( glist_findrtext( (t_glist*)x->x_canvas, (t_text *)x ) ); + height = rtext_height( glist_findrtext( (t_glist*)x->x_canvas, (t_text *)x ) ); + sys_vgui(".x%x.c delete rectangle %xCOLOR\n", x->x_canvas, x ); + sys_vgui(".x%x.c create rectangle %d %d %d %d -fill %s -tags %xCOLOR\n", + x->x_canvas, x->x_obj.te_xpix+width+5, x->x_obj.te_ypix, + x->x_obj.te_xpix+width+height+5, + x->x_obj.te_ypix+height, color, x ); +} + +static void pdp_cmap_r(t_pdp_cmap *x, t_floatarg fr ) +{ + if ( ( fr >= 0 ) && ( fr < 255 ) ) + { + x->x_colorR = (int)fr; + x->x_colors[x->x_current].y = (yuv_RGBtoY( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB ))<<7; + x->x_colors[x->x_current].u = (yuv_RGBtoU( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + x->x_colors[x->x_current].v = (yuv_RGBtoV( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + pdp_cmap_draw_color( x, x->x_colorR, x->x_colorG, x->x_colorB ); + } +} + +static void pdp_cmap_g(t_pdp_cmap *x, t_floatarg fg ) +{ + if ( ( fg >= 0 ) && ( fg < 255 ) ) + { + x->x_colorG = (int)fg; + x->x_colors[x->x_current].y = (yuv_RGBtoY( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB ))<<7; + x->x_colors[x->x_current].u = (yuv_RGBtoU( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + x->x_colors[x->x_current].v = (yuv_RGBtoV( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + pdp_cmap_draw_color( x, x->x_colorR, x->x_colorG, x->x_colorB ); + } +} + +static void pdp_cmap_b(t_pdp_cmap *x, t_floatarg fb ) +{ + if ( ( fb >= 0 ) && ( fb < 255 ) ) + { + x->x_colorB = (int)fb; + x->x_colors[x->x_current].y = (yuv_RGBtoY( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB ))<<7; + x->x_colors[x->x_current].u = (yuv_RGBtoU( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + x->x_colors[x->x_current].v = (yuv_RGBtoV( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + pdp_cmap_draw_color( x, x->x_colorR, x->x_colorG, x->x_colorB ); + } +} + +static void pdp_cmap_cursx(t_pdp_cmap *x, t_floatarg fx ) +{ + if ( ( fx >= 0 ) && ( fx < x->x_vwidth) ) + { + x->x_cursX = (int)fx; + } +} + +static void pdp_cmap_cursy(t_pdp_cmap *x, t_floatarg fy ) +{ + if ( ( fy >= 0 ) && ( fy < x->x_vheight) ) + { + x->x_cursY = (int)fy; + } +} + +static void pdp_cmap_tolerance(t_pdp_cmap *x, t_floatarg ftolerance ) +{ + if ( ftolerance >= 0 ) + { + x->x_colors[x->x_current].tolerance = (int)ftolerance; + } +} + +static void pdp_cmap_luminosity(t_pdp_cmap *x, t_floatarg fluminosity ) +{ + if ( ( fluminosity == 0 ) || ( fluminosity == 1 ) ) + { + x->x_luminosity = (int)fluminosity; + } +} + +static void pdp_cmap_delete(t_pdp_cmap *x, t_floatarg fcolor ) +{ + if ( ( fcolor >= 0 ) && ( fcolor < x->x_capacity ) ) + { + x->x_colors[(int)fcolor].on = 0; + } +} + +static void pdp_cmap_clear(t_pdp_cmap *x) +{ + t_int ci; + + for ( ci=0; ci<x->x_capacity; ci++) + { + x->x_colors[ci].on = 0; + } + x->x_current = 0; +} + +static void pdp_cmap_resize(t_pdp_cmap *x, t_floatarg fnewsize ) +{ + t_color *colors; + t_int ci, csize; + + if ( (int) fnewsize<=0 ) return; + + // allocate new structures + colors = (t_color*) getbytes( fnewsize*sizeof(t_color) ); + + for ( ci=0; ci<fnewsize; ci++ ) + { + colors[ci].on = 0; + colors[ci].tolerance = 10; + } + + if ( fnewsize < x->x_capacity ) + { + post( "pdp_form : new size is too small : texts lost !!" ); + csize = fnewsize; + } + else + { + csize = x->x_capacity; + } + + // copy all values + for ( ci=0; ci<csize; ci++ ) + { + memcpy( &colors[ci], &x->x_colors[ci], sizeof( t_color ) ); + } + + // free old structures + if ( x->x_colors ) freebytes( x->x_colors, x->x_capacity*sizeof(t_color) ); + + // set new structures + x->x_colors = colors; + x->x_capacity = fnewsize; + x->x_current = 0; +} + +static void pdp_cmap_setcur(t_pdp_cmap *x, t_floatarg fpx, t_floatarg fpy ) +{ + if ( (fpx>=0.0) && (fpx<=1.0) && (fpy>=0.0) && (fpy<=1.0) ) + { + x->x_cursX = fpx*(t_float)x->x_vwidth; + x->x_cursY = fpy*(t_float)x->x_vheight; + } +} + +static void pdp_cmap_current(t_pdp_cmap *x, t_floatarg fcurrent ) +{ + if ( ( fcurrent >= 0 ) && ( fcurrent < x->x_capacity ) ) + { + x->x_current = (int)fcurrent; + post( "pdp_cmap : color index set to : %d", x->x_current ); + } +} + +static void pdp_cmap_cursor(t_pdp_cmap *x, t_floatarg fcursor ) +{ + if ( ( fcursor == 0 ) || ( fcursor == 1 ) ) + { + x->x_cursor = (int)fcursor; + } +} + +static void pdp_cmap_pick(t_pdp_cmap *x) +{ + t_int y,u,v; + + if ( x->x_frame && ( x->x_cursX > 0 ) && ( x->x_cursX < x->x_vwidth ) + && ( x->x_cursY > 0 ) && ( x->x_cursY < x->x_vheight ) ) + { + x->x_colors[x->x_current].oy = x->x_frame[ x->x_cursY*x->x_vwidth+x->x_cursX ]; + x->x_colors[x->x_current].ov = x->x_frame[ x->x_vsize+((x->x_cursY>>1)*(x->x_vwidth>>1)+(x->x_cursX>>1)) ]; + x->x_colors[x->x_current].ou = x->x_frame[ x->x_vsize+(x->x_vsize>>2)+((x->x_cursY>>1)*(x->x_vwidth>>1)+(x->x_cursX>>1)) ]; + y = (x->x_colors[x->x_current].oy)>>7; + v = (x->x_colors[x->x_current].ov>>8)+128; + u = (x->x_colors[x->x_current].ou>>8)+128; + x->x_colorR = yuv_YUVtoR( y, u, v ); + x->x_colorG = yuv_YUVtoG( y, u, v ); + x->x_colorB = yuv_YUVtoB( y, u, v ); + pdp_cmap_draw_color( x, x->x_colorR, x->x_colorG, x->x_colorB ); + x->x_colors[x->x_current].y = 255; + x->x_colors[x->x_current].u = 255; + x->x_colors[x->x_current].v = 255; + x->x_colors[x->x_current].on = 1; + } +} + +static void pdp_cmap_allocate(t_pdp_cmap *x) +{ + x->x_frame = (short int *) getbytes ( ( x->x_vsize + ( x->x_vsize>>1 ) ) << 1 ); + + if ( !x->x_frame ) + { + post( "pdp_mgrid : severe error : cannot allocate buffer !!! "); + return; + } +} + +static void pdp_cmap_free_ressources(t_pdp_cmap *x) +{ + if ( x->x_frame ) freebytes ( x->x_frame, ( x->x_vsize + ( x->x_vsize>>1 ) ) << 1 ); +} + +static void pdp_cmap_process_yv12(t_pdp_cmap *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_int i, ci; + t_int px=0, py=0, ppx=0, ppy=0; + t_int y=0, u=0, v=0; + short int *pfY, *pfU, *pfV; + short int *poY, *poU, *poV; + t_int diff; + + /* allocate all ressources */ + if ( ( (int)header->info.image.width != x->x_vwidth ) || + ( (int)header->info.image.height != x->x_vheight ) ) + { + pdp_cmap_free_ressources( x ); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_cmap_allocate( x ); + post( "pdp_cmap : reallocated buffers" ); + } + + memcpy(x->x_frame, data, (x->x_vsize + (x->x_vsize>>1))<<1 ); + + // map colors + for ( ci=0; ci<x->x_capacity; ci++ ) + { + if ( x->x_colors[ci].on ) + { + pfY = data; + pfV = data+x->x_vsize; + pfU = data+x->x_vsize+(x->x_vsize>>2); + poY = x->x_frame; + poV = x->x_frame+x->x_vsize; + poU = x->x_frame+x->x_vsize+(x->x_vsize>>2); + for ( py=0; py<x->x_vheight; py++ ) + { + for ( px=0; px<x->x_vwidth; px++ ) + { + y = *poY; + v = *poV; + u = *poU; + + if ( x->x_luminosity ) + { + diff = (abs(y-x->x_colors[ci].oy)>>7)+(abs(u-x->x_colors[ci].ou)>>8)+(abs(v-x->x_colors[ci].ov)>>8); + } + else + { + diff = (abs(u-x->x_colors[ci].ou)>>8)+(abs(v-x->x_colors[ci].ov)>>8); + } + + if ( diff <= x->x_colors[ci].tolerance ) + { + // change color not luminosity + // *pfY = x->x_colors[ci].y; + *pfV = x->x_colors[ci].v; + *pfU = x->x_colors[ci].u; + } + + pfY++;poY++; + if ( (px%2==0) && (py%2==0) ) + { + pfU++;pfV++; + poU++;poV++; + } + } + } + } + } + + // draw cursor + if ( ( x->x_cursX > 0 ) && ( x->x_cursY > 0 ) && ( x->x_cursor ) ) + { + for ( px=(x->x_cursX-5); px<=(x->x_cursX+5); px++ ) + { + if ( ( px > 0 ) && ( px < x->x_vwidth ) ) + { + if ( ((*(data+x->x_cursY*x->x_vwidth+px))>>7) < 128 ) + { + *(data+x->x_cursY*x->x_vwidth+px) = 0xff<<7; + } + else + { + *(data+x->x_cursY*x->x_vwidth+px) = 0x00<<7; + } + } + } + for ( py=(x->x_cursY-5); py<=(x->x_cursY+5); py++ ) + { + if ( ( py > 0 ) && ( py < x->x_vheight ) ) + { + if ( ((*(data+py*x->x_vwidth+x->x_cursX))>>7) < 128 ) + { + *(data+py*x->x_vwidth+x->x_cursX) = 0xff<<7; + } + else + { + *(data+py*x->x_vwidth+x->x_cursX) = 0x00<<7; + } + } + } + } + + pdp_packet_pass_if_valid(x->x_pdp_output, &x->x_packet0); + + return; +} + +static void pdp_cmap_process(t_pdp_cmap *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_cmap_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + pdp_cmap_process_yv12(x); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_cmap_process */ + break; + + } + } + +} + +static void pdp_cmap_input_0(t_pdp_cmap *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + pdp_cmap_process(x); + + } +} + +static void pdp_cmap_free(t_pdp_cmap *x) +{ + int i; + + pdp_packet_mark_unused(x->x_packet0); + pdp_cmap_free_ressources( x ); +} + +t_class *pdp_cmap_class; + +void *pdp_cmap_new(void) +{ + t_int ci; + + t_pdp_cmap *x = (t_pdp_cmap *)pd_new(pdp_cmap_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("current")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("cursx")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("cursy")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("R")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("G")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("B")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("tolerance")); + + x->x_pdp_output = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + + x->x_cursX = -1; + x->x_cursY = -1; + x->x_cursor = 1; + x->x_luminosity = 1; + + x->x_capacity = DEFAULT_CAPACITY; + x->x_current = 0; + x->x_colors = (t_color *) getbytes( x->x_capacity*sizeof(t_color) ); + for ( ci=0; ci<x->x_capacity; ci++) + { + x->x_colors[ci].on = 0; + x->x_colors[ci].tolerance = 10; + } + + x->x_canvas = canvas_getcurrent(); + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_cmap_setup(void) +{ + post( pdp_cmap_version ); + pdp_cmap_class = class_new(gensym("pdp_cmap"), (t_newmethod)pdp_cmap_new, + (t_method)pdp_cmap_free, sizeof(t_pdp_cmap), 0, A_NULL); + + class_addmethod(pdp_cmap_class, (t_method)pdp_cmap_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_cmap_class, (t_method)pdp_cmap_r, gensym("R"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_cmap_class, (t_method)pdp_cmap_g, gensym("G"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_cmap_class, (t_method)pdp_cmap_b, gensym("B"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_cmap_class, (t_method)pdp_cmap_cursx, gensym("cursx"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_cmap_class, (t_method)pdp_cmap_cursy, gensym("cursy"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_cmap_class, (t_method)pdp_cmap_pick, gensym("pick"), A_NULL); + class_addmethod(pdp_cmap_class, (t_method)pdp_cmap_tolerance, gensym("tolerance"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_cmap_class, (t_method)pdp_cmap_cursor, gensym("cursor"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_cmap_class, (t_method)pdp_cmap_luminosity, gensym("luminosity"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_cmap_class, (t_method)pdp_cmap_current, gensym("current"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_cmap_class, (t_method)pdp_cmap_clear, gensym("clear"), A_NULL); + class_addmethod(pdp_cmap_class, (t_method)pdp_cmap_delete, gensym("delete"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_cmap_class, (t_method)pdp_cmap_resize, gensym("resize"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_cmap_class, (t_method)pdp_cmap_setcur, gensym("setcur"), A_DEFFLOAT, A_DEFFLOAT, A_NULL); +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_compose.c b/modules/pdp_compose.c new file mode 100644 index 0000000..ed2a5b3 --- /dev/null +++ b/modules/pdp_compose.c @@ -0,0 +1,459 @@ +/* + * PiDiP module + * Copyright (c) by Yves Degoyon ( ydegoyon@free.fr ) + * + * 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. + * + */ + +/* This object is a video compositor mixing two sources + * idea expressed by liz + */ + +#include "pdp.h" +#include "yuv.h" +#include <math.h> +#include <stdio.h> + +struct _rtext +{ + char *x_buf; + t_int x_bufsize; + t_int x_selstart; + t_int x_selend; + t_int x_active; + t_int x_dragfrom; + t_int x_height; + t_int x_drawnwidth; + t_int x_drawnheight; + t_text *x_text; + t_glist *x_glist; + char x_tag[50]; + struct _rtext *x_next; +}; + +#define t_rtext struct _rtext + +extern int rtext_width(t_rtext *x); +extern int rtext_height(t_rtext *x); +extern t_rtext *glist_findrtext(t_glist *gl, t_text *who); + +#define COLORHEIGHT 5 + +static char *pdp_compose_version = "pdp_compose: a video compositor version 0.1 written by Yves Degoyon (ydegoyon@free.fr)"; + +typedef struct pdp_compose_struct +{ + t_object x_obj; + t_float x_f; + + t_int x_packet0; + t_int x_dropped; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + t_int x_colorR; // RGB components of mixing color + t_int x_colorG; + t_int x_colorB; + t_int x_colorY; // YUV components of mixing color + t_int x_colorU; + t_int x_colorV; + t_int x_tolerance; // tolerance + t_int x_cursX; // X coordinate of cursor + t_int x_cursY; // Y coordinate of cursor + t_int x_cursor; // cursor drawing flag + t_int x_luminosity; // flag to indicate if luminosity is used + short int *x_frame; // keep a copy of current frame for picking color + short int *x_right_frame; // 2nd video source + + t_outlet *x_pdp_output; // output packets + + t_canvas *x_canvas; + +} t_pdp_compose; + +static void pdp_compose_draw_color(t_pdp_compose *x) +{ + t_int width, height; + char color[32]; + + sprintf( color, "#%.2X%.2X%.2X", x->x_colorR, x->x_colorG, x->x_colorB ); + width = rtext_width( glist_findrtext( (t_glist*)x->x_canvas, (t_text *)x ) ); + height = rtext_height( glist_findrtext( (t_glist*)x->x_canvas, (t_text *)x ) ); + sys_vgui(".x%x.c delete rectangle %xCOLOR\n", x->x_canvas, x ); + sys_vgui(".x%x.c create rectangle %d %d %d %d -fill %s -tags %xCOLOR\n", + x->x_canvas, x->x_obj.te_xpix+width+5, x->x_obj.te_ypix, + x->x_obj.te_xpix+width+height+5, + x->x_obj.te_ypix+height, color, x ); +} + +static void pdp_compose_setcur(t_pdp_compose *x, t_floatarg fpx, t_floatarg fpy ) +{ + if ( (fpx>=0.0) && (fpx<=1.0) && (fpy>=0.0) && (fpy<=1.0) ) + { + x->x_cursX = fpx*(t_float)x->x_vwidth; + x->x_cursY = fpy*(t_float)x->x_vheight; + } +} + +static void pdp_compose_r(t_pdp_compose *x, t_floatarg fr ) +{ + if ( ( fr >= 0 ) && ( fr < 255 ) ) + { + x->x_colorR = (int)fr; + x->x_colorY = (yuv_RGBtoY( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB ))<<7; + x->x_colorU = (yuv_RGBtoU( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + x->x_colorV = (yuv_RGBtoV( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + pdp_compose_draw_color( x ); + } +} + +static void pdp_compose_g(t_pdp_compose *x, t_floatarg fg ) +{ + if ( ( fg >= 0 ) && ( fg < 255 ) ) + { + x->x_colorG = (int)fg; + x->x_colorY = (yuv_RGBtoY( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB ))<<7; + x->x_colorU = (yuv_RGBtoU( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + x->x_colorV = (yuv_RGBtoV( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + pdp_compose_draw_color( x ); + } +} + +static void pdp_compose_b(t_pdp_compose *x, t_floatarg fb ) +{ + if ( ( fb >= 0 ) && ( fb < 255 ) ) + { + x->x_colorB = (int)fb; + x->x_colorY = (yuv_RGBtoY( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB ))<<7; + x->x_colorU = (yuv_RGBtoU( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + x->x_colorV = (yuv_RGBtoV( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + pdp_compose_draw_color( x ); + } +} + +static void pdp_compose_cursor(t_pdp_compose *x, t_floatarg fcursor ) +{ + if ( ( (int)fcursor == 0 ) || ( (int)fcursor == 1 ) ) + { + x->x_cursor = (int)fcursor; + } +} + +static void pdp_compose_tolerance(t_pdp_compose *x, t_floatarg ftolerance ) +{ + if ( ftolerance >= 0 ) + { + x->x_tolerance = (int)ftolerance; + } +} + +static void pdp_compose_cursx(t_pdp_compose *x, t_floatarg fx ) +{ + if ( ( fx >= 0 ) && ( fx < x->x_vwidth) ) + { + x->x_cursX = (int)fx; + } +} + +static void pdp_compose_cursy(t_pdp_compose *x, t_floatarg fy ) +{ + if ( ( fy >= 0 ) && ( fy < x->x_vheight) ) + { + x->x_cursY = (int)fy; + } +} + +static void pdp_compose_luminosity(t_pdp_compose *x, t_floatarg fluminosity ) +{ + if ( ( fluminosity == 0 ) || ( fluminosity == 1 ) ) + { + x->x_luminosity = (int)fluminosity; + } +} + +static void pdp_compose_pick(t_pdp_compose *x) +{ + t_int y,u,v; + + if ( x->x_frame && ( x->x_cursX > 0 ) && ( x->x_cursX < x->x_vwidth ) + && ( x->x_cursY > 0 ) && ( x->x_cursY < x->x_vheight ) ) + { + x->x_colorY = x->x_frame[ x->x_cursY*x->x_vwidth+x->x_cursX ]; + x->x_colorV = x->x_frame[ x->x_vsize + (x->x_cursY>>1)*(x->x_vwidth>>1)+(x->x_cursX>>1) ]; + x->x_colorU = x->x_frame[ x->x_vsize + (x->x_vsize>>2) + (x->x_cursY>>1)*(x->x_vwidth>>1)+(x->x_cursX>>1) ]; + y = (x->x_colorY)>>7; + u = (x->x_colorU>>8)+128; + v = (x->x_colorV>>8)+128; + x->x_colorR = yuv_YUVtoR( y, u, v ); + x->x_colorG = yuv_YUVtoG( y, u, v ); + x->x_colorB = yuv_YUVtoB( y, u, v ); + pdp_compose_draw_color( x ); + } +} + +static void pdp_compose_allocate(t_pdp_compose *x) +{ + x->x_frame = (short int *) getbytes ( ( x->x_vsize + ( x->x_vsize>>1 ) ) << 1 ); + x->x_right_frame = (short int *) getbytes ( ( x->x_vsize + ( x->x_vsize>>1 ) ) << 1 ); + + if ( !x->x_frame || !x->x_right_frame ) + { + post( "pdp_mgrid : severe error : cannot allocate buffer !!! "); + return; + } +} + +static void pdp_compose_free_ressources(t_pdp_compose *x) +{ + if ( x->x_frame ) freebytes ( x->x_frame, ( x->x_vsize + ( x->x_vsize>>1 ) ) << 1 ); + if ( x->x_right_frame ) freebytes ( x->x_right_frame, ( x->x_vsize + ( x->x_vsize>>1 ) ) << 1 ); +} + +static void pdp_compose_process_yv12(t_pdp_compose *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_int i, cf; + t_int px=0, py=0, ppx=0, ppy=0, found=0, xcell=0, ycell=0; + t_int celldiff=0, cellwidth=0, cellheight=0; + t_int y=0, u=0, v=0; + t_int sum; + short int *pfY, *pfV, *pfU, *prY, *prV, *prU, *pdY, *pdV, *pdU; + + /* allocate all ressources */ + if ( ( (int)header->info.image.width != x->x_vwidth ) || + ( (int)header->info.image.height != x->x_vheight ) ) + { + pdp_compose_free_ressources( x ); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_compose_allocate( x ); + post( "pdp_compose : reallocated buffers" ); + } + + memcpy(x->x_frame, data, (x->x_vsize + (x->x_vsize>>1))<<1 ); + + // draw cursor + if ( ( x->x_cursor ) && ( x->x_cursX > 0 ) && ( x->x_cursY > 0 ) ) + { + for ( px=(x->x_cursX-5); px<=(x->x_cursX+5); px++ ) + { + if ( ( px > 0 ) && ( px < x->x_vwidth ) ) + { + if ( ((*(data+x->x_cursY*x->x_vwidth+px))>>7) < 128 ) + { + *(data+x->x_cursY*x->x_vwidth+px) = 0xff<<7; + } + else + { + *(data+x->x_cursY*x->x_vwidth+px) = 0x00<<7; + } + } + } + for ( py=(x->x_cursY-5); py<=(x->x_cursY+5); py++ ) + { + if ( ( py > 0 ) && ( py < x->x_vheight ) ) + { + if ( ((*(data+py*x->x_vwidth+x->x_cursX))>>7) < 128 ) + { + *(data+py*x->x_vwidth+x->x_cursX) = 0xff<<7; + } + else + { + *(data+py*x->x_vwidth+x->x_cursX) = 0x00<<7; + } + } + } + } + + pfY = x->x_frame; + pfV = x->x_frame+x->x_vsize; + pfU = x->x_frame+x->x_vsize+(x->x_vsize>>2); + pdY = data; + pdV = data+x->x_vsize; + pdU = data+x->x_vsize+(x->x_vsize>>2); + prY = x->x_right_frame; + prV = x->x_right_frame+x->x_vsize; + prU = x->x_right_frame+x->x_vsize+(x->x_vsize>>2); + // track color + if ( x->x_colorR != -1 ) + { + for ( py=0; py<x->x_vheight; py++ ) + { + for ( px=0; px<x->x_vwidth; px++ ) + { + y = *pfY; + v = *pfV; + u = *pfU; + if ( x->x_luminosity ) + { + sum = (abs(y-x->x_colorY)>>7); + } + else + { + sum = (abs(y-x->x_colorY)>>7)+(abs(u-x->x_colorU)>>8)+(abs(v-x->x_colorV)>>8); + } + if ( sum <= x->x_tolerance ) + { + *pdY = *prY; + *pdV = *prV; + *pdU = *prU; + } + prY++;pdY++;pfY++; + if ( (px%2==0) && (py%2==0) ) + { + prU++; prV++; + pfU++; pfV++; + pdU++; pdV++; + } + } + } + } + + pdp_packet_pass_if_valid(x->x_pdp_output, &x->x_packet0); + + return; +} + +static void pdp_compose_process(t_pdp_compose *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_compose_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + pdp_compose_process_yv12(x); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_compose_process */ + break; + + } + } + +} + +static void pdp_compose_input_1(t_pdp_compose *x, t_symbol *s, t_floatarg f) +{ + short int *rightdata = (short int *)pdp_packet_data((int)f); + + if (s== gensym("register_rw")) memcpy(x->x_right_frame, rightdata, (x->x_vsize + (x->x_vsize>>1))<<1 ); +} + +static void pdp_compose_input_0(t_pdp_compose *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + pdp_compose_process(x); + + } +} + +static void pdp_compose_free(t_pdp_compose *x) +{ + int i; + + pdp_packet_mark_unused(x->x_packet0); + pdp_compose_free_ressources( x ); +} + +t_class *pdp_compose_class; + +void *pdp_compose_new(void) +{ + int i; + + t_pdp_compose *x = (t_pdp_compose *)pd_new(pdp_compose_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("pdp"), gensym("pdp1")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("R")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("G")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("B")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("cursx")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("cursy")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("tolerance")); + + x->x_pdp_output = outlet_new(&x->x_obj, &s_anything); + + x->x_colorR = -1; + x->x_colorG = -1; + x->x_colorB = -1; + + x->x_colorY = (yuv_RGBtoY( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB ))<<7; + x->x_colorU = (yuv_RGBtoU( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + x->x_colorV = (yuv_RGBtoV( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + + x->x_packet0 = -1; + + x->x_cursX = -1; + x->x_cursY = -1; + x->x_tolerance = 20; + x->x_luminosity = 1; + x->x_cursor = 1; + + x->x_canvas = canvas_getcurrent(); + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_compose_setup(void) +{ + post( pdp_compose_version ); + pdp_compose_class = class_new(gensym("pdp_compose"), (t_newmethod)pdp_compose_new, + (t_method)pdp_compose_free, sizeof(t_pdp_compose), 0, A_NULL); + + class_addmethod(pdp_compose_class, (t_method)pdp_compose_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_compose_class, (t_method)pdp_compose_input_1, gensym("pdp1"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_compose_class, (t_method)pdp_compose_r, gensym("R"), A_FLOAT, A_NULL); + class_addmethod(pdp_compose_class, (t_method)pdp_compose_g, gensym("G"), A_FLOAT, A_NULL); + class_addmethod(pdp_compose_class, (t_method)pdp_compose_b, gensym("B"), A_FLOAT, A_NULL); + class_addmethod(pdp_compose_class, (t_method)pdp_compose_cursx, gensym("cursx"), A_FLOAT, A_NULL); + class_addmethod(pdp_compose_class, (t_method)pdp_compose_cursy, gensym("cursy"), A_FLOAT, A_NULL); + class_addmethod(pdp_compose_class, (t_method)pdp_compose_pick, gensym("pick"), A_NULL); + class_addmethod(pdp_compose_class, (t_method)pdp_compose_cursor, gensym("cursor"), A_FLOAT, A_NULL); + class_addmethod(pdp_compose_class, (t_method)pdp_compose_tolerance, gensym("tolerance"), A_FLOAT, A_NULL); + class_addmethod(pdp_compose_class, (t_method)pdp_compose_luminosity, gensym("luminosity"), A_FLOAT, A_NULL); + class_addmethod(pdp_compose_class, (t_method)pdp_compose_setcur, gensym("setcur"), A_FLOAT, A_FLOAT, A_NULL); +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_ctrack.c b/modules/pdp_ctrack.c new file mode 100644 index 0000000..45e1ccb --- /dev/null +++ b/modules/pdp_ctrack.c @@ -0,0 +1,676 @@ +/* + * PiDiP module + * Copyright (c) by Yves Degoyon ( ydegoyon@free.fr ) + * + * 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. + * + */ + +/* This object is a color tracker that lets you follow the movement of objects + */ + +#include "pdp.h" +#include "yuv.h" +#include <math.h> +#include <stdio.h> + +struct _rtext +{ + char *x_buf; + int x_bufsize; + int x_selstart; + int x_selend; + int x_active; + int x_dragfrom; + int x_height; + int x_drawnwidth; + int x_drawnheight; + t_text *x_text; + t_glist *x_glist; + char x_tag[50]; + struct _rtext *x_next; +}; + +#define t_rtext struct _rtext + +extern int rtext_width(t_rtext *x); +extern int rtext_height(t_rtext *x); +extern t_rtext *glist_findrtext(t_glist *gl, t_text *who); + +#define COLORHEIGHT 5 + +static char *pdp_ctrack_version = "pdp_ctrack: a color tracker version 0.1 written by Yves Degoyon (ydegoyon@free.fr)"; + +typedef struct pdp_ctrack_struct +{ + t_object x_obj; + t_float x_f; + + t_int x_packet0; + t_int x_dropped; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + t_int x_colorR; // RGB components of tracked color + t_int x_colorG; + t_int x_colorB; + t_int x_colorY; // YUV components of tracked color + t_int x_colorU; + t_int x_colorV; + t_int x_tolerance; // tolerance + t_int x_luminosity; // use luminosity or not + t_int x_steady; // steady mode : the zone is searched around the cursor + t_int x_cursor; // show cursor or not + t_int x_showframe; // show frame or not + t_int x_cursX; // X coordinate of cursor + t_int x_cursY; // Y coordinate of cursor + short int *x_frame; // keep a copy of current frame for picking color + + t_outlet *x_pdp_output; // output packets + t_outlet *x_x1; // output x1 coordinate of block which has been detected + t_outlet *x_y1; // output y1 coordinate of block which has been detected + t_outlet *x_x2; // output x2 coordinate of block which has been detected + t_outlet *x_y2; // output y2 coordinate of block which has been detected + t_outlet *x_R; // output R component of selected color + t_outlet *x_G; // output R component of selected color + t_outlet *x_B; // output R component of selected color + + t_canvas *x_canvas; + +} t_pdp_ctrack; + +static void pdp_ctrack_draw_color(t_pdp_ctrack *x) +{ + t_int width, height; + char color[32]; + + sprintf( color, "#%.2X%.2X%.2X", x->x_colorR, x->x_colorG, x->x_colorB ); + width = rtext_width( glist_findrtext( (t_glist*)x->x_canvas, (t_text *)x ) ); + height = rtext_height( glist_findrtext( (t_glist*)x->x_canvas, (t_text *)x ) ); + sys_vgui(".x%x.c delete rectangle %xCOLOR\n", x->x_canvas, x ); + sys_vgui(".x%x.c create rectangle %d %d %d %d -fill %s -tags %xCOLOR\n", + x->x_canvas, x->x_obj.te_xpix+width+5, x->x_obj.te_ypix, + x->x_obj.te_xpix+width+height+5, + x->x_obj.te_ypix+height, color, x ); +} + +static void pdp_ctrack_setcur(t_pdp_ctrack *x, t_floatarg fpx, t_floatarg fpy ) +{ + if ( (fpx>=0.0) && (fpx<=1.0) && (fpy>=0.0) && (fpy<=1.0) ) + { + x->x_cursX = fpx*(t_float)x->x_vwidth; + x->x_cursY = fpy*(t_float)x->x_vheight; + } +} + +static void pdp_ctrack_r(t_pdp_ctrack *x, t_floatarg fr ) +{ + if ( ( fr >= 0 ) && ( fr < 255 ) ) + { + x->x_colorR = (int)fr; + x->x_colorY = (yuv_RGBtoY( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB ))<<7; + x->x_colorU = (yuv_RGBtoU( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + x->x_colorV = (yuv_RGBtoV( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + pdp_ctrack_draw_color( x ); + outlet_float( x->x_R, x->x_colorR ); + } +} + +static void pdp_ctrack_g(t_pdp_ctrack *x, t_floatarg fg ) +{ + if ( ( fg >= 0 ) && ( fg < 255 ) ) + { + x->x_colorG = (int)fg; + x->x_colorY = (yuv_RGBtoY( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB ))<<7; + x->x_colorU = (yuv_RGBtoU( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + x->x_colorV = (yuv_RGBtoV( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + pdp_ctrack_draw_color( x ); + outlet_float( x->x_G, x->x_colorG ); + } +} + +static void pdp_ctrack_b(t_pdp_ctrack *x, t_floatarg fb ) +{ + if ( ( fb >= 0 ) && ( fb < 255 ) ) + { + x->x_colorB = (int)fb; + x->x_colorY = (yuv_RGBtoY( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB ))<<7; + x->x_colorU = (yuv_RGBtoU( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + x->x_colorV = (yuv_RGBtoV( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + pdp_ctrack_draw_color( x ); + outlet_float( x->x_B, x->x_colorB ); + } +} + +static void pdp_ctrack_cursx(t_pdp_ctrack *x, t_floatarg fx ) +{ + if ( ( fx >= 0 ) && ( fx < x->x_vwidth) ) + { + x->x_cursX = (int)fx; + } +} + +static void pdp_ctrack_tolerance(t_pdp_ctrack *x, t_floatarg ftolerance ) +{ + if ( ftolerance >= 0 ) + { + x->x_tolerance = (int)ftolerance; + } +} + +static void pdp_ctrack_cursy(t_pdp_ctrack *x, t_floatarg fy ) +{ + if ( ( fy >= 0 ) && ( fy < x->x_vheight) ) + { + x->x_cursY = (int)fy; + } +} + +static void pdp_ctrack_luminosity(t_pdp_ctrack *x, t_floatarg fluminosity ) +{ + if ( ( fluminosity == 0 ) || ( fluminosity == 1 ) ) + { + x->x_luminosity = (int)fluminosity; + } +} + +static void pdp_ctrack_cursor(t_pdp_ctrack *x, t_floatarg fcursor ) +{ + if ( ( fcursor == 0 ) || ( fcursor == 1 ) ) + { + x->x_cursor = (int)fcursor; + } +} + +static void pdp_ctrack_frame(t_pdp_ctrack *x, t_floatarg fframe ) +{ + if ( ( fframe == 0 ) || ( fframe == 1 ) ) + { + x->x_showframe = (int)fframe; + } +} + +static void pdp_ctrack_steady(t_pdp_ctrack *x, t_floatarg fsteady ) +{ + if ( ( fsteady == 0 ) || ( fsteady == 1 ) ) + { + x->x_steady = (int)fsteady; + } +} + +static void pdp_ctrack_pick(t_pdp_ctrack *x) +{ + t_int y,u,v; + + if ( x->x_frame && ( x->x_cursX > 0 ) && ( x->x_cursX < x->x_vwidth ) + && ( x->x_cursY > 0 ) && ( x->x_cursY < x->x_vheight ) ) + { + x->x_colorY = x->x_frame[ x->x_cursY*x->x_vwidth+x->x_cursX ]; + x->x_colorV = x->x_frame[ x->x_vsize + (x->x_cursY>>1)*(x->x_vwidth>>1)+(x->x_cursX>>1) ]; + x->x_colorU = x->x_frame[ x->x_vsize + (x->x_vsize>>2) + (x->x_cursY>>1)*(x->x_vwidth>>1)+(x->x_cursX>>1) ]; + y = (x->x_colorY)>>7; + u = (x->x_colorU>>8)+128; + v = (x->x_colorV>>8)+128; + x->x_colorR = yuv_YUVtoR( y, u, v ); + outlet_float( x->x_R, x->x_colorR ); + x->x_colorG = yuv_YUVtoG( y, u, v ); + outlet_float( x->x_G, x->x_colorG ); + x->x_colorB = yuv_YUVtoB( y, u, v ); + outlet_float( x->x_B, x->x_colorB ); + pdp_ctrack_draw_color( x ); + } +} + +static void pdp_ctrack_allocate(t_pdp_ctrack *x) +{ + x->x_frame = (short int *) getbytes ( ( x->x_vsize + ( x->x_vsize>>1 ) ) << 1 ); + + if ( !x->x_frame ) + { + post( "pdp_mgrid : severe error : cannot allocate buffer !!! "); + return; + } +} + +static void pdp_ctrack_free_ressources(t_pdp_ctrack *x) +{ + if ( x->x_frame ) freebytes ( x->x_frame, ( x->x_vsize + ( x->x_vsize>>1 ) ) << 1 ); +} + +static void pdp_ctrack_process_yv12(t_pdp_ctrack *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_int i, cf; + t_int px=0, py=0, ppx=0, ppy=0, found=0, xcell=0, ycell=0; + t_int y=0, u=0, v=0; + t_int x1=0, y1=0, x2=0, y2=0; + t_int X1=0, Y1=0, X2=0, Y2=0; + short int *pfY, *pfU, *pfV; + t_int diff; + + /* allocate all ressources */ + if ( ( (int)header->info.image.width != x->x_vwidth ) || + ( (int)header->info.image.height != x->x_vheight ) ) + { + pdp_ctrack_free_ressources( x ); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_ctrack_allocate( x ); + post( "pdp_ctrack : reallocated buffers" ); + } + + memcpy(x->x_frame, data, (x->x_vsize + (x->x_vsize>>1))<<1 ); + + // draw cursor + if ( ( x->x_cursX > 0 ) && ( x->x_cursY > 0 ) && ( x->x_cursor ) ) + { + for ( px=(x->x_cursX-5); px<=(x->x_cursX+5); px++ ) + { + if ( ( px > 0 ) && ( px < x->x_vwidth ) ) + { + if ( ((*(data+x->x_cursY*x->x_vwidth+px))>>7) < 128 ) + { + *(data+x->x_cursY*x->x_vwidth+px) = 0xff<<7; + } + else + { + *(data+x->x_cursY*x->x_vwidth+px) = 0x00<<7; + } + } + } + for ( py=(x->x_cursY-5); py<=(x->x_cursY+5); py++ ) + { + if ( ( py > 0 ) && ( py < x->x_vheight ) ) + { + if ( ((*(data+py*x->x_vwidth+x->x_cursX))>>7) < 128 ) + { + *(data+py*x->x_vwidth+x->x_cursX) = 0xff<<7; + } + else + { + *(data+py*x->x_vwidth+x->x_cursX) = 0x00<<7; + } + } + } + } + + // track color + pfY = x->x_frame; + pfV = x->x_frame+x->x_vsize; + pfU = x->x_frame+x->x_vsize+(x->x_vsize>>2); + if ( x->x_colorR != -1 ) + { + for ( py=0; py<x->x_vheight; py++ ) + { + for ( px=0; px<x->x_vwidth; px++ ) + { + y = *pfY++; + v = *pfV; + u = *pfU; + + if ( x->x_luminosity ) + { + diff = (abs(y-x->x_colorY)>>7)+(abs(u-x->x_colorU)>>8)+(abs(v-x->x_colorV)>>8); + } + else + { + diff = (abs(u-x->x_colorU)>>8)+(abs(v-x->x_colorV)>>8); + } + + if ( diff <= x->x_tolerance ) + { + x1=x2=px; + y1=y2=py; + found=0; + + for (ppy=y1; ppy<x->x_vheight; ppy++) + { + found = 0; + for (ppx=x1; ppx<x->x_vwidth; ppx++) + { + y = x->x_frame[ ppy*x->x_vwidth+ppx ]; + v = x->x_frame[ x->x_vsize + (((ppy>>1)*(x->x_vwidth>>1))+(ppx>>1)) ]; + u = x->x_frame[ x->x_vsize + (x->x_vsize>>2) + (((ppy>>1)*(x->x_vwidth>>1))+(ppx>>1)) ]; + + if ( x->x_luminosity ) + { + diff = (abs(y-x->x_colorY)>>7)+(abs(u-x->x_colorU)>>8)+(abs(v-x->x_colorV)>>8); + } + else + { + diff = (abs(u-x->x_colorU)>>8)+(abs(v-x->x_colorV)>>8); + } + + if ( diff <= x->x_tolerance ) + { + if ( ppx > x2 ) x2 = ppx; + y2 = ppy; + found=1; + } + else + { + break; + } + } + if (!found) break; // a whole line without the looked-up color + } + // check further extensions + // to the bottom + for (ppx=x1; ppx<x2; ppx++) + { + for (ppy=y2; ppy<x->x_vheight; ppy++) + { + y = x->x_frame[ ppy*x->x_vwidth+ppx ]; + v = x->x_frame[ x->x_vsize + (((ppy>>1)*(x->x_vwidth>>1))+(ppx>>1)) ]; + u = x->x_frame[ x->x_vsize + (x->x_vsize>>2) + (((ppy>>1)*(x->x_vwidth>>1))+(ppx>>1)) ]; + + if ( x->x_luminosity ) + { + diff = (abs(y-x->x_colorY)>>7)+(abs(u-x->x_colorU)>>8)+(abs(v-x->x_colorV)>>8); + } + else + { + diff = (abs(u-x->x_colorU)>>8)+(abs(v-x->x_colorV)>>8); + } + + if ( diff <= x->x_tolerance ) + { + y2 = ppy; + } + else + { + break; + } + } + } + // to the left + for (ppy=y1; ppy<=y2; ppy++) + { + for (ppx=x1; ppx>0; ppx--) + { + y = x->x_frame[ ppy*x->x_vwidth+ppx ]; + v = x->x_frame[ x->x_vsize + (((ppy>>1)*(x->x_vwidth>>1))+(ppx>>1)) ]; + u = x->x_frame[ x->x_vsize + (x->x_vsize>>2) + (((ppy>>1)*(x->x_vwidth>>1))+(ppx>>1)) ]; + + if ( x->x_luminosity ) + { + diff = (abs(y-x->x_colorY)>>7)+(abs(u-x->x_colorU)>>8)+(abs(v-x->x_colorV)>>8); + } + else + { + diff = (abs(u-x->x_colorU)>>8)+(abs(v-x->x_colorV)>>8); + } + + if ( diff <= x->x_tolerance ) + { + x1 = ppx; + } + else + { + break; + } + } + } + // to the right + for (ppy=y1; ppy<=y2; ppy++) + { + for (ppx=x2; ppx<x->x_vwidth; ppx++) + { + y = x->x_frame[ ppy*x->x_vwidth+ppx ]; + v = x->x_frame[ x->x_vsize + (((ppy>>1)*(x->x_vwidth>>1))+(ppx>>1)) ]; + u = x->x_frame[ x->x_vsize + (x->x_vsize>>2) + (((ppy>>1)*(x->x_vwidth>>1))+(ppx>>1)) ]; + + if ( x->x_luminosity ) + { + diff = (abs(y-x->x_colorY)>>7)+(abs(u-x->x_colorU)>>8)+(abs(v-x->x_colorV)>>8); + } + else + { + diff = (abs(u-x->x_colorU)>>8)+(abs(v-x->x_colorV)>>8); + } + + if ( diff <= x->x_tolerance ) + { + x2 = ppx; + } + else + { + break; + } + } + } + + // select zone + if ( !x->x_steady ) + { + // track the biggest object + if ( abs(x2-x1)*abs(y2-y1) > abs(X2-X1)*abs(Y2-Y1) ) + { + X1=x1; X2=x2; Y1=y1; Y2=y2; + } + } + else + { + // check if the cursor is in selected zone + if ( (x->x_cursX>=x1) && (x->x_cursX<=x2) + && (x->x_cursY>=y1) && (x->x_cursY<=y2 ) ) + { + X1=x1; X2=x2; Y1=y1; Y2=y2; + // set new cursor position + x->x_cursX = ( X1+X2 )/2; + x->x_cursY = ( Y1+Y2 )/2; + } + } + + px=x2+1; py=y2; + // post( "pdp_ctrack : px=%d py=%d", px, py ); + } + + if ( (px%2==0) && (py%2==0) ) + { + pfU++;pfV++; + } + } + } + if ( X1!=0 || X2!=0 || Y1!=0 || Y2!=0 ) + { + outlet_float( x->x_x1, X1 ); + outlet_float( x->x_y1, Y1 ); + outlet_float( x->x_x2, X2 ); + outlet_float( x->x_y2, Y2 ); + + // draw the frame + if ( x->x_showframe ) + { + for (ppy=Y1; ppy<=Y2; ppy++) + { + if ( ((*(data+ppy*x->x_vwidth+X1))>>7) < 128 ) + { + *(data+ppy*x->x_vwidth+X1) = 0xff<<7; + } + else + { + *(data+ppy*x->x_vwidth+X1) = 0x00<<7; + } + if ( ((*(data+ppy*x->x_vwidth+X2))>>7) < 128 ) + { + *(data+ppy*x->x_vwidth+X2) = 0xff<<7; + } + else + { + *(data+ppy*x->x_vwidth+X2) = 0x00<<7; + } + } + for (ppx=X1; ppx<=X2; ppx++) + { + if ( ((*(data+Y1*x->x_vwidth+ppx))>>7) < 128 ) + { + *(data+Y1*x->x_vwidth+ppx) = 0xff<<7; + } + else + { + *(data+Y1*x->x_vwidth+ppx) = 0x00<<7; + } + if ( ((*(data+Y2*x->x_vwidth+ppx))>>7) < 128 ) + { + *(data+Y2*x->x_vwidth+ppx) = 0xff<<7; + } + else + { + *(data+Y2*x->x_vwidth+ppx) = 0x00<<7; + } + } + } + } + } + + pdp_packet_pass_if_valid(x->x_pdp_output, &x->x_packet0); + + return; +} + +static void pdp_ctrack_process(t_pdp_ctrack *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_ctrack_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + pdp_ctrack_process_yv12(x); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_ctrack_process */ + break; + + } + } + +} + +static void pdp_ctrack_input_0(t_pdp_ctrack *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + pdp_ctrack_process(x); + + } +} + +static void pdp_ctrack_free(t_pdp_ctrack *x) +{ + int i; + + pdp_packet_mark_unused(x->x_packet0); + pdp_ctrack_free_ressources( x ); +} + +t_class *pdp_ctrack_class; + +void *pdp_ctrack_new(void) +{ + int i; + + t_pdp_ctrack *x = (t_pdp_ctrack *)pd_new(pdp_ctrack_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("R")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("G")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("B")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("cursx")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("cursy")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("tolerance")); + + x->x_pdp_output = outlet_new(&x->x_obj, &s_anything); + x->x_x1 = outlet_new(&x->x_obj, &s_float); + x->x_y1 = outlet_new(&x->x_obj, &s_float); + x->x_x2 = outlet_new(&x->x_obj, &s_float); + x->x_y2 = outlet_new(&x->x_obj, &s_float); + x->x_R = outlet_new(&x->x_obj, &s_float); + x->x_G = outlet_new(&x->x_obj, &s_float); + x->x_B = outlet_new(&x->x_obj, &s_float); + + x->x_colorR = -1; + x->x_colorG = -1; + x->x_colorB = -1; + + x->x_colorY = (yuv_RGBtoY( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB ))<<7; + x->x_colorU = (yuv_RGBtoU( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + x->x_colorV = (yuv_RGBtoV( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8; + + x->x_packet0 = -1; + + x->x_cursX = -1; + x->x_cursY = -1; + x->x_tolerance = 50; + x->x_luminosity = 1; + x->x_steady = 0; + x->x_cursor = 1; + x->x_showframe = 1; + + x->x_canvas = canvas_getcurrent(); + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_ctrack_setup(void) +{ + post( pdp_ctrack_version ); + pdp_ctrack_class = class_new(gensym("pdp_ctrack"), (t_newmethod)pdp_ctrack_new, + (t_method)pdp_ctrack_free, sizeof(t_pdp_ctrack), 0, A_NULL); + + class_addmethod(pdp_ctrack_class, (t_method)pdp_ctrack_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_ctrack_class, (t_method)pdp_ctrack_r, gensym("R"), A_FLOAT, A_NULL); + class_addmethod(pdp_ctrack_class, (t_method)pdp_ctrack_g, gensym("G"), A_FLOAT, A_NULL); + class_addmethod(pdp_ctrack_class, (t_method)pdp_ctrack_b, gensym("B"), A_FLOAT, A_NULL); + class_addmethod(pdp_ctrack_class, (t_method)pdp_ctrack_cursx, gensym("cursx"), A_FLOAT, A_NULL); + class_addmethod(pdp_ctrack_class, (t_method)pdp_ctrack_cursy, gensym("cursy"), A_FLOAT, A_NULL); + class_addmethod(pdp_ctrack_class, (t_method)pdp_ctrack_pick, gensym("pick"), A_NULL); + class_addmethod(pdp_ctrack_class, (t_method)pdp_ctrack_tolerance, gensym("tolerance"), A_FLOAT, A_NULL); + class_addmethod(pdp_ctrack_class, (t_method)pdp_ctrack_luminosity, gensym("luminosity"), A_FLOAT, A_NULL); + class_addmethod(pdp_ctrack_class, (t_method)pdp_ctrack_steady, gensym("steady"), A_FLOAT, A_NULL); + class_addmethod(pdp_ctrack_class, (t_method)pdp_ctrack_cursor, gensym("cursor"), A_FLOAT, A_NULL); + class_addmethod(pdp_ctrack_class, (t_method)pdp_ctrack_frame, gensym("frame"), A_FLOAT, A_NULL); + class_addmethod(pdp_ctrack_class, (t_method)pdp_ctrack_setcur, gensym("setcur"), A_DEFFLOAT, A_DEFFLOAT, A_NULL); +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_cycle.c b/modules/pdp_cycle.c new file mode 100644 index 0000000..f2d0085 --- /dev/null +++ b/modules/pdp_cycle.c @@ -0,0 +1,246 @@ +/* + * PiDiP module + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is a port of cycle effect from EffecTV + * Originally written by clifford smith <nullset@dookie.net> + * Pd-fication by Yves Degoyon ( ydegoyon@free.fr ) + */ + + +#include "pdp.h" +#include <math.h> + +#define NEWCOLOR(c,o) ((c+o)%230) + +static char *pdp_cycle_version = "pdp_cycle: version 0.1, port of cycle from EffecTV by clifford smith, adapted by ydegoyon@free.fr "; + +typedef struct pdp_cycle_struct +{ + t_object x_obj; + t_float x_f; + + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_outlet *x_outlet0; + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + t_int x_cycley; // flag to activate y cycling + t_int x_cycleu; // flag to activate u cycling + t_int x_cyclev; // flag to activate v cycling + + t_int x_yoffset; + t_int x_uoffset; + t_int x_voffset; + +} t_pdp_cycle; + +static void pdp_cycle_cycley(t_pdp_cycle *x, t_floatarg fcycley ) +{ + if ( ( fcycley == 0 ) || ( fcycley == 1 ) ) + { + x->x_cycley = fcycley; + } +} + +static void pdp_cycle_cycleu(t_pdp_cycle *x, t_floatarg fcycleu ) +{ + if ( ( fcycleu == 0 ) || ( fcycleu == 1 ) ) + { + x->x_cycleu = fcycleu; + } +} + +static void pdp_cycle_cyclev(t_pdp_cycle *x, t_floatarg fcyclev ) +{ + if ( ( fcyclev == 0 ) || ( fcyclev == 1 ) ) + { + x->x_cyclev = fcyclev; + } +} + +static void pdp_cycle_process_yv12(t_pdp_cycle *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + t_int i; + t_int px, py, y, u, v; + + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + x->x_yoffset += 1; + x->x_uoffset += 3; + x->x_voffset += 7; + + for(py=1; py<x->x_vheight; py++) + { + for(px=0; px<x->x_vwidth; px++) + { + if ( x->x_cycley ) + { + y = *(data+py*x->x_vwidth+px)>>7; + *(newdata+py*x->x_vwidth+px) = NEWCOLOR(y,x->x_yoffset)<<7; + } + if ( x->x_cycleu ) + { + u = ( *(data+x->x_vsize+(x->x_vsize>>2)+((py*x->x_vwidth>>2)+(px>>1))) >>8 ) + 128; + *(newdata+x->x_vsize+(x->x_vsize>>2)+((py*x->x_vwidth>>2)+(px>>1))) = (NEWCOLOR(u,x->x_uoffset)-128)<<8; + } + if ( x->x_cyclev ) + { + v = ( *(data+x->x_vsize+((py*x->x_vwidth>>2)+(px>>1))) >>8 ) + 128; + *(newdata+x->x_vsize+((py*x->x_vwidth>>2)+(px>>1))) = (NEWCOLOR(v,x->x_voffset)-128)<<8; + } + } + } + + return; +} + +static void pdp_cycle_sendpacket(t_pdp_cycle *x) +{ + /* delete source packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_cycle_process(t_pdp_cycle *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_cycle_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding) + { + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_cycle_process_yv12, pdp_cycle_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_cycle_process */ + break; + + } + } + +} + +static void pdp_cycle_input_0(t_pdp_cycle *x, t_symbol *s, t_floatarg f) +{ + + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_cycle_process(x); + + } + +} + +static void pdp_cycle_free(t_pdp_cycle *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); +} + +t_class *pdp_cycle_class; + +void *pdp_cycle_new(void) +{ + int i; + + t_pdp_cycle *x = (t_pdp_cycle *)pd_new(pdp_cycle_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("cycley")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("cycleu")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("cyclev")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_cycley = 1; + x->x_cycleu = 0; + x->x_cyclev = 0; + + x->x_yoffset = 0; + x->x_uoffset = 0; + x->x_voffset = 0; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_cycle_setup(void) +{ +// post( pdp_cycle_version ); + pdp_cycle_class = class_new(gensym("pdp_cycle"), (t_newmethod)pdp_cycle_new, + (t_method)pdp_cycle_free, sizeof(t_pdp_cycle), 0, A_NULL); + + class_addmethod(pdp_cycle_class, (t_method)pdp_cycle_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_cycle_class, (t_method)pdp_cycle_cycley, gensym("cycley"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_cycle_class, (t_method)pdp_cycle_cycleu, gensym("cycleu"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_cycle_class, (t_method)pdp_cycle_cyclev, gensym("cyclev"), A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_dice.c b/modules/pdp_dice.c new file mode 100644 index 0000000..ddb6007 --- /dev/null +++ b/modules/pdp_dice.c @@ -0,0 +1,345 @@ +/* + * PiDiP module + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is a port of dice effect from EffecTV + * Originally written by clifford smith <nullset@dookie.net> + * Pd-fication by Yves Degoyon ( ydegoyon@free.fr ) + */ + + +#include "pdp.h" +#include <math.h> + +#define DEFAULT_CUBE_BITS 4 +#define MAX_CUBE_BITS 5 +#define MIN_CUBE_BITS 0 + +typedef enum _pdp_dice_dir { + up = 0, + right = 1, + down = 2, + left = 3 +} t_pdp_dice_dir; + +static unsigned int fastrand_val; +#define inline_fastrand() (fastrand_val=fastrand_val*1103515245+12345) + +static char *pdp_dice_version = "pdp_dice: version 0.1, port of dice from EffecTV by clifford smith, adapted by ydegoyon@free.fr "; + +typedef struct pdp_dice_struct +{ + t_object x_obj; + t_float x_f; + + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_outlet *x_outlet0; + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + char *x_dicemap; + + t_int x_cube_bits; + t_int x_cube_size; + t_int x_map_height; + t_int x_map_width; + +} t_pdp_dice; + +static void pdp_dice_create_map(t_pdp_dice *x) +{ + int px, py, i; + + if ( x->x_dicemap == NULL ) + { + post( "pdp_dice : tried to create map but it's not allocated" ); + return; + } + + x->x_map_height = x->x_vheight >> x->x_cube_bits; + x->x_map_width = x->x_vwidth >> x->x_cube_bits; + x->x_cube_size = 1 << x->x_cube_bits; + + i = 0; + for (py=0; py<x->x_map_height; py++) + { + for(px=0; px<x->x_map_width; px++) + { + x->x_dicemap[i] = (inline_fastrand() >> 24) & 0x03; + i++; + } + } + + return; +} + +static void pdp_dice_cubebits(t_pdp_dice *x, t_floatarg fcubebits ) +{ + if ( ( fcubebits >= MIN_CUBE_BITS ) || ( fcubebits <= MAX_CUBE_BITS ) ) + { + x->x_cube_bits = fcubebits; + pdp_dice_create_map(x); + } +} + +static void pdp_dice_free_ressources(t_pdp_dice *x) +{ + if ( x->x_dicemap ) freebytes( x->x_dicemap, x->x_vsize ); +} + +static void pdp_dice_allocate(t_pdp_dice *x) +{ + x->x_dicemap = (char *) getbytes( x->x_vsize ); +} + +static void pdp_dice_process_yv12(t_pdp_dice *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + t_int i, iuv; + t_int mapx, mapy, mapi; + t_int base, baseuv, dx, dy, di, diuv; + + /* allocate all ressources */ + if ( ((int)header->info.image.width != x->x_vwidth) || + ((int)header->info.image.height != x->x_vheight) ) + { + pdp_dice_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_dice_allocate(x); + post( "pdp_dice : reallocated buffers" ); + pdp_dice_create_map(x); + post( "pdp_dice : initialized map" ); + } + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + mapi = 0; + for(mapy = 0; mapy < x->x_map_height; mapy++) + { + for(mapx = 0; mapx < x->x_map_width; mapx++) + { + base = (mapy << x->x_cube_bits) * x->x_vwidth + (mapx << x->x_cube_bits); + baseuv = (((mapy << x->x_cube_bits)>>1) * (x->x_vwidth>>1)) + ((mapx << x->x_cube_bits)>>1); + switch (x->x_dicemap[mapi]) + { + case up: + for (dy = 0; dy < x->x_cube_size; dy++) + { + i = base + dy * x->x_vwidth; + iuv = baseuv + ((dy>>1) * (x->x_vwidth>>1)); + for (dx = 0; dx < x->x_cube_size; dx++) + { + newdata[i] = data[i]; + newdata[x->x_vsize+iuv] = data[x->x_vsize+iuv]; + newdata[x->x_vsize+(x->x_vsize>>2)+iuv] = data[x->x_vsize+(x->x_vsize>>2)+iuv]; + i++; + if ( (dx%2==0) && (dy%2==0) ) iuv++; + } + } + break; + + case left: + for (dy = 0; dy < x->x_cube_size; dy++) + { + i = base + dy * x->x_vwidth; + iuv = baseuv + ((dy>>1) * (x->x_vwidth>>1)); + for (dx = 0; dx < x->x_cube_size; dx++) + { + di = base + (dx * x->x_vwidth) + (x->x_cube_size - dy - 1); + diuv = baseuv + ((dx>>1) * (x->x_vwidth>>1)) + ((x->x_cube_size - dy - 1)>>1); + newdata[di] = data[i]; + newdata[x->x_vsize+diuv] = data[x->x_vsize+iuv]; + newdata[x->x_vsize+(x->x_vsize>>2)+diuv] = data[x->x_vsize+(x->x_vsize>>2)+iuv]; + i++; + if ( (dx%2==0) && (dy%2==0) ) iuv++; + } + } + break; + + case down: + for (dy = 0; dy < x->x_cube_size; dy++) + { + di = base + dy * x->x_vwidth; + diuv = baseuv + ((dy>>1) * (x->x_vwidth>>1)); + i = base + (x->x_cube_size - dy - 1) * x->x_vwidth + x->x_cube_size; + iuv = baseuv + (((x->x_cube_size - dy - 1)>>1) * (x->x_vwidth>>1)) + (x->x_cube_size>>1); + for (dx = 0; dx < x->x_cube_size; dx++) + { + i--; + if ( dx%2==0) iuv--; + newdata[di] = data[i]; + newdata[x->x_vsize+diuv] = data[x->x_vsize+iuv]; + newdata[x->x_vsize+(x->x_vsize>>2)+diuv] = data[x->x_vsize+(x->x_vsize>>2)+iuv]; + di++; + if ( (dx%2==0) && (dy%2==0) ) iuv++; + } + } + break; + + case right: + for (dy = 0; dy < x->x_cube_size; dy++) + { + i = base + (dy * x->x_vwidth); + iuv = baseuv + ((dy>>1) * (x->x_vwidth>>1)); + for (dx = 0; dx < x->x_cube_size; dx++) + { + di = base + dy + (x->x_cube_size - dx - 1) * x->x_vwidth; + diuv = baseuv + (dy>>1) + (((x->x_cube_size - dx - 1)>>1) * (x->x_vwidth>>1)); + newdata[di] = data[i]; + newdata[x->x_vsize+diuv] = data[x->x_vsize+iuv]; + newdata[x->x_vsize+(x->x_vsize>>2)+diuv] = data[x->x_vsize+(x->x_vsize>>2)+iuv]; + i++; + if ( (dx%2==0) && (dy%2==0) ) iuv++; + } + } + break; + + default: + break; + } + mapi++; + } + } + + return; +} + +static void pdp_dice_sendpacket(t_pdp_dice *x) +{ + /* delete source packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_dice_process(t_pdp_dice *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_dice_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding) + { + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_dice_process_yv12, pdp_dice_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_dice_process */ + break; + + } + } + +} + +static void pdp_dice_input_0(t_pdp_dice *x, t_symbol *s, t_floatarg f) +{ + + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_dice_process(x); + + } + +} + +static void pdp_dice_free(t_pdp_dice *x) +{ + int i; + + pdp_dice_free_ressources(x); + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); +} + +t_class *pdp_dice_class; + +void *pdp_dice_new(void) +{ + int i; + + t_pdp_dice *x = (t_pdp_dice *)pd_new(pdp_dice_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("cubebits")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_cube_bits = DEFAULT_CUBE_BITS; + x->x_cube_size = 0; + x->x_map_height = 0; + x->x_map_width = 0; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_dice_setup(void) +{ +// post( pdp_dice_version ); + pdp_dice_class = class_new(gensym("pdp_dice"), (t_newmethod)pdp_dice_new, + (t_method)pdp_dice_free, sizeof(t_pdp_dice), 0, A_NULL); + + class_addmethod(pdp_dice_class, (t_method)pdp_dice_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_dice_class, (t_method)pdp_dice_cubebits, gensym("cubebits"), A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_edge.c b/modules/pdp_edge.c new file mode 100644 index 0000000..89e3cd8 --- /dev/null +++ b/modules/pdp_edge.c @@ -0,0 +1,300 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is an adaptation of edge effect from effectv + * Originally written by Fukuchi Kentaro & others + * Pd-fication by Yves Degoyon + */ + + + +#include "pdp.h" +#include <math.h> + +static char *pdp_edge_version = "pdp_edge: version 0.1, port of edge from effectv( Fukuchi Kentaro ) adapted by Yves Degoyon (ydegoyon@free.fr)"; + +typedef struct pdp_edge_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + t_int x_mapw; + t_int x_maph; + t_int x_video_width_margin; + t_int *x_map; + +} t_pdp_edge; + +static void pdp_edge_allocate(t_pdp_edge *x) +{ + x->x_map = (t_int*) getbytes ( ( x->x_vwidth * x->x_vheight * sizeof (t_int) ) << 1 ); + bzero(x->x_map, ( x->x_vwidth * x->x_vheight * sizeof (t_int) ) << 1 ); +} + +static void pdp_edge_free_ressources(t_pdp_edge *x) +{ + if ( x->x_map ) freebytes ( x->x_map, ( x->x_vwidth * x->x_vheight * sizeof (t_int) ) << 1 ); +} + +static void pdp_edge_process_yv12(t_pdp_edge *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + int i; + + t_int px, py; + t_int y, u, v; + t_int y0, u0, v0; + t_int y1, u1, v1; + t_int y2, u2, v2; + t_int y3, u3, v3; + short int *pdata, *pnewdata; + + /* allocate all ressources */ + if ( (int)(header->info.image.width*header->info.image.height) != x->x_vsize ) + { + pdp_edge_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + x->x_mapw = x->x_vwidth >> 2; + x->x_maph = x->x_vheight >> 2; + x->x_video_width_margin = x->x_vwidth - ( x->x_mapw << 2 ); + pdp_edge_allocate(x); + } + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + pdata = data + x->x_vwidth*4+4; + pnewdata = newdata + x->x_vwidth*4+4; + for(py=1; py<x->x_vheight-4; py+=4) + { + for(px=1; px<x->x_vwidth-4; px+=4) + { + /* difference between the current pixel and right neighbor. */ + y2 = (*(pdata+(py*x->x_vwidth+px))>>8) - (*(pdata+(py*x->x_vwidth+px)-4)>>8); + u2 = (*(pdata+x->x_vsize+(py*x->x_vwidth>>2)+(px>>1))>>8) - + (*(pdata+x->x_vsize+(py*x->x_vwidth>>2)+(px>>1)-2)>>8); + v2 = (*(pdata+x->x_vsize+(x->x_vsize>>2)+(py*x->x_vwidth>>2)+(px>>1))>>8) - + (*(pdata+x->x_vsize+(x->x_vsize>>2)+(py*x->x_vwidth>>2)+(px>>1)-2)>>8); + y2 *= y2; + u2 *= u2; + v2 *= v2; + y2 = y2>>5; /* To lack the lower bit for saturated addition, */ + u2 = u2>>5; /* devide the value with 32, instead of 16. It is */ + v2 = v2>>4; /* same as `v2 &= 0xfefeff' */ + if(y2>127) y2 = 127; + if(u2>127) u2 = 127; + if(v2>255) v2 = 255; + + /* difference between the current pixel and upper neighbor. */ + y3 = (*(pdata+(py*x->x_vwidth+px))>>8) - (*(pdata+(py*x->x_vwidth+px)-4*x->x_vwidth)>>8); + u3 = (*(pdata+x->x_vsize+(py*x->x_vwidth>>2)+(px>>1))>>8) - + (*(pdata+x->x_vsize+(py*x->x_vwidth>>2)+(px>>1)-2*x->x_vwidth)>>8); + v3 = (*(pdata+x->x_vsize+(x->x_vsize>>2)+(py*x->x_vwidth>>2)+(px>>1))>>8) - + (*(pdata+x->x_vsize+(x->x_vsize>>2)+(py*x->x_vwidth>>2)+(px>>1)-2*x->x_vwidth)>>8); + y3 *= y3; + u3 *= u3; + v3 *= v3; + y3 = y3>>5; /* To lack the lower bit for saturated addition, */ + u3 = u3>>5; /* devide the value with 32, instead of 16. It is */ + v3 = v3>>4; /* same as `v2 &= 0xfefeff' */ + if(y3>127) y3 = 127; + if(u3>127) u3 = 127; + if(v3>255) v3 = 255; + + y0 = (x->x_map[(py-1)*x->x_vwidth*2+px*2]>>17); + u0 = (x->x_map[(py-1)*x->x_vwidth*2+px*2]>>9)&0xff; + v0 = x->x_map[(py-1)*x->x_vwidth*2+px*2]&0xff; + y1 = (x->x_map[py*x->x_vwidth*2+(px-1)*2+1]>>17); + u1 = (x->x_map[py*x->x_vwidth*2+(px-1)*2+1]>>9)&0xff; + v1 = x->x_map[py*x->x_vwidth*2+(px-1)*2+1]&0xff; + x->x_map[py*x->x_vwidth*2+px*2] = (y2<<17)|(u2<<9)|v2; + x->x_map[py*x->x_vwidth*2+px*2+1] = (y3<<17)|(u3<<9)|v3; + y = y0 + y1; + u = y & 0x01010100; + *(pnewdata+(py*x->x_vwidth+px)) = (y | (u - (u>>8)))<<8; + *(pnewdata+x->x_vsize+(py*x->x_vwidth>>2)+(px>>1)) = (y | (u - (u>>8)))<<8; + *(pnewdata+x->x_vsize+(x->x_vsize>>2)+(py*x->x_vwidth>>2)+(px>>1)) = (y | (u - (u>>8)))<<8; + y = y0 + y3; + u = y & 0x01010100; + *(pnewdata+(py*x->x_vwidth+px)+1) = (y | (u - (u>>8)))<<8; + *(pnewdata+x->x_vsize+(py*x->x_vwidth>>2)+(px>>1+1)) = (y | (u - (u>>8)))<<8; + *(pnewdata+x->x_vsize+(x->x_vsize>>2)+(py*x->x_vwidth>>2)+(px>>1+1)) = (y | (u - (u>>8)))<<8; + *(pnewdata+(py*x->x_vwidth+px)+2) = y3<<8; + *(pnewdata+x->x_vsize+(py*x->x_vwidth>>2)+((px+2)>>1)) = u3<<8; + *(pnewdata+x->x_vsize+(x->x_vsize>>2)+(py*x->x_vwidth>>2)+((px+2)>>1)) = v3<<8; + *(pnewdata+(py*x->x_vwidth+px)+3) = y3<<8; + *(pnewdata+x->x_vsize+(py*x->x_vwidth>>2)+((px+3)>>1)) = u3<<8; + *(pnewdata+x->x_vsize+(x->x_vsize>>2)+(py*x->x_vwidth>>2)+((px+3)>>1)) = v3<<8; + y = y2 + y1; + u = y & 0x01010100; + *(pnewdata+(py*x->x_vwidth+px)+x->x_vwidth) = (y | (u - (u>>8)))<<8; + *(pnewdata+x->x_vsize+((py+1)*x->x_vwidth>>2)+(px>>1)) = (y | (u - (u>>8)))<<8; + *(pnewdata+x->x_vsize+(x->x_vsize>>2)+((py+1)*x->x_vwidth>>2)+(px>>1)) = (y | (u - (u>>8)))<<8; + y = y2 + y3; + u = y & 0x01010100; + + *(pnewdata+(py*x->x_vwidth+px)+x->x_vwidth+1) = (y | (u - (u>>8)))<<8; + *(pnewdata+x->x_vsize+((py+1)*x->x_vwidth>>2)+((px+1)>>1)) = (y | (u - (u>>8)))<<8; + *(pnewdata+x->x_vsize+(x->x_vsize>>2)+((py+1)*x->x_vwidth>>2)+((px+1)>>1)) = (y | (u - (u>>8)))<<8; + + *(pnewdata+(py*x->x_vwidth+px)+x->x_vwidth+2) = y3<<8; + *(pnewdata+x->x_vsize+((py+1)*x->x_vwidth>>2)+((px+2)>>1)) = u3<<8; + *(pnewdata+x->x_vsize+(x->x_vsize>>2)+((py+1)*x->x_vwidth>>2)+((px+2)>>1)) = v3<<8; + + *(pnewdata+(py*x->x_vwidth+px)+x->x_vwidth+3) = y3<<8; + *(pnewdata+x->x_vsize+((py+1)*x->x_vwidth>>2)+((px+3)>>1)) = u3<<8; + *(pnewdata+x->x_vsize+(x->x_vsize>>2)+((py+1)*x->x_vwidth>>2)+((px+3)>>1)) = v3<<8; + + *(pnewdata+(py*x->x_vwidth+px)+2*x->x_vwidth) = y2<<8; + *(pnewdata+x->x_vsize+((py+2)*x->x_vwidth>>2)+((px)>>1)) = u2<<8; + *(pnewdata+x->x_vsize+(x->x_vsize>>2)+((py+2)*x->x_vwidth>>2)+((px)>>1)) = v2<<8; + + *(pnewdata+(py*x->x_vwidth+px)+2*x->x_vwidth+1) = y2<<8; + *(pnewdata+x->x_vsize+((py+2)*x->x_vwidth>>2)+((px+1)>>1)) = u2<<8; + *(pnewdata+x->x_vsize+(x->x_vsize>>2)+((py+2)*x->x_vwidth>>2)+((px+1)>>1)) = v2<<8; + + *(pnewdata+(py*x->x_vwidth+px)+3*x->x_vwidth) = y2<<8; + *(pnewdata+x->x_vsize+((py+3)*x->x_vwidth>>2)+((px)>>1)) = u2<<8; + *(pnewdata+x->x_vsize+(x->x_vsize>>2)+((py+3)*x->x_vwidth>>2)+((px)>>1)) = v2<<8; + + *(pnewdata+(py*x->x_vwidth+px)+3*x->x_vwidth+1) = y2<<8; + *(pnewdata+x->x_vsize+((py+3)*x->x_vwidth>>2)+((px+1)>>1)) = u2<<8; + *(pnewdata+x->x_vsize+(x->x_vsize>>2)+((py+3)*x->x_vwidth>>2)+((px+1)>>1)) = v2<<8; + } + } + + return; +} + +static void pdp_edge_sendpacket(t_pdp_edge *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_edge_process(t_pdp_edge *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_edge_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_edge_process_yv12, pdp_edge_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + break; + + default: + /* don't know the type, so dont pdp_edge_process */ + break; + + } + } + +} + +static void pdp_edge_input_0(t_pdp_edge *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_edge_process(x); + + } +} + +static void pdp_edge_free(t_pdp_edge *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); + pdp_edge_free_ressources(x); +} + +t_class *pdp_edge_class; + +void *pdp_edge_new(void) +{ + int i; + + t_pdp_edge *x = (t_pdp_edge *)pd_new(pdp_edge_class); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_edge_setup(void) +{ +// post( pdp_edge_version ); + pdp_edge_class = class_new(gensym("pdp_edge"), (t_newmethod)pdp_edge_new, + (t_method)pdp_edge_free, sizeof(t_pdp_edge), 0, A_NULL); + + class_addmethod(pdp_edge_class, (t_method)pdp_edge_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_ffmpeg~.c b/modules/pdp_ffmpeg~.c new file mode 100644 index 0000000..30e321f --- /dev/null +++ b/modules/pdp_ffmpeg~.c @@ -0,0 +1,740 @@ +/* + * Pure Data Packet module. + * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org> + * + * 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. + * + */ + +/* This object is a streaming object towards a ffmeg server + * A lot of this object code is inspired by the excellent ffmpeg.c + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * The rest is written by Yves Degoyon ( ydegoyon@free.fr ) + */ + + +#include "pdp.h" +#include <math.h> +#include <time.h> +#include <sys/time.h> +#include <avformat.h> + +#define VIDEO_BUFFER_SIZE (1024*1024) +#define MAX_AUDIO_PACKET_SIZE (128 * 1024) +#define AUDIO_PACKET_SIZE (2*1152) + +static char *pdp_ffmpeg_version = "pdp_ffmpeg~: version 0.1, a video streaming object (towards ffserver)"; + +typedef struct pdp_ffmpeg_struct +{ + t_object x_obj; + t_float x_f; + + t_int x_packet0; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + t_outlet *x_outlet_streaming; // indicates the action of streaming + t_outlet *x_outlet_nbframes; // number of frames emitted + t_outlet *x_outlet_nbframes_dropped; // number of frames dropped + + char *x_feedname; + t_int x_streaming; // streaming flag + t_int x_nbframes; // number of frames emitted + t_int x_nbframes_dropped; // number of frames dropped + t_int x_nbvideostreams; // number of video streams + t_int x_nbaudiostreams; // number of audio streams + t_int x_cursec; // current second + t_int *x_secondcount; // number of frames emitted in the current second ( per video stream ) + + /* AV data structures */ + AVFormatContext *x_avcontext; + AVFormatParameters x_avparameters; // unused but the call is necessary to allocate structures + AVPicture *x_final_picture; + AVPicture *x_formatted_picture; + AVPicture x_picture_format; + AVPicture x_picture_final; + ImgReSampleContext *x_img_resample_ctx; + uint8_t *x_video_buffer; + uint8_t *x_rdata; + uint8_t *x_buf1; + uint8_t *x_buf2; + + /* audio structures */ + short x_audio_buf[2*MAX_AUDIO_PACKET_SIZE]; /* buffer for incoming audio */ + short x_audio_enc_buf[2*MAX_AUDIO_PACKET_SIZE]; /* buffer for audio to be encoded */ + uint8_t x_audio_out[4*MAX_AUDIO_PACKET_SIZE]; /* buffer for encoded audio */ + t_int x_audioin_position; // writing position for incoming audio + t_int x_audio_per_frame; // number of audio samples to transmit for each frame + ReSampleContext *x_audio_resample_ctx; // structures for audio resample + FifoBuffer *x_audio_fifo; // audio fifos ( one per codec ) + +} t_pdp_ffmpeg; + +static int pdp_ffmpeg_read_ffserver_streams(t_pdp_ffmpeg *x) +{ + int i, err; + AVFormatContext *ic; + + err = av_open_input_file(&ic, x->x_feedname, NULL, FFM_PACKET_SIZE, NULL); + if (err < 0) + { + return err; + } + + /* copy stream format */ + x->x_avcontext->nb_streams = ic->nb_streams; + x->x_nbvideostreams = 0; + x->x_nbaudiostreams = 0; + + for(i=0;i<ic->nb_streams;i++) + { + AVStream *st; + + st = av_mallocz(sizeof(AVFormatContext)); + memcpy(st, ic->streams[i], sizeof(AVStream)); + x->x_avcontext->streams[i] = st; + + if ( ic->streams[i]->codec.codec_type == CODEC_TYPE_UNKNOWN ) + { + post( "pdp_ffmpeg~ : stream #%d # type : unknown", i ); + } + if ( ic->streams[i]->codec.codec_type == CODEC_TYPE_AUDIO ) + { + post( "pdp_ffmpeg~ : stream #%d # type : audio # id : %d # bitrate : %d", + i, ic->streams[i]->codec.codec_id, ic->streams[i]->codec.bit_rate ); + post( "pdp_ffmpeg~ : sample rate : %d # channels : %d", + ic->streams[i]->codec.sample_rate, ic->streams[i]->codec.channels ); + x->x_nbaudiostreams++; + } + if ( ic->streams[i]->codec.codec_type == CODEC_TYPE_VIDEO ) + { + post( "pdp_ffmpeg~ : stream #%d # type : video # id : %d # bitrate : %d", + i, ic->streams[i]->codec.codec_id, ic->streams[i]->codec.bit_rate ); + post( "pdp_ffmpeg~ : framerate : %d # width : %d # height : %d", + ic->streams[i]->codec.frame_rate/10000, ic->streams[i]->codec.width, ic->streams[i]->codec.height ); + x->x_nbvideostreams++; + } + } + + if ( x->x_secondcount ) free( x->x_secondcount ); + x->x_secondcount = (t_int*) malloc( x->x_nbvideostreams*sizeof(t_int) ); + memset( x->x_secondcount, 0x00, x->x_nbvideostreams*sizeof(t_int) ); + x->x_audio_fifo = (FifoBuffer*) malloc( x->x_nbaudiostreams*sizeof(FifoBuffer) ); + for ( i=0; i<x->x_nbaudiostreams; i++) + { + fifo_init(&x->x_audio_fifo[i], 2 * MAX_AUDIO_PACKET_SIZE); + } + + av_close_input_file(ic); + + return 0; +} + +static void pdp_ffmpeg_starve(t_pdp_ffmpeg *x) +{ + t_int ret, i; + + if (!x->x_streaming) + { + post("pdp_ffmpeg~ : close request but no feed is opened ... ignored" ); + return; + } + + x->x_streaming = 0; + outlet_float( x->x_outlet_streaming, x->x_streaming ); + x->x_nbframes = 0; + outlet_float( x->x_outlet_nbframes, x->x_nbframes ); + x->x_nbframes_dropped = 0; + outlet_float( x->x_outlet_nbframes_dropped, x->x_nbframes_dropped ); + if ( x->x_buf1 ) free( x->x_buf1 ); + x->x_buf1 = NULL; + if ( x->x_buf2 ) free( x->x_buf2 ); + x->x_buf2 = NULL; + + if (x->x_img_resample_ctx) + { + img_resample_close(x->x_img_resample_ctx); + x->x_img_resample_ctx = NULL; + } + + if (x->x_audio_resample_ctx) + { + audio_resample_close(x->x_audio_resample_ctx); + x->x_audio_resample_ctx = NULL; + } + + if ( ( ret = url_fclose(&x->x_avcontext->pb) ) < 0 ) + { + post("pdp_ffmpeg~ : could not close stream (ret=%d)", ret ); + } + + for(i=0;i<x->x_avcontext->nb_streams;i++) + { + avcodec_close( &x->x_avcontext->streams[i]->codec ); + av_free( x->x_avcontext->streams[i] ); + } + +} + +static void pdp_ffmpeg_feed(t_pdp_ffmpeg *x, t_symbol *s) +{ + t_int ret, i; + + if (x->x_streaming) + { + post("pdp_ffmpeg~ : feed request but a feed is running ... ignored" ); + return; + } + + if ( !strstr( s->s_name, "http:" ) || !strstr( s->s_name, ".ffm" ) ) + { + post( "pdp_ffmpeg~ : wrong feed format <%s>: should be like http://localhost:8090/test.ffm", s->s_name ); + } + if ( x->x_feedname ) free( x->x_feedname ); + x->x_feedname = (char*) malloc( strlen( s->s_name ) + 1 ); + strcpy( x->x_feedname, s->s_name ); + + /* set output format */ + x->x_avcontext->oformat = guess_format(NULL, s->s_name, NULL); + + if ( ( ret = pdp_ffmpeg_read_ffserver_streams(x) ) < 0 ) + { + post( "pdp_ffmpeg~ : error encountered while reading feed informations :", ret ); + if ( ret == -1 ) post( "pdp_ffmpeg~ : unknown error" ); + if ( ret == -2 ) post( "pdp_ffmpeg~ : i/o error" ); + if ( ret == -3 ) post( "pdp_ffmpeg~ : number syntax expected in filename" ); + if ( ret == -4 ) post( "pdp_ffmpeg~ : invalid data found" ); + if ( ret == -5 ) post( "pdp_ffmpeg~ : not enough memory" ); + if ( ret == -6 ) post( "pdp_ffmpeg~ : unknown format" ); + + x->x_streaming = 0; + outlet_float( x->x_outlet_streaming, x->x_streaming ); + return; + } + + /* open the stream now */ + if (url_fopen(&x->x_avcontext->pb, s->s_name, URL_WRONLY) < 0) + { + post("pdp_ffmpeg~ : could not open stream '%s'", s->s_name); + x->x_streaming = 0; + outlet_float( x->x_outlet_streaming, x->x_streaming ); + return; + } + else + { + post("pdp_ffmpeg~ : opened stream '%s'", s->s_name); + } + + /* open each encoder */ + for(i=0;i<x->x_avcontext->nb_streams;i++) + { + AVCodec *codec; + codec = avcodec_find_encoder(x->x_avcontext->streams[i]->codec.codec_id); + if (!codec) + { + post("pdp_ffmpeg~ : unsupported codec for output stream #%d\n", i ); + x->x_streaming = 0; + outlet_float( x->x_outlet_streaming, x->x_streaming ); + return; + } + if (avcodec_open(&x->x_avcontext->streams[i]->codec, codec) < 0) + { + post("pdp_ffmpeg~ : error while opening codec for stream #%d - maybe incorrect parameters such as bit_rate, rate, width or height\n", i); + x->x_streaming = 0; + outlet_float( x->x_outlet_streaming, x->x_streaming ); + return; + } + else + { + post("pdp_ffmpeg~ : opened encoder for stream #%d", i); + } + } + + /* set parameters */ + if (av_set_parameters(x->x_avcontext, &x->x_avparameters) < 0) + { + post("pdp_ffmpeg~ : severe error : could not set encoding parameters" ); + x->x_streaming = 0; + outlet_float( x->x_outlet_streaming, x->x_streaming ); + return; + } + + /* write header */ + if (av_write_header(x->x_avcontext) < 0) + { + post("pdp_ffmpeg~ : could not write header (incorrect codec parameters ?)\n", i); + x->x_streaming = 0; + outlet_float( x->x_outlet_streaming, x->x_streaming ); + return; + } + + x->x_streaming = 1; + outlet_float( x->x_outlet_streaming, x->x_streaming ); + x->x_nbframes = 0; + outlet_float( x->x_outlet_nbframes, x->x_nbframes ); + x->x_nbframes_dropped = 0; + outlet_float( x->x_outlet_nbframes_dropped, x->x_nbframes_dropped ); + +} + +static void pdp_ffmpeg_allocate(t_pdp_ffmpeg *x) +{ + x->x_rdata = (uint8_t*) getbytes( (x->x_vsize+(x->x_vsize>>1))*sizeof(uint8_t) ); +} + +static void pdp_ffmpeg_free_ressources(t_pdp_ffmpeg *x) +{ + if (x->x_rdata) freebytes( x->x_rdata, (x->x_vsize+(x->x_vsize>>1))*sizeof(uint8_t) ); +} + +static void pdp_ffmpeg_process_yv12(t_pdp_ffmpeg *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = 0; + short int *newdata = 0; + t_int newpacket = -1, i; + short int *pY, *pU, *pV; + uint8_t *pnY, *pnU, *pnV; + t_int px, py; + t_int svideoindex; + t_int saudioindex; + struct timeval etime; + t_int sizeout, size, encsize; + t_int framebytes; + t_int owidth, oheight; + short *pencbuf; + + /* allocate all ressources */ + if ( ((int)header->info.image.width != x->x_vwidth) || + ((int)header->info.image.height != x->x_vheight) ) + { + pdp_ffmpeg_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_ffmpeg_allocate(x); + } + + if ( x->x_streaming ) + { + AVPicture pdppict; + + pY = data; + pV = data+x->x_vsize; + pU = data+x->x_vsize+(x->x_vsize>>2); + pnY = x->x_rdata; + pnU = x->x_rdata+x->x_vsize; + pnV = x->x_rdata+x->x_vsize+(x->x_vsize>>2); + for(py=0; py<x->x_vheight; py++) + { + for(px=0; px<x->x_vwidth; px++) + { + *pnY = (uint8_t) (*(pY++)>>7); + if ( *pnY > 255 ) *pnY=255; + pnY++; + if ( (px%2==0) && (py%2==0) ) + { + *pnV = (uint8_t) (((*(pV++))>>8)+128); + if ( *pnV > 255 ) *pnV=255; + *pnU = (uint8_t) (((*(pU++))>>8)+128); + if ( *pnU > 255 ) *pnU=255; + pnU++;pnV++; + } + } + } + + if ( avpicture_fill(&pdppict, x->x_rdata, + PIX_FMT_YUV420P, + x->x_vwidth, + x->x_vheight) < 0 ) + { + post( "pdp_ffmpeg~ : could not build av picture" ); + } + + // output all video streams + svideoindex=0; + saudioindex=0; + for (i=0; i<x->x_avcontext->nb_streams; i++) + { + /* convert pixel format and size if needed */ + if ( x->x_avcontext->streams[i]->codec.codec_type == CODEC_TYPE_VIDEO ) + { + t_int size; + + // check if the framerate has been exceeded + if ( gettimeofday(&etime, NULL) == -1) + { + post("pdp_ffmpeg~ : could not read time" ); + } + if ( etime.tv_sec != x->x_cursec ) + { + x->x_cursec = etime.tv_sec; + x->x_secondcount[ svideoindex ] = 0; + } + if ( x->x_secondcount[ svideoindex ] >= x->x_avcontext->streams[i]->codec.frame_rate/10000 ) + { + x->x_nbframes_dropped++; + continue; + } + + if ( x->x_avcontext->streams[i]->codec.pix_fmt != PIX_FMT_YUV420P ) + { + /* create temporary picture */ + size = avpicture_get_size(x->x_avcontext->streams[i]->codec.pix_fmt, + x->x_vwidth, x->x_vheight ); + if (!x->x_buf1) x->x_buf1 = (uint8_t*) malloc(size); + if (!x->x_buf1) + { + post ("pdp_ffmpeg~ : severe error : could not allocate image buffer" ); + return; + } + x->x_formatted_picture = &x->x_picture_format; + avpicture_fill(x->x_formatted_picture, x->x_buf1, + x->x_avcontext->streams[i]->codec.pix_fmt, + x->x_vwidth, x->x_vheight ); + + if (img_convert(x->x_formatted_picture, + x->x_avcontext->streams[i]->codec.pix_fmt, + &pdppict, PIX_FMT_YUV420P, + x->x_vwidth, x->x_vheight ) < 0) + { + post ("pdp_ffmpeg~ : error : image conversion failed" ); + } + } + else + { + x->x_formatted_picture = &pdppict; + } + + // post ( "pdp_ffmpeg~ : resampling [%d,%d] -> [%d,%d]", + // x->x_vwidth, x->x_vheight, + // x->x_avcontext->streams[i]->codec.width, + // x->x_avcontext->streams[i]->codec.height ); + if ( ( x->x_avcontext->streams[i]->codec.width < x->x_vwidth ) && + ( x->x_avcontext->streams[i]->codec.height < x->x_vheight ) ) + { + owidth = x->x_avcontext->streams[i]->codec.width; + oheight = x->x_avcontext->streams[i]->codec.height; + + if (x->x_img_resample_ctx) img_resample_close(x->x_img_resample_ctx); + x->x_img_resample_ctx = img_resample_full_init( + owidth, oheight, + x->x_vwidth, x->x_vheight, 0, 0, 0, 0); + + size = avpicture_get_size(x->x_avcontext->streams[i]->codec.pix_fmt, + owidth, oheight ); + if ( !x->x_buf2 ) + { + x->x_buf2 = (uint8_t*) malloc(size); + } + if (!x->x_buf2) + { + post ("pdp_ffmpeg~ : severe error : could not allocate image buffer" ); + return; + } + x->x_final_picture = &x->x_picture_final; + avpicture_fill(x->x_final_picture, x->x_buf2, + x->x_avcontext->streams[i]->codec.pix_fmt, + owidth, oheight ); + + img_resample(x->x_img_resample_ctx, x->x_final_picture, x->x_formatted_picture); + + } + else + { + x->x_final_picture = x->x_formatted_picture; + } + + // encode and send the picture + { + AVFrame aframe; + t_int fsize, ret; + + memset(&aframe, 0, sizeof(AVFrame)); + *(AVPicture*)&aframe= *x->x_final_picture; + + aframe.quality = x->x_avcontext->streams[i]->quality; + + fsize = avcodec_encode_video(&x->x_avcontext->streams[i]->codec, + x->x_video_buffer, VIDEO_BUFFER_SIZE, + &aframe); + if ( ( ret = av_write_frame( x->x_avcontext, i, x->x_video_buffer, fsize) ) < 0 ) + { + post ("pdp_ffmpeg~ : error : could not send frame : (ret=%d)", ret ); + return; + } + else + { + x->x_nbframes++; + x->x_secondcount[ svideoindex++ ]++; + } + } + } + + /* convert and stream audio data */ + if ( x->x_avcontext->streams[i]->codec.codec_type == CODEC_TYPE_AUDIO ) + { + // we assume audio is synchronized on next video stream + if ( ( (i+1) < x->x_avcontext->nb_streams ) && + ( x->x_avcontext->streams[i+1]->codec.codec_type == CODEC_TYPE_VIDEO ) ) + { + x->x_audio_per_frame = + // 2*( (int) sys_getsr() ) / ( x->x_avcontext->streams[i+1]->codec.frame_rate/10000); + AUDIO_PACKET_SIZE; + // post ("pdp_ffmpeg~ : transmit %d samples", x->x_audio_per_frame ); + } + else + { + post ("pdp_ffmpeg~ : can't stream audio : video stream is not found" ); + continue; + } + + if ( x->x_audioin_position > x->x_audio_per_frame ) + { + size = x->x_audioin_position; + if ( ( x->x_avcontext->streams[i]->codec.sample_rate != (int)sys_getsr() ) || + ( x->x_avcontext->streams[i]->codec.channels != 2 ) ) + { + if (x->x_audio_resample_ctx) audio_resample_close(x->x_audio_resample_ctx); + x->x_audio_resample_ctx = + audio_resample_init(x->x_avcontext->streams[i]->codec.channels, 2, + x->x_avcontext->streams[i]->codec.sample_rate, + (int)sys_getsr()); + sizeout = audio_resample(x->x_audio_resample_ctx, + x->x_audio_enc_buf, + x->x_audio_buf, + size / (x->x_avcontext->streams[i]->codec.channels * 2)); + pencbuf = (short*) &x->x_audio_enc_buf; + sizeout = sizeout * x->x_avcontext->streams[i]->codec.channels * 2; + } + else + { + pencbuf = (short*) &x->x_audio_buf; + sizeout = size; + } + + /* output resampled raw samples */ + fifo_write(&x->x_audio_fifo[saudioindex], (uint8_t*)pencbuf, sizeout, + &x->x_audio_fifo[saudioindex].wptr); + + framebytes = x->x_avcontext->streams[i]->codec.frame_size * 2 * + x->x_avcontext->streams[i]->codec.channels; + + while (fifo_read(&x->x_audio_fifo[saudioindex], (uint8_t*)pencbuf, framebytes, + &x->x_audio_fifo[saudioindex].rptr) == 0) + { + encsize = avcodec_encode_audio(&x->x_avcontext->streams[i]->codec, + (uint8_t*)&x->x_audio_out, sizeof(x->x_audio_out), + (short *)pencbuf); + av_write_frame(x->x_avcontext, i, x->x_audio_out, encsize); + } + saudioindex++; + } + } + } + x->x_audioin_position=0; + } + return; +} + +static void pdp_ffmpeg_killpacket(t_pdp_ffmpeg *x) +{ + /* delete source packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; +} + + /* store audio data in PCM format and stream it */ +static t_int *pdp_ffmpeg_perform(t_int *w) +{ + t_float *in1 = (t_float *)(w[1]); // left audio inlet + t_float *in2 = (t_float *)(w[2]); // right audio inlet + t_pdp_ffmpeg *x = (t_pdp_ffmpeg *)(w[3]); + int n = (int)(w[4]); // number of samples + t_float fsample; + t_int isample, i; + + // just fills the buffer + while (n--) + { + fsample=*(in1++); + if (fsample > 1.0) { fsample = 1.0; } + if (fsample < -1.0) { fsample = -1.0; } + isample=(short) (32767.0 * fsample); + *(x->x_audio_buf+x->x_audioin_position)=isample; + x->x_audioin_position=(x->x_audioin_position+1)%(2*MAX_AUDIO_PACKET_SIZE); + if ( x->x_audioin_position == 2*MAX_AUDIO_PACKET_SIZE-1 ) + { + post( "pdp_ffmpeg~ : reaching end of audio buffer" ); + } + fsample=*(in2++); + if (fsample > 1.0) { fsample = 1.0; } + if (fsample < -1.0) { fsample = -1.0; } + isample=(short) (32767.0 * fsample); + *(x->x_audio_buf+x->x_audioin_position)=isample; + x->x_audioin_position=(x->x_audioin_position+1)%(2*MAX_AUDIO_PACKET_SIZE); + if ( x->x_audioin_position == 2*MAX_AUDIO_PACKET_SIZE-1 ) + { + post( "pdp_ffmpeg~ : reaching end of audio buffer" ); + } + } + + return (w+5); +} + +static void pdp_ffmpeg_dsp(t_pdp_ffmpeg *x, t_signal **sp) +{ + dsp_add(pdp_ffmpeg_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, sp[0]->s_n); +} + +static void pdp_ffmpeg_process(t_pdp_ffmpeg *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_ffmpeg_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding) + { + + case PDP_IMAGE_YV12: + pdp_queue_add(x, pdp_ffmpeg_process_yv12, pdp_ffmpeg_killpacket, &x->x_queue_id); + outlet_float( x->x_outlet_nbframes, x->x_nbframes ); + outlet_float( x->x_outlet_nbframes_dropped, x->x_nbframes_dropped ); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_ffmpeg_process */ + break; + + } + } + +} + +static void pdp_ffmpeg_input_0(t_pdp_ffmpeg *x, t_symbol *s, t_floatarg f) +{ + + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)) + { + /* add the process method and callback to the process queue */ + pdp_ffmpeg_process(x); + } + +} + +static void pdp_ffmpeg_free(t_pdp_ffmpeg *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); + pdp_ffmpeg_free_ressources(x); + if (x->x_img_resample_ctx) + { + img_resample_close(x->x_img_resample_ctx); + x->x_img_resample_ctx = NULL; + } + if (x->x_audio_resample_ctx) + { + audio_resample_close(x->x_audio_resample_ctx); + x->x_audio_resample_ctx = NULL; + } + av_free_static(); +} + +t_class *pdp_ffmpeg_class; + +void *pdp_ffmpeg_new(void) +{ + int i; + + t_pdp_ffmpeg *x = (t_pdp_ffmpeg *)pd_new(pdp_ffmpeg_class); + inlet_new (&x->x_obj, &x->x_obj.ob_pd, gensym ("signal"), gensym ("signal")); + + x->x_outlet_streaming = outlet_new(&x->x_obj, &s_float); + x->x_outlet_nbframes = outlet_new(&x->x_obj, &s_float); + x->x_outlet_nbframes_dropped = outlet_new(&x->x_obj, &s_float); + + x->x_packet0 = -1; + x->x_queue_id = -1; + x->x_nbframes = 0; + x->x_nbframes_dropped = 0; + x->x_img_resample_ctx = NULL; + x->x_audio_resample_ctx = NULL; + x->x_secondcount = NULL; + x->x_nbvideostreams = 0; + x->x_audioin_position = 0; + + x->x_rdata = NULL; + x->x_buf1 = NULL; + x->x_buf2 = NULL; + x->x_avcontext = av_mallocz(sizeof(AVFormatContext)); + x->x_video_buffer = av_malloc( VIDEO_BUFFER_SIZE ); + if ( !x->x_video_buffer || !x->x_avcontext ) + { + post( "pdp_ffmpeg~ : severe error : could not allocate video structures." ); + return NULL; + } + + // activate codecs + av_register_all(); + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_ffmpeg_tilde_setup(void) +{ + post( pdp_ffmpeg_version ); + pdp_ffmpeg_class = class_new(gensym("pdp_ffmpeg~"), (t_newmethod)pdp_ffmpeg_new, + (t_method)pdp_ffmpeg_free, sizeof(t_pdp_ffmpeg), 0, A_NULL); + + CLASS_MAINSIGNALIN(pdp_ffmpeg_class, t_pdp_ffmpeg, x_f ); + class_addmethod(pdp_ffmpeg_class, (t_method)pdp_ffmpeg_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_ffmpeg_class, (t_method)pdp_ffmpeg_dsp, gensym("dsp"), 0); + class_addmethod(pdp_ffmpeg_class, (t_method)pdp_ffmpeg_feed, gensym("feed"), A_SYMBOL, A_NULL); + class_addmethod(pdp_ffmpeg_class, (t_method)pdp_ffmpeg_starve, gensym("starve"), A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_form.c b/modules/pdp_form.c new file mode 100644 index 0000000..5b92fe8 --- /dev/null +++ b/modules/pdp_form.c @@ -0,0 +1,608 @@ +/* + * PiDiP module + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is a geometric forms generator object for PDP + * It uses imlib2 for all graphical operations + */ + +/* Listening to : + * Culturcide - Bruce + * This Heat - Independence + */ + +#include "pdp.h" +#include "yuv.h" +#include <math.h> +#include <ctype.h> +#include <Imlib2.h> // imlib2 is required + + +/* forms type */ +enum _form_type +{ + IMLIB_LINE, + IMLIB_RECTANGLE, + IMLIB_ELLIPSE +}; +typedef enum _form_type t_form_type; + +typedef struct _form +{ + t_form_type type; + t_int n1,n2,n3,n4; // numerical coordinates or rays + t_int r,g,b; +} t_form; + + +#define DEFAULT_CAPACITY 10 + +static char *pdp_form_version = "pdp_form: version 0.1 : forms rendering object written by ydegoyon@free.fr "; + +typedef struct pdp_form_struct +{ + t_object x_obj; + t_float x_f; + + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_outlet *x_outlet0; + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + t_form *x_forms; + t_int x_nbforms; + t_int x_current; + t_int x_capacity; + + /* imlib data */ + Imlib_Image x_image; + +} t_pdp_form; + + /* add a line */ +static void pdp_form_line(t_pdp_form *x, t_symbol *s, int argc, t_atom *argv) +{ + if ( x->x_nbforms >= x->x_capacity ) + { + post( "pdp_form : sorry, maximum capacity has been reached... try resize" ); + return; + } + + if ( argc < 4 ) + { + post( "pdp_form : error in the number of arguments ( minimum is 4 )", argc ); + return; + } + if ( argv[0].a_type != A_FLOAT || argv[1].a_type != A_FLOAT || + argv[2].a_type != A_FLOAT || argv[3].a_type != A_FLOAT ) { + post( "pdp_form : add : wrong arguments" ); + return; + } + + x->x_forms[x->x_nbforms].type = IMLIB_LINE; + x->x_forms[x->x_nbforms].n1 = (int)argv[0].a_w.w_float; + x->x_forms[x->x_nbforms].n2 = (int)argv[1].a_w.w_float; + x->x_forms[x->x_nbforms].n3 = (int)argv[2].a_w.w_float; + x->x_forms[x->x_nbforms].n4 = (int)argv[3].a_w.w_float; + + if ( (argc>=5) && (argv[4].a_type == A_FLOAT) ) + { + x->x_forms[x->x_nbforms].r = (int)argv[4].a_w.w_float; + } + if ( (argc>=6) && (argv[5].a_type == A_FLOAT) ) + { + x->x_forms[x->x_nbforms].g = (int)argv[5].a_w.w_float; + } + if ( (argc>=7) && (argv[6].a_type == A_FLOAT) ) + { + x->x_forms[x->x_nbforms].b = (int)argv[6].a_w.w_float; + } + + post( "pdp_form : added line [%d,%d,%d,%d] @ %d (r=%d g=%d b=%d)", + x->x_forms[x->x_nbforms].n1, x->x_forms[x->x_nbforms].n2, + x->x_forms[x->x_nbforms].n3, x->x_forms[x->x_nbforms].n4, x->x_nbforms, + x->x_forms[x->x_nbforms].r, x->x_forms[x->x_nbforms].g, x->x_forms[x->x_nbforms].b ); + + if ( x->x_current == -1 ) x->x_current = x->x_nbforms; + x->x_nbforms++; + +} + + /* add a rectangle */ +static void pdp_form_rectangle(t_pdp_form *x, t_symbol *s, int argc, t_atom *argv) +{ + if ( x->x_nbforms >= x->x_capacity ) + { + post( "pdp_form : sorry, maximum capacity has been reached... try resize" ); + return; + } + + if ( argc < 4 ) + { + post( "pdp_form : error in the number of arguments ( minimum is 4 )", argc ); + return; + } + if ( argv[0].a_type != A_FLOAT || argv[1].a_type != A_FLOAT || + argv[2].a_type != A_FLOAT || argv[3].a_type != A_FLOAT ) { + post( "pdp_form : add : wrong arguments" ); + return; + } + + x->x_forms[x->x_nbforms].type = IMLIB_RECTANGLE; + x->x_forms[x->x_nbforms].n1 = (int)argv[0].a_w.w_float; + x->x_forms[x->x_nbforms].n2 = (int)argv[1].a_w.w_float; + x->x_forms[x->x_nbforms].n3 = (int)argv[2].a_w.w_float; + x->x_forms[x->x_nbforms].n4 = (int)argv[3].a_w.w_float; + + if ( (argc>=5) && (argv[4].a_type == A_FLOAT) ) + { + x->x_forms[x->x_nbforms].r = (int)argv[4].a_w.w_float; + } + if ( (argc>=6) && (argv[5].a_type == A_FLOAT) ) + { + x->x_forms[x->x_nbforms].g = (int)argv[5].a_w.w_float; + } + if ( (argc>=7) && (argv[6].a_type == A_FLOAT) ) + { + x->x_forms[x->x_nbforms].b = (int)argv[6].a_w.w_float; + } + + post( "pdp_form : added rectangle [%d,%d,%d,%d] @ %d (r=%d g=%d b=%d)", + x->x_forms[x->x_nbforms].n1, x->x_forms[x->x_nbforms].n2, + x->x_forms[x->x_nbforms].n3, x->x_forms[x->x_nbforms].n4, x->x_nbforms, + x->x_forms[x->x_nbforms].r, x->x_forms[x->x_nbforms].g, x->x_forms[x->x_nbforms].b ); + + if ( x->x_current == -1 ) x->x_current = x->x_nbforms; + x->x_nbforms++; + +} + + /* add an ellipse */ +static void pdp_form_ellipse(t_pdp_form *x, t_symbol *s, int argc, t_atom *argv) +{ + if ( x->x_nbforms >= x->x_capacity ) + { + post( "pdp_form : sorry, maximum capacity has been reached... try resize" ); + return; + } + + if ( argc < 4 ) + { + post( "pdp_form : error in the number of arguments ( minimum is 4 )", argc ); + return; + } + if ( argv[0].a_type != A_FLOAT || argv[1].a_type != A_FLOAT || + argv[2].a_type != A_FLOAT || argv[3].a_type != A_FLOAT ) { + post( "pdp_form : add : wrong arguments" ); + return; + } + + x->x_forms[x->x_nbforms].type = IMLIB_ELLIPSE; + x->x_forms[x->x_nbforms].n1 = (int)argv[0].a_w.w_float; + x->x_forms[x->x_nbforms].n2 = (int)argv[1].a_w.w_float; + x->x_forms[x->x_nbforms].n3 = (int)argv[2].a_w.w_float; + x->x_forms[x->x_nbforms].n4 = (int)argv[3].a_w.w_float; + + if ( (argc>=5) && (argv[4].a_type == A_FLOAT) ) + { + x->x_forms[x->x_nbforms].r = (int)argv[4].a_w.w_float; + } + if ( (argc>=6) && (argv[5].a_type == A_FLOAT) ) + { + x->x_forms[x->x_nbforms].g = (int)argv[5].a_w.w_float; + } + if ( (argc>=7) && (argv[6].a_type == A_FLOAT) ) + { + x->x_forms[x->x_nbforms].b = (int)argv[6].a_w.w_float; + } + + post( "pdp_form : added ellipse [%d,%d,%d,%d] @ %d (r=%d g=%d b=%d)", + x->x_forms[x->x_nbforms].n1, x->x_forms[x->x_nbforms].n2, + x->x_forms[x->x_nbforms].n3, x->x_forms[x->x_nbforms].n4, x->x_nbforms, + x->x_forms[x->x_nbforms].r, x->x_forms[x->x_nbforms].g, x->x_forms[x->x_nbforms].b ); + + if ( x->x_current == -1 ) x->x_current = x->x_nbforms; + x->x_nbforms++; + +} + +static void pdp_form_current(t_pdp_form *x, t_floatarg fcurrent ) +{ + if ( ( fcurrent >= 0 ) && ( fcurrent < x->x_nbforms ) ) + { + // post( "pdp_form : current item set to %d", x->x_current ); + x->x_current = fcurrent; + } +} + +static void pdp_form_x1(t_pdp_form *x, t_floatarg fx ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_nbforms ) ) + { + x->x_forms[x->x_current].n1 = fx; + } +} + +static void pdp_form_y1(t_pdp_form *x, t_floatarg fy ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_nbforms ) ) + { + x->x_forms[x->x_current].n2 = fy; + } +} + +static void pdp_form_x2(t_pdp_form *x, t_floatarg fx ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_nbforms ) ) + { + x->x_forms[x->x_current].n3 = fx; + } +} + +static void pdp_form_y2(t_pdp_form *x, t_floatarg fy ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_nbforms ) ) + { + x->x_forms[x->x_current].n4 = fy; + } +} + +static void pdp_form_r(t_pdp_form *x, t_floatarg fr ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_nbforms ) ) + { + x->x_forms[x->x_current].r = fr; + } +} + +static void pdp_form_g(t_pdp_form *x, t_floatarg fg ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_nbforms ) ) + { + x->x_forms[x->x_current].g = fg; + } +} + +static void pdp_form_b(t_pdp_form *x, t_floatarg fb ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_nbforms ) ) + { + x->x_forms[x->x_current].b = fb; + } +} + +static void pdp_form_clear(t_pdp_form *x ) +{ + x->x_nbforms = 0; +} + +static void pdp_form_delete(t_pdp_form *x, t_floatarg fnum ) +{ + t_int i; + char *lostword; + + if ( ( fnum>0 ) && ( fnum<=x->x_nbforms ) ) + { + for ( i=(int)fnum; i<x->x_nbforms; i++ ) + { + memcpy( &x->x_forms[ i-1 ], &x->x_forms[ i ], sizeof( t_form ) ); + } + x->x_nbforms--; + } +} + +static void pdp_form_resize(t_pdp_form *x, t_floatarg fnewsize ) +{ + t_form *forms; + t_int i, csize; + + if ( (int) fnewsize<=0 ) return; + + // allocate new structures + forms = (t_form*) getbytes( fnewsize*sizeof(t_form) ); + + for ( i=0; i<fnewsize; i++ ) + { + forms[i].r = forms[i].g = forms[i].b = 255; + } + + if ( fnewsize < x->x_nbforms ) + { + post( "pdp_form : new size is too small : texts lost !!" ); + csize = fnewsize; + } + else + { + csize = x->x_nbforms; + } + + // copy all values + for ( i=0; i<csize; i++ ) + { + memcpy( &forms[i], &x->x_forms[i], sizeof( t_form ) ); + } + + // free old structures + if ( x->x_forms ) freebytes( x->x_forms, x->x_capacity*sizeof(t_form) ); + + // set new structures + x->x_forms = forms; + x->x_nbforms = csize; + x->x_capacity = fnewsize; + if ( x->x_nbforms > 0 ) + { + x->x_current = 0; + } + else + { + x->x_current = -1; + } +} + +static void pdp_form_allocate(t_pdp_form *x) +{ + x->x_image = imlib_create_image( x->x_vwidth, x->x_vheight ); + if ( x->x_image == NULL ) + { + post( "pdp_form : severe error : could not allocate image !!" ); + } + imlib_context_set_image(x->x_image); +} + +static void pdp_form_free_ressources(t_pdp_form *x) +{ + if ( x->x_image != NULL ) imlib_free_image(); +} + +static void pdp_form_process_yv12(t_pdp_form *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + t_int ti; + t_int px, py; + unsigned char y, u, v; + DATA32 *imdata; + DATA32 bgcolor; + short int *pY, *pU, *pV; + + if ( ( (int)(header->info.image.width) != x->x_vwidth ) || + ( (int)(header->info.image.height) != x->x_vheight ) ) + { + pdp_form_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_form_allocate(x); + } + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + memcpy( newdata, data, (x->x_vsize+(x->x_vsize>>1))<<1 ); + + // draw all texts + imlib_image_clear(); + imlib_context_set_direction(IMLIB_TEXT_TO_ANGLE); + imdata = imlib_image_get_data(); + bgcolor = imdata[0]; + + for (ti=0; ti<x->x_nbforms; ti++) + { + imlib_context_set_color( x->x_forms[ti].r, x->x_forms[ti].g, x->x_forms[ti].b, 255 ); + + switch ( x->x_forms[ti].type ) + { + case IMLIB_LINE : + imlib_image_draw_line( x->x_forms[ti].n1, x->x_forms[ti].n2, x->x_forms[ti].n3, x->x_forms[ti].n4, 1); + break; + + case IMLIB_RECTANGLE : + imlib_image_draw_rectangle( x->x_forms[ti].n1, x->x_forms[ti].n2, + x->x_forms[ti].n3-x->x_forms[ti].n1, x->x_forms[ti].n4-x->x_forms[ti].n2 ); + imlib_image_fill_rectangle( x->x_forms[ti].n1, x->x_forms[ti].n2, + x->x_forms[ti].n3-x->x_forms[ti].n1, x->x_forms[ti].n4-x->x_forms[ti].n2 ); + break; + + case IMLIB_ELLIPSE : + imlib_image_draw_ellipse( x->x_forms[ti].n1, x->x_forms[ti].n2, x->x_forms[ti].n3, x->x_forms[ti].n4 ); + imlib_image_fill_ellipse( x->x_forms[ti].n1, x->x_forms[ti].n2, x->x_forms[ti].n3, x->x_forms[ti].n4 ); + break; + } + } + + pY = newdata; + pV = newdata+x->x_vsize; + pU = newdata+x->x_vsize+(x->x_vsize>>2); + for ( py=0; py<x->x_vheight; py++ ) + { + for ( px=0; px<x->x_vwidth; px++ ) + { + if ( imdata[py*x->x_vwidth+px] != bgcolor ) + { + y = yuv_RGBtoY(imdata[py*x->x_vwidth+px]); + u = yuv_RGBtoU(imdata[py*x->x_vwidth+px]); + v = yuv_RGBtoV(imdata[py*x->x_vwidth+px]); + + *(pY) = y<<7; + if ( (px%2==0) && (py%2==0) ) + { + *(pV) = (v-128)<<8; + *(pU) = (u-128)<<8; + } + } + pY++; + if ( (px%2==0) && (py%2==0) ) + { + pV++;pU++; + } + } + } + + return; +} + +static void pdp_form_sendpacket(t_pdp_form *x) +{ + /* delete source packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_form_process(t_pdp_form *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_form_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding) + { + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_form_process_yv12, pdp_form_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_form_process */ + break; + + } + } + +} + +static void pdp_form_input_0(t_pdp_form *x, t_symbol *s, t_floatarg f) +{ + + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_form_process(x); + + } + +} + +static void pdp_form_free(t_pdp_form *x) +{ + int i; + + pdp_form_free_ressources(x); + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); +} + +t_class *pdp_form_class; + +void *pdp_form_new(void) +{ + int i; + + t_pdp_form *x = (t_pdp_form *)pd_new(pdp_form_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("current")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("x1")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("y1")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("x2")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("y2")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("r")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("g")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("b")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + x->x_image = NULL; + + x->x_capacity = DEFAULT_CAPACITY; + + x->x_forms = (t_form *) getbytes( x->x_capacity*sizeof(t_form) ); + + for ( i=0; i<x->x_capacity; i++ ) + { + x->x_forms[i].r = x->x_forms[i].g = x->x_forms[i].b = 255; + } + + x->x_nbforms = 0; + x->x_current = -1; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_form_setup(void) +{ + + post( pdp_form_version ); + pdp_form_class = class_new(gensym("pdp_form"), (t_newmethod)pdp_form_new, + (t_method)pdp_form_free, sizeof(t_pdp_form), 0, A_NULL); + + class_addmethod(pdp_form_class, (t_method)pdp_form_input_0, gensym("pdp"), + A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_form_class, (t_method)pdp_form_line, gensym("line"), A_GIMME, A_NULL); + class_addmethod(pdp_form_class, (t_method)pdp_form_rectangle, gensym("rectangle"), A_GIMME, A_NULL); + class_addmethod(pdp_form_class, (t_method)pdp_form_ellipse, gensym("ellipse"), A_GIMME, A_NULL); + class_addmethod(pdp_form_class, (t_method)pdp_form_current, gensym("current"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_form_class, (t_method)pdp_form_x1, gensym("x1"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_form_class, (t_method)pdp_form_y1, gensym("y1"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_form_class, (t_method)pdp_form_x2, gensym("x2"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_form_class, (t_method)pdp_form_y2, gensym("y2"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_form_class, (t_method)pdp_form_r, gensym("r"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_form_class, (t_method)pdp_form_g, gensym("g"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_form_class, (t_method)pdp_form_b, gensym("b"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_form_class, (t_method)pdp_form_clear, gensym("clear"), A_NULL); + class_addmethod(pdp_form_class, (t_method)pdp_form_delete, gensym("delete"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_form_class, (t_method)pdp_form_resize, gensym("resize"), A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_i.c b/modules/pdp_i.c new file mode 100644 index 0000000..4ea749c --- /dev/null +++ b/modules/pdp_i.c @@ -0,0 +1,454 @@ + +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon <ydegoyon@free.fr> + * + * 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. + * + */ + +/* This object is a video streaming receiver + * It receives PDP packets sent by a pdp_o object + */ + +#include <sys/types.h> +#include <string.h> +#include <sys/socket.h> +#include <errno.h> +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <sys/time.h> +#include <unistd.h> +#include <fcntl.h> +#include <stdio.h> +#include <bzlib.h> // bz2 decompression routines +#include "pdp.h" +#include "pdp_streaming.h" + +typedef void (*t_fdpollfn)(void *ptr, int fd); +extern void sys_rmpollfn(int fd); +extern void sys_addpollfn(int fd, t_fdpollfn fn, void *ptr); + +#define SOCKET_ERROR -1 +#define INPUT_BUFFER_SIZE 1048578 /* 1 M */ + +/* time-out used for select() call */ +static struct timeval ztout; + +static char *pdp_i_version = "pdp_i : a video stream receiver, written by ydegoyon@free.fr"; + +extern void sys_sockerror(char *s); + +void pdp_i_closesocket(int fd) +{ + if ( close(fd) < 0 ) + { + perror( "close" ); + } + else + { + post( "pdp_i : closed socket : %d", fd ); + } +} + +int pdp_i_setsocketoptions(int sockfd) +{ + int sockopt = 1; + if (setsockopt(sockfd, SOL_TCP, TCP_NODELAY, (const char*) &sockopt, sizeof(int)) < 0) + { + post("pdp_i : setsockopt TCP_NODELAY failed"); + perror( "setsockopt" ); + return -1; + } + else + { + post("pdp_i : TCP_NODELAY set"); + } + + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(int)) < 0) + { + post("pdp_i : setsockopt SO_REUSEADDR failed"); + perror( "setsockopt" ); + return -1; + } + else + { + post("pdp_i : setsockopt SO_REUSEADDR done."); + } + return 0; +} + +/* ------------------------ pdp_i ----------------------------- */ + +static t_class *pdp_i_class; + +typedef struct _pdp_i +{ + t_object x_obj; + t_int x_socket; + t_outlet *x_connection_status; + t_outlet *x_frames; + t_outlet *x_connectionip; + t_outlet *x_pdp_output; + t_int x_serversocket; + t_int x_framesreceived; // total number of frames received + + void *x_inbuffer; /* accumulation buffer for incoming frames */ + t_int x_inwriteposition; + t_int x_inbuffersize; + + /* PDP data structures */ + t_int x_packet; + t_pdp *x_header; + t_int x_vheight; + t_int x_vwidth; + t_int x_vsize; + t_int x_psize; + t_int x_hsize; + t_int x_bsize; + t_int x_bzsize; + short int *x_data; + unsigned char *x_hdata; // huffman coded data + unsigned char *x_ddata; // decompressed data + unsigned short *x_bdata; // previous data + +} t_pdp_i; + + /* huffman decoding */ +static int pdp_i_huffman(t_pdp_i *x, char *source, char *dest, t_int size, t_int *dsize) +{ + char *pcount=source; + char *pvalue=(source+1); + + *dsize=0; + while ( pcount < (source+size) ) + { + while ( (*pcount) > 0 ) + { + *(dest++)=*(pvalue); + *pcount-=1; + *dsize+=1; + } + pcount+=2; + pvalue+=2; + } + + // post( "pdp_i : dsize=%d", *dsize ); + return *dsize; +} + +static void pdp_i_free_ressources(t_pdp_i *x) +{ + if ( x->x_ddata ) freebytes( x->x_ddata, x->x_psize ); + if ( x->x_hdata ) freebytes( x->x_hdata, x->x_hsize ); + if ( x->x_bdata ) freebytes( x->x_hdata, x->x_bsize ); +} + +static void pdp_i_allocate(t_pdp_i *x) +{ + x->x_psize = x->x_vsize + (x->x_vsize>>1); + x->x_hsize = (x->x_vsize + (x->x_vsize>>1)); + x->x_bsize = (x->x_vsize + (x->x_vsize>>1))*sizeof(unsigned short); + x->x_ddata = (unsigned char*) getbytes(x->x_psize); + x->x_hdata = (unsigned char*) getbytes(x->x_hsize); + x->x_bdata = (unsigned short*) getbytes(x->x_bsize); + if ( !x->x_ddata || !x->x_hdata ) + { + post( "pdp_i : severe error : could not allocate buffer" ); + } +} + +static void pdp_i_recv(t_pdp_i *x) +{ + int ret, i; + t_hpacket *pheader; + + if ( ( ret = recv(x->x_socket, (void*) (x->x_inbuffer + x->x_inwriteposition), + (size_t)((x->x_inbuffersize-x->x_inwriteposition)), + MSG_NOSIGNAL) ) < 0 ) + { + post( "pdp_i : receive error" ); + perror( "recv" ); + return; + } + else + { + // post( "pdp_i : received %d bytes at %d on %d ( up to %d)", + // ret, x->x_inwriteposition, x->x_socket, + // x->x_inbuffersize-x->x_inwriteposition*sizeof( unsigned long) ); + + if ( ret == 0 ) + { + /* peer has reset connection */ + outlet_float( x->x_connection_status, 0 ); + pdp_i_closesocket( x->x_socket ); + sys_rmpollfn(x->x_socket); + x->x_socket = -1; + } + else + { + // check we don't overflow input buffer + if ( x->x_inwriteposition+ret >= x->x_inbuffersize ) + { + // post( "pdp_i : too much input...resetting" ); + x->x_inwriteposition=0; + return; + } + x->x_inwriteposition += ret; + if ( pheader = (t_hpacket*) strstr( (char*) x->x_inbuffer, PDP_PACKET_START ) ) + { + // check if a full packet is present + if ( x->x_inwriteposition >= (int)((char*)pheader - (char*)(x->x_inbuffer)) + (int)sizeof(t_hpacket) + (int)pheader->clength ) + { + if ( ( x->x_vwidth != pheader->width ) || + ( x->x_vheight != pheader->height ) ) + { + pdp_i_free_ressources(x); + x->x_vheight = pheader->height; + x->x_vwidth = pheader->width; + x->x_vsize = x->x_vheight*x->x_vwidth; + pdp_i_allocate(x); + post( "pdp_i : allocated buffers : vsize=%d : hsize=%d", x->x_vsize, x->x_hsize ); + } + + x->x_packet = pdp_packet_new_image_YCrCb( x->x_vwidth, x->x_vheight ); + x->x_header = pdp_packet_header(x->x_packet); + x->x_data = (short int *)pdp_packet_data(x->x_packet); + memcpy( x->x_data, x->x_bdata, x->x_bsize ); + + // post( "pdp_i : decompress %d in %d bytes", pheader->clength, x->x_hsize ); + x->x_bzsize = x->x_hsize; + + if ( ( ret = BZ2_bzBuffToBuffDecompress( (char*)x->x_hdata, + &x->x_bzsize, + (char *) pheader+sizeof(t_hpacket), + pheader->clength, + 0, 0 ) ) == BZ_OK ) + { + // post( "pdp_i : bz2 decompression (%d)->(%d)", pheader->clength, x->x_bzsize ); + + switch( pheader->encoding ) + { + case REGULAR : + memcpy( x->x_ddata, x->x_hdata, x->x_bzsize ); + break; + + case HUFFMAN : + pdp_i_huffman( x, x->x_hdata, x->x_ddata, x->x_bzsize, &x->x_psize ); + break; + } + + for ( i=0; i<x->x_vsize; i++ ) + { + if ( !strcmp( pheader->tag, PDP_PACKET_TAG ) ) + { + x->x_data[i] = x->x_ddata[i]<<7; + } + else + { + if ( x->x_ddata[i] != 0 ) + { + x->x_data[i] = x->x_ddata[i]<<7; + } + } + } + for ( i=x->x_vsize; i<(x->x_vsize+(x->x_vsize>>1)); i++ ) + { + if ( !strcmp( pheader->tag, PDP_PACKET_TAG ) ) + { + x->x_data[i] = (x->x_ddata[i])<<8; + } + else + { + if ( x->x_ddata[i] != 0 ) + { + x->x_data[i] = (x->x_ddata[i])<<8; + } + } + } + + x->x_header->info.image.encoding = PDP_IMAGE_YV12; + x->x_header->info.image.width = x->x_vwidth; + x->x_header->info.image.height = x->x_vheight; + + pdp_packet_pass_if_valid(x->x_pdp_output, &x->x_packet); + // post( "pdp_i : propagate packet : %d", x->x_packet ); + outlet_float( x->x_frames, ++x->x_framesreceived ); + } + else + { + post( "pdp_i : bz2 decompression failed (ret=%d)", ret ); + } + + memcpy( x->x_bdata, x->x_data, x->x_bsize ); + + // roll buffer + x->x_inwriteposition -= (int)((char*)pheader-(char*)(x->x_inbuffer)) + sizeof(t_hpacket) + pheader->clength; + memcpy( x->x_inbuffer, pheader+sizeof(t_hpacket) + pheader->clength, x->x_inwriteposition ); + } + } + } + + } +} + +static void pdp_i_acceptconnection(t_pdp_i *x) +{ + struct sockaddr_in incomer_address; + int sockaddrl = (int) sizeof( struct sockaddr ); + + int fd = accept(x->x_serversocket, (struct sockaddr*)&incomer_address, &sockaddrl ); + + if (fd < 0) { + post("pdp_i : accept failed"); + return; + } + + if ( x->x_socket > 0 ) + { + post( "pdp_i : accepting a new source : %s", inet_ntoa( incomer_address.sin_addr) ); + pdp_i_closesocket( x->x_socket ); + sys_rmpollfn(x->x_socket); + outlet_float( x->x_connection_status, 0 ); + } + + x->x_socket = fd; + x->x_framesreceived = 0; + sys_addpollfn(x->x_socket, (t_fdpollfn)pdp_i_recv, x); + post("pdp_i : new source : %s.", inet_ntoa( incomer_address.sin_addr )); + outlet_float( x->x_connection_status, 1 ); + outlet_float( x->x_frames, x->x_framesreceived ); + outlet_symbol( x->x_connectionip, gensym( inet_ntoa( incomer_address.sin_addr) ) ); + +} + + +static int pdp_i_startservice(t_pdp_i* x, int portno) +{ + struct sockaddr_in server; + int sockfd; + + /* create a socket */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + + if (sockfd < 0) + { + sys_sockerror("socket"); + return (0); + } + server.sin_family = AF_INET; + server.sin_addr.s_addr = INADDR_ANY; + + /* assign server port number */ + server.sin_port = htons((u_short)portno); + post("listening to port number %d", portno); + + pdp_i_setsocketoptions(sockfd); + + /* name the socket */ + if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) { + sys_sockerror("bind"); + pdp_i_closesocket(sockfd); + return (0); + } + + if (listen(sockfd, 5) < 0) { + sys_sockerror("listen"); + pdp_i_closesocket(sockfd); + } + else + { + x->x_serversocket = sockfd; + sys_addpollfn(x->x_serversocket, (t_fdpollfn)pdp_i_acceptconnection, x); + } + + return 1; +} + +static void pdp_i_free(t_pdp_i *x) +{ + post( "pdp_i : free %x", x ); + if (x->x_serversocket > 0) { + post( "pdp_i : closing server socket" ); + pdp_i_closesocket(x->x_serversocket); + sys_rmpollfn(x->x_serversocket); + x->x_serversocket = -1; + } + if (x->x_socket > 0) { + post( "pdp_i : closing socket" ); + pdp_i_closesocket(x->x_socket); + sys_rmpollfn(x->x_socket); + x->x_socket = -1; + } + if ( x->x_inbuffer ) freebytes( x->x_inbuffer, x->x_inbuffersize ); + pdp_i_free_ressources( x ); +} + +static void *pdp_i_new(t_floatarg fportno) +{ + t_pdp_i *x; + int i; + + if ( fportno <= 0 || fportno > 65535 ) + { + post( "pdp_i : error : wrong portnumber : %d", (int)fportno ); + return NULL; + } + + x = (t_pdp_i *)pd_new(pdp_i_class); + x->x_pdp_output = outlet_new(&x->x_obj, &s_anything); + x->x_connection_status = outlet_new(&x->x_obj, &s_float); + x->x_frames = outlet_new(&x->x_obj, &s_float); + x->x_connectionip = outlet_new(&x->x_obj, &s_symbol); + + x->x_serversocket = -1; + + x->x_inbuffersize = INPUT_BUFFER_SIZE; + x->x_inbuffer = (char*) getbytes( x->x_inbuffersize ); + memset( x->x_inbuffer, 0x0, INPUT_BUFFER_SIZE ); + + if ( !x->x_inbuffer ) + { + post( "pdp_i : could not allocate buffer." ); + return NULL; + } + + x->x_inwriteposition = 0; + x->x_socket = -1; + x->x_packet = -1; + x->x_ddata = NULL; + x->x_hdata = NULL; + x->x_bdata = NULL; + + ztout.tv_sec = 0; + ztout.tv_usec = 0; + + post( "pdp_i : starting service on port %d", (int)fportno ); + pdp_i_startservice(x, (int)fportno); + + return (x); +} + + +void pdp_i_setup(void) +{ + post( pdp_i_version ); + pdp_i_class = class_new(gensym("pdp_i"), + (t_newmethod) pdp_i_new, (t_method) pdp_i_free, + sizeof(t_pdp_i), CLASS_NOINLET, A_DEFFLOAT, A_DEFFLOAT, A_NULL); + +} diff --git a/modules/pdp_imgloader.c b/modules/pdp_imgloader.c new file mode 100644 index 0000000..13cae1e --- /dev/null +++ b/modules/pdp_imgloader.c @@ -0,0 +1,300 @@ +/* + * PiDiP module + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object loads an image from a file and blends it with a video + * It uses imlib2 for all graphical operations + */ + +#include "pdp.h" +#include "yuv.h" +#include <math.h> +#include <ctype.h> +#include <Imlib2.h> // imlib2 is required + +static char *pdp_imgloader_version = "pdp_imgloader: version 0.1 : image loading object written by ydegoyon@free.fr "; + +typedef struct pdp_imgloader_struct +{ + t_object x_obj; + t_float x_f; + + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_outlet *x_outlet0; + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + t_int x_xoffset; // x offset of the image + t_int x_yoffset; // y offset of the image + + /* imlib data */ + Imlib_Image x_image; + DATA32 *x_imdata; + t_int x_iwidth; + t_int x_iheight; + + t_float x_blend; + +} t_pdp_imgloader; + + /* load an image */ +static void pdp_imgloader_load(t_pdp_imgloader *x, t_symbol *filename, t_floatarg fx, t_floatarg fy) +{ + Imlib_Load_Error imliberr; + + post( "pdp_imgloader : loading : %s", filename->s_name ); + + if ( x->x_image != NULL ) + { + imlib_free_image(); + } + x->x_image = imlib_load_image_with_error_return( filename->s_name, &imliberr ); + if ( imliberr != IMLIB_LOAD_ERROR_NONE ) + { + post( "pdp_imgloader : severe error : could not load image (err=%d)!!", imliberr ); + x->x_image = NULL; + return; + } + imlib_context_set_image(x->x_image); + x->x_imdata = imlib_image_get_data(); + x->x_iwidth = imlib_image_get_width(); + x->x_iheight = imlib_image_get_height(); + post( "pdp_imgloader : loaded : %s (%dx%d)", filename->s_name, x->x_iwidth, x->x_iheight ); + x->x_xoffset = (int) fx; + x->x_yoffset = (int) fy; +} + +static void pdp_imgloader_xoffset(t_pdp_imgloader *x, t_floatarg fx ) +{ + x->x_xoffset = (int) fx; +} + +static void pdp_imgloader_yoffset(t_pdp_imgloader *x, t_floatarg fy ) +{ + x->x_yoffset = (int) fy; +} + +static void pdp_imgloader_blend(t_pdp_imgloader *x, t_floatarg fblend ) +{ + if ( ( fblend > 0.0 ) && ( fblend < 1.0 ) ) + { + x->x_blend = fblend; + } +} + +static void pdp_imgloader_clear(t_pdp_imgloader *x ) +{ + if ( x->x_image != NULL ) + { + imlib_free_image(); + } + x->x_image = NULL; +} + +static void pdp_imgloader_process_yv12(t_pdp_imgloader *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + t_int px, py; + t_float alpha, factor; + unsigned char y, u, v; + short int *pY, *pU, *pV; + + if ( ( (int)(header->info.image.width) != x->x_vwidth ) || + ( (int)(header->info.image.height) != x->x_vheight ) ) + { + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + } + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + memcpy( newdata, data, (x->x_vsize+(x->x_vsize>>1))<<1 ); + + pY = newdata; + pV = newdata+x->x_vsize; + pU = newdata+x->x_vsize+(x->x_vsize>>2); + for ( py=0; py<x->x_vheight; py++ ) + { + for ( px=0; px<x->x_vwidth; px++ ) + { + if ( ( x->x_image != NULL ) + && (px >= x->x_xoffset) && ( px < x->x_xoffset + x->x_iwidth ) + && (py >= x->x_yoffset) && ( py < x->x_yoffset + x->x_iheight ) + ) + { + y = yuv_RGBtoY(x->x_imdata[(py-x->x_yoffset)*x->x_iwidth+(px-x->x_xoffset)]); + u = yuv_RGBtoU(x->x_imdata[(py-x->x_yoffset)*x->x_iwidth+(px-x->x_xoffset)]); + v = yuv_RGBtoV(x->x_imdata[(py-x->x_yoffset)*x->x_iwidth+(px-x->x_xoffset)]); + + + if ( imlib_image_has_alpha() ) + { + alpha = (x->x_imdata[(py-x->x_yoffset)*x->x_iwidth+(px-x->x_xoffset)] >> 24)/255; + } + else + { + alpha = 1.0; + } + factor = x->x_blend*alpha; + + *(pY) = (int)((1-factor)*(*(pY)) + factor*(y<<7)); + if ( (px%2==0) && (py%2==0) ) + { + *(pV) = (int)((1-factor)*(*(pV)) + factor*((v-128)<<8)); + *(pU) = (int)((1-factor)*(*(pU)) + factor*((u-128)<<8)); + } + } + pY++; + if ( (px%2==0) && (py%2==0) ) + { + pV++;pU++; + } + } + } + + return; +} + +static void pdp_imgloader_sendpacket(t_pdp_imgloader *x) +{ + /* delete source packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_imgloader_process(t_pdp_imgloader *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_imgloader_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding) + { + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_imgloader_process_yv12, pdp_imgloader_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_imgloader_process */ + break; + + } + } + +} + +static void pdp_imgloader_input_0(t_pdp_imgloader *x, t_symbol *s, t_floatarg f) +{ + + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_imgloader_process(x); + + } + +} + +static void pdp_imgloader_free(t_pdp_imgloader *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); +} + +t_class *pdp_imgloader_class; + +void *pdp_imgloader_new(void) +{ + int i; + + t_pdp_imgloader *x = (t_pdp_imgloader *)pd_new(pdp_imgloader_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("xoffset")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("yoffset")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("blend")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + x->x_image = NULL; + + x->x_blend = 1; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_imgloader_setup(void) +{ + + post( pdp_imgloader_version ); + pdp_imgloader_class = class_new(gensym("pdp_imgloader"), (t_newmethod)pdp_imgloader_new, + (t_method)pdp_imgloader_free, sizeof(t_pdp_imgloader), 0, A_NULL); + + class_addmethod(pdp_imgloader_class, (t_method)pdp_imgloader_input_0, gensym("pdp"), + A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_imgloader_class, (t_method)pdp_imgloader_load, gensym("load"), A_SYMBOL, A_DEFFLOAT, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_imgloader_class, (t_method)pdp_imgloader_clear, gensym("clear"), A_NULL); + class_addmethod(pdp_imgloader_class, (t_method)pdp_imgloader_xoffset, gensym("xoffset"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_imgloader_class, (t_method)pdp_imgloader_yoffset, gensym("yoffset"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_imgloader_class, (t_method)pdp_imgloader_blend, gensym("blend"), A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_imgsaver.c b/modules/pdp_imgsaver.c new file mode 100644 index 0000000..5f11098 --- /dev/null +++ b/modules/pdp_imgsaver.c @@ -0,0 +1,340 @@ +/* + * PiDiP module + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object saves a snaphot to a file + * Image type is specified by extension + * It uses imlib2 for all graphical operations + */ + +#include "pdp.h" +#include "yuv.h" +#include <math.h> +#include <ctype.h> +#include <pthread.h> +#include <Imlib2.h> // imlib2 is required + +static char *pdp_imgsaver_version = "pdp_imgsaver: version 0.1 : image snapshot object written by ydegoyon@free.fr "; + +typedef struct pdp_imgsaver_struct +{ + t_object x_obj; + t_float x_f; + + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_outlet *x_outlet0; + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + t_int x_save_pending; + + /* imlib data */ + Imlib_Image x_image; + DATA32 *x_imdata; + t_int x_iwidth; + t_int x_iheight; + + t_symbol *x_filename; + short int *x_datas; + pthread_t x_savechild; /* thread id for the saving child */ + +} t_pdp_imgsaver; + + /* do save the image */ +static void *pdp_imgsaver_do_save(void *tdata) +{ + Imlib_Load_Error imliberr; + t_pdp_imgsaver *x = (t_pdp_imgsaver*) tdata; + t_int px, py; + short int *pY, *pU, *pV; + unsigned char y, u, v; + + if ( ( x->x_vwidth == 0 ) || ( x->x_vheight == 0 ) ) + { + post( "pdp_imgsaver : tried to save an image but no video is playing" ); + x->x_save_pending = 0; + x->x_filename = NULL; + return NULL; + } + + x->x_image = imlib_create_image( x->x_vwidth, x->x_vheight ); + if ( x->x_image == NULL ) + { + post( "pdp_imgsaver : severe error : could not allocate image !!" ); + x->x_save_pending = 0; + x->x_filename = NULL; + return NULL; + } + imlib_context_set_image(x->x_image); + + x->x_imdata = imlib_image_get_data(); + x->x_iwidth = imlib_image_get_width(); + x->x_iheight = imlib_image_get_height(); + + pY = x->x_datas; + pV = x->x_datas+x->x_vsize; + pU = x->x_datas+x->x_vsize+(x->x_vsize>>2); + for ( py=0; py<x->x_iheight; py++ ) + { + for ( px=0; px<x->x_iwidth; px++ ) + { + y = *(pY)>>7; + v = (*(pV)>>8)+128; + u = (*(pU)>>8)+128; + x->x_imdata[ py*x->x_iwidth + px ] = yuv_YUVtoRGB( y, u, v ); + pY++; + if ( (px%2==0) && (py%2==0) ) + { + pV++;pU++; + } + } + } + + post( "pdp_imgsaver : saving image to : %s", x->x_filename->s_name ); + imlib_save_image_with_error_return(x->x_filename->s_name, &imliberr ); + if ( imliberr != IMLIB_LOAD_ERROR_NONE ) + { + post( "pdp_imgsaver : severe error : could not save image (err=%d)!!", imliberr ); + } + else + { + post( "pdp_imgsaver : saved to : %s", x->x_filename->s_name ); + } + + if ( x->x_image != NULL ) + { + imlib_free_image(); + x->x_image = NULL; + } + + x->x_save_pending = 0; + x->x_filename = NULL; + + post( "pdp_imgsaver : saving thread %d finished", x->x_savechild ); + x->x_savechild = 0; + + return NULL; + +} + + /* launched the thread to save the image */ +static void pdp_imgsaver_save(t_pdp_imgsaver *x, t_symbol *filename) +{ + pthread_attr_t save_child_attr; + + if ( x->x_save_pending ) + { + post( "pdp_imgsaver : a save operation is currently running...retry later" ); + return; + } + x->x_save_pending = 1; + x->x_filename = filename; + if ( x->x_image != NULL ) + { + imlib_free_image(); + x->x_image = NULL; + } + + // launch saving thread + if ( pthread_attr_init( &save_child_attr ) < 0 ) + { + post( "pdp_imgsaver : could not launch save thread" ); + perror( "pthread_attr_init" ); + return; + } + if ( pthread_attr_setdetachstate( &save_child_attr, PTHREAD_CREATE_DETACHED ) < 0 ) { + post( "pdp_imgsaver : could not launch save thread" ); + perror( "pthread_attr_setdetachstate" ); + return; + } + if ( pthread_create( &x->x_savechild, &save_child_attr, pdp_imgsaver_do_save, x ) < 0 ) { + post( "pdp_imgsaver : could not launch save thread" ); + perror( "pthread_create" ); + return; + } + else + { + post( "pdp_imgsaver : saving thread %d launched", (int)x->x_savechild ); + } +} + +static void pdp_imgsaver_allocate(t_pdp_imgsaver *x) +{ + x->x_datas = (short int *)getbytes((( x->x_vsize + (x->x_vsize>>1))<<1)); +} + +static void pdp_imgsaver_free_ressources(t_pdp_imgsaver *x) +{ + if ( x->x_datas ) freebytes( x->x_datas, (( x->x_vsize + (x->x_vsize>>1))<<1)); +} + +static void pdp_imgsaver_process_yv12(t_pdp_imgsaver *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + t_int px, py; + t_float alpha, factor; + unsigned char y, u, v; + short int *pY, *pU, *pV; + + if ( ( (int)(header->info.image.width) != x->x_vwidth ) || + ( (int)(header->info.image.height) != x->x_vheight ) ) + { + pdp_imgsaver_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_imgsaver_allocate(x); + } + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + memcpy( newdata, data, (x->x_vsize+(x->x_vsize>>1))<<1 ); + if ( !x->x_save_pending ) + { + memcpy( x->x_datas, data, (x->x_vsize+(x->x_vsize>>1))<<1 ); + } + + return; +} + +static void pdp_imgsaver_sendpacket(t_pdp_imgsaver *x) +{ + /* delete source packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_imgsaver_process(t_pdp_imgsaver *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_imgsaver_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding) + { + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_imgsaver_process_yv12, pdp_imgsaver_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_imgsaver_process */ + break; + + } + } + +} + +static void pdp_imgsaver_input_0(t_pdp_imgsaver *x, t_symbol *s, t_floatarg f) +{ + + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_imgsaver_process(x); + + } + +} + +static void pdp_imgsaver_free(t_pdp_imgsaver *x) +{ + int i; + + pdp_imgsaver_free_ressources(x); + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); +} + +t_class *pdp_imgsaver_class; + +void *pdp_imgsaver_new(void) +{ + int i; + + t_pdp_imgsaver *x = (t_pdp_imgsaver *)pd_new(pdp_imgsaver_class); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_datas = NULL; + x->x_queue_id = -1; + x->x_image = NULL; + + x->x_vwidth = 0; + x->x_vheight = 0; + + x->x_save_pending = 0; + x->x_filename = NULL; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_imgsaver_setup(void) +{ + + post( pdp_imgsaver_version ); + pdp_imgsaver_class = class_new(gensym("pdp_imgsaver"), (t_newmethod)pdp_imgsaver_new, + (t_method)pdp_imgsaver_free, sizeof(t_pdp_imgsaver), 0, A_NULL); + + class_addmethod(pdp_imgsaver_class, (t_method)pdp_imgsaver_input_0, gensym("pdp"), + A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_imgsaver_class, (t_method)pdp_imgsaver_save, gensym("save"), A_SYMBOL, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_intrusion.c b/modules/pdp_intrusion.c new file mode 100644 index 0000000..26c9ead --- /dev/null +++ b/modules/pdp_intrusion.c @@ -0,0 +1,428 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is an adaptation of hologram effect from effectv + * but, in these paranoid times, i found it funnier to rename it as intrusion + * because it can detect moving objects ( targets ?? ) + * Originally written by Fukuchi Kentaro & others + * Pd-fication by Yves Degoyon + */ + + + +#include "pdp.h" +#include <math.h> + +#define NB_IMAGES 4 +#define MAGIC_THRESHOLD 10 +static unsigned int fastrand_val; +#define inline_fastrand() (fastrand_val=fastrand_val*1103515245+12345) + +static char *pdp_intrusion_version = "pdp_intrusion: version 0.1, inspired by hologram from effectv( Fukuchi Kentaro ) adapted by Yves Degoyon (ydegoyon@free.fr)"; + +typedef struct pdp_intrusion_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + unsigned int x_noisepattern[256]; // noise pattern + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + unsigned int x_encoding; + short int *x_images[NB_IMAGES]; + t_int x_rtimage; + short int *x_diff; + short int *x_bdata; + int x_threshold; + int x_phase; + int x_loopcount; + int x_threshfreq; + +} t_pdp_intrusion; + +/* check if there is a real difference with background image */ +short int *pdp_intrusion_diff(t_pdp_intrusion *x, short int *src) +{ + int i; + int Y; + int Yb; + short int *p=NULL; + short int *pb=NULL; + short int *r=NULL; + int v; + + p = src; + pb = x->x_bdata; + r = x->x_diff; + for(i=0; i<(x->x_vsize); i++) { + Y = (*p); + Yb = (*pb); + *r = (Yb - Y); + p++; pb++; + r++; + } + + return x->x_diff; +} + +static void pdp_intrusion_threshold(t_pdp_intrusion *x, t_floatarg fthreshold ) +{ + if ( fthreshold>0 && fthreshold<255 ) + { + x->x_threshold = ((int)fthreshold ) << 8; + } +} + +static void pdp_intrusion_background(t_pdp_intrusion *x ) +{ + int i, j; + + if ( ( x->x_images[0] == NULL ) || + ( x->x_images[1] == NULL ) || + ( x->x_images[2] == NULL ) || + ( x->x_images[3] == NULL ) ) + { + post( "pdp_intrusion_background : no images available !! " ); + return; + } + post( "pdp_intrusion : setting background" ); + + memcpy( x->x_bdata, x->x_images[0], (( x->x_vsize + (x->x_vsize>>1))<<1)); + + for( i=1; i<NB_IMAGES; i++ ) + { + for ( j=0; j<(x->x_vsize+(x->x_vsize>>1)); j++ ) + { + x->x_bdata[j] = (x->x_bdata[j]&x->x_images[i][j])+((x->x_bdata[j]^x->x_images[i][j])>>1); + } + } +} + +static void pdp_intrusion_allocate(t_pdp_intrusion *x, t_int newsize) +{ + int i; + + for ( i=0; i<NB_IMAGES; i++ ) + { + if ( x->x_images[i] != NULL ) + { + freebytes( x->x_images[i], (x->x_vsize + (x->x_vsize>>1))<<1 ); + } + } + if ( x->x_diff != NULL ) + { + freebytes( x->x_diff, (x->x_vsize + (x->x_vsize>>1))<<1 ); + } + if ( x->x_bdata ) freebytes( x->x_bdata, (( x->x_vsize + (x->x_vsize>>1))<<1)); + + x->x_vsize = newsize; + for ( i=0; i<NB_IMAGES; i++ ) + { + x->x_images[i] = (short int*) getbytes((x->x_vsize + (x->x_vsize>>1))<<1); + } + x->x_diff = (short int*) getbytes((x->x_vsize + (x->x_vsize>>1))<<1); + x->x_bdata = (short int *)getbytes((( x->x_vsize + (x->x_vsize>>1))<<1)); +} + +static void pdp_intrusion_process_yv12(t_pdp_intrusion *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + int i; + + unsigned int totalnbpixels; + unsigned int u_offset; + unsigned int v_offset; + unsigned int totnbpixels; + int px, py; + short int *diff; + short int *sy, *su, *sv, t; + short int *sby, *sbu, *sbv; + short int *sny, *snu, *snv; + int Y=0, U=0, V=0; + + /* allocate all ressources */ + if ( (int)(header->info.image.width*header->info.image.height) != x->x_vsize ) + { + pdp_intrusion_allocate(x, header->info.image.width*header->info.image.height ); + post( "pdp_intrusion : reallocating buffers" ); + } + + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + x->x_encoding = header->info.image.encoding; + + totalnbpixels = x->x_vsize; + u_offset = x->x_vsize; + v_offset = x->x_vsize + (x->x_vsize>>2); + totnbpixels = x->x_vsize + (x->x_vsize>>1); + + newheader->info.image.encoding = x->x_encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + /* copy images if necessary */ + memcpy( x->x_images[x->x_rtimage], data, (( x->x_vsize + (x->x_vsize>>1))<<1)); + x->x_rtimage=(x->x_rtimage+1)%4; + + if ( !x->x_bdata ) return; + + /* check pixels which has changed */ + diff = pdp_intrusion_diff(x, data); + + sy = data; + su = (data+x->x_vsize); + sv = (data+x->x_vsize+(x->x_vsize>>2)); + sby = x->x_bdata; + sbu = (x->x_bdata+x->x_vsize); + sbv = (x->x_bdata+x->x_vsize+(x->x_vsize>>2)); + sny = newdata; + snu = (newdata+x->x_vsize); + snv = (newdata+x->x_vsize+(x->x_vsize>>2)); + + for(py=1; py<x->x_vheight; py++) + { + if(((py+x->x_phase) & 0x7f)<0x58) + { + for(px=0; px<x->x_vwidth; px++) + { + if ( sv >= data + x->x_vsize + (x->x_vsize>>1 ) ) break; + if(*diff > x->x_threshold) + { + t = x->x_noisepattern[inline_fastrand()>>24]; + Y = (*sy) + t; + U = (*su) + t; + V = (*sv) + t; + Y = (Y>>1)-100; + U = (U>>1)-100; + V = V>>2; + Y += ((*sby)>>1)+((rand()%255)<<8); + U += ((*sbu)>>1)+((rand()%255)<<8); + V += ((*sbv)>>1)+((rand()%255)<<8); + // clipping + if((Y>>8)<20) Y=20<<8; + if((U>>8)<-108) U=-108<<8; + if((V>>8)<-108) V=-108<<8; + if((Y>>8)>255) Y = 255; + if((U>>8)>128) U = 128; + if((V>>8)>128) V = 128; + *sny = Y; + *snu = U; + *snv = V; + } + else + { + *sny = *sy; + *snu = *su; + *snv = *sv; + } + diff++; sy++; sby++; sny++; + if ( ((px+1)%2==0) && ((py+1)%2==0)) + { + su++; sbu++; snu++; + sv++; sbv++; snv++; + } + } + } + else + { + for(px=0; px<x->x_vwidth; px++) + { + if ( sv >= data + x->x_vsize + (x->x_vsize>>1 ) ) break; + if(*diff > x->x_threshold){ + t = x->x_noisepattern[inline_fastrand()>>24]; + Y = (*sy) + t; + U = (*su) + t; + V = (*sv) + t; + Y = (Y>>1)-100; + U = (U>>1)-100; + V = V>>2; + Y += ((*sby)>>1)+((rand()%255)<<8); + U += ((*sbu)>>1)+((rand()%255)<<8); + V += ((*sbv)>>1)+((rand()%255)<<8); + if((Y>>8)<0) Y=0; + if((U>>8)<-128) U=-128<<8; + if((V>>8)<-128) V=-128<<8; + if((Y>>8)>255) Y = 255; + if((U>>8)>128) U = 128; + if((V>>8)>128) V = 128; + *sny = Y; + *snu = U; + *snv = V; + } else { + *sny = *sy; + *snu = *su; + *snv = *sv; + } + diff++; sy++; sby++; sny++; + if ( ((px+1)%2==0) && ((py+1)%2==0) ) + { + su++; sbu++; snu++; + sv++; sbv++; snv++; + } + } + } + } + + x->x_phase-=37; + + return; +} + +static void pdp_intrusion_sendpacket(t_pdp_intrusion *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_intrusion_process(t_pdp_intrusion *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_intrusion_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_intrusion_process_yv12, pdp_intrusion_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // pdp_intrusion_process_packet(x); + break; + + default: + /* don't know the type, so dont pdp_intrusion_process */ + break; + + } + } +} + +static void pdp_intrusion_input_0(t_pdp_intrusion *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_intrusion_process(x); + + } +} + +static void pdp_intrusion_free(t_pdp_intrusion *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); + + for (i=0; i<NB_IMAGES; i++ ) + { + if ( x->x_images[i] ) freebytes( x->x_images[i], (x->x_vsize + (x->x_vsize>>1))<<1 ); + } + +} + +t_class *pdp_intrusion_class; + +void *pdp_intrusion_new(void) +{ + int i; + + t_pdp_intrusion *x = (t_pdp_intrusion *)pd_new(pdp_intrusion_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_bang, gensym("background")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("threshold")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_threshold = MAGIC_THRESHOLD<<8; + x->x_phase = 0; + x->x_bdata = NULL; + x->x_diff = NULL; + x->x_vsize = -1; + x->x_loopcount = 0; + x->x_threshfreq = 10; + + // initialize noise pattern + for(i=0; i<256; i++) + { + x->x_noisepattern[i] = (i * i * i / 40000)* i / 256; + } + + // initialize images + for(i=0; i<NB_IMAGES; i++) + { + x->x_images[i] = NULL; + } + x->x_rtimage=0; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_intrusion_setup(void) +{ +// post( pdp_intrusion_version ); + pdp_intrusion_class = class_new(gensym("pdp_intrusion"), (t_newmethod)pdp_intrusion_new, + (t_method)pdp_intrusion_free, sizeof(t_pdp_intrusion), 0, A_NULL); + + class_addmethod(pdp_intrusion_class, (t_method)pdp_intrusion_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_intrusion_class, (t_method)pdp_intrusion_background, gensym("background"), A_NULL); + class_addmethod(pdp_intrusion_class, (t_method)pdp_intrusion_threshold, gensym("threshold"), A_FLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_juxta.c b/modules/pdp_juxta.c new file mode 100644 index 0000000..e0b107a --- /dev/null +++ b/modules/pdp_juxta.c @@ -0,0 +1,319 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is an object allowing juxtaposition of frames from two inlets + * Written by Yves Degoyon + */ + + + +#include "pdp.h" +#include <math.h> + +static char *pdp_juxta_version = "pdp_juxta: version 0.1, frames juxtaposition, written by Yves Degoyon (ydegoyon@free.fr)"; + +typedef struct pdp_juxta_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_packet; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth0; + t_int x_vheight0; + t_int x_vsize0; + + t_int x_vwidth1; + t_int x_vheight1; + t_int x_vsize1; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + +} t_pdp_juxta; + +static void pdp_juxta_process_yv12(t_pdp_juxta *x) +{ + t_pdp *header0 = pdp_packet_header(x->x_packet0); + short int *data0 = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *header1 = pdp_packet_header(x->x_packet1); + short int *data1 = (short int *)pdp_packet_data(x->x_packet1); + t_pdp *header; + short int *data; + int i; + short int *poY, *poV, *poU, *p0Y, *p0V, *p0U, *p1Y, *p1V, *p1U; + + int px, py; + + if ( header0 ) + { + x->x_vwidth0 = header0->info.image.width; + x->x_vheight0 = header0->info.image.height; + x->x_vsize0 = x->x_vwidth0*x->x_vheight0; + } + else + { + x->x_vwidth0 = x->x_vheight0 = x->x_vsize0 = 0; + } + + if ( header1 ) + { + x->x_vwidth1 = header1->info.image.width; + x->x_vheight1 = header1->info.image.height; + x->x_vsize1 = x->x_vwidth1*x->x_vheight1; + } + else + { + x->x_vwidth1 = x->x_vheight1 = x->x_vsize1 = 0; + } + + x->x_vwidth = x->x_vwidth0 + x->x_vwidth1; + if ( x->x_vheight0 > x->x_vheight1 ) + { + x->x_vheight = x->x_vheight0; + } + else + { + x->x_vheight = x->x_vheight1; + } + x->x_vsize = x->x_vwidth*x->x_vheight; + // post( "pdp_juxta : resulting frame : %dx%d", x->x_vwidth, x->x_vheight ); + + x->x_packet = pdp_packet_new_image_YCrCb( x->x_vwidth, x->x_vheight ); + + header = pdp_packet_header(x->x_packet); + data = (short int *)pdp_packet_data(x->x_packet); + + header->info.image.encoding = PDP_IMAGE_YV12; + header->info.image.width = x->x_vwidth; + header->info.image.height = x->x_vheight; + + poY = data; + poV = data+x->x_vsize; + poU = data+x->x_vsize+(x->x_vsize>>2); + p0Y = data0; + p0V = data0+x->x_vsize0; + p0U = data0+x->x_vsize0+(x->x_vsize0>>2); + p1Y = data1; + p1V = data1+x->x_vsize1; + p1U = data1+x->x_vsize1+(x->x_vsize1>>2); + for ( py=0; py<x->x_vheight; py++ ) + { + for ( px=0; px<x->x_vwidth; px++ ) + { + if ( px < x->x_vwidth0 && p0Y ) + { + *poY = *p0Y; + *poV = *p0V; + *poU = *p0U; + poY++;p0Y++; + if ( (px%2==0) && (py%2==0) ) + { + poU++; poV++; + p0U++; p0V++; + } + } + if ( px >= x->x_vwidth0 && p1Y ) + { + *poY = *p1Y; + *poV = *p1V; + *poU = *p1U; + poY++;p1Y++; + if ( (px%2==0) && (py%2==0) ) + { + poU++; poV++; + p1U++; p1V++; + } + } + } + } + + return; +} + +static void pdp_juxta_sendpacket0(t_pdp_juxta *x) +{ + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet); +} + +static void pdp_juxta_sendpacket1(t_pdp_juxta *x) +{ + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet); +} + +static void pdp_juxta_process0(t_pdp_juxta *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_juxta_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + pdp_queue_add(x, pdp_juxta_process_yv12, pdp_juxta_sendpacket0, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + break; + + default: + /* don't know the type, so dont pdp_juxta_process */ + break; + + } + } +} + +static void pdp_juxta_process1(t_pdp_juxta *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet1)) + && (PDP_IMAGE == header->type)){ + + /* pdp_juxta_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet1)->info.image.encoding){ + + case PDP_IMAGE_YV12: + pdp_queue_add(x, pdp_juxta_process_yv12, pdp_juxta_sendpacket1, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + break; + + default: + /* don't know the type, so dont pdp_juxta_process */ + break; + + } + } +} + +static void pdp_juxta_input_0(t_pdp_juxta *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + { + /* release the packet */ + if ( x->x_packet0 != -1 ) + { + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + } + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + } + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_juxta_process0(x); + + } +} + +static void pdp_juxta_input_1(t_pdp_juxta *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + { + /* release the packet */ + if ( x->x_packet1 != -1 ) + { + pdp_packet_mark_unused(x->x_packet1); + x->x_packet1 = -1; + } + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet1, (int)f, pdp_gensym("image/YCrCb/*") ); + } + + if ((s == gensym("process")) && (-1 != x->x_packet1) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_juxta_process1(x); + + } +} + +static void pdp_juxta_free(t_pdp_juxta *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); + pdp_packet_mark_unused(x->x_packet1); +} + +t_class *pdp_juxta_class; + +void *pdp_juxta_new(void) +{ + int i; + + t_pdp_juxta *x = (t_pdp_juxta *)pd_new(pdp_juxta_class); + + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("pdp"), gensym("pdp1")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("pdp"), gensym("pdp2")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_packet = -1; + x->x_queue_id = -1; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_juxta_setup(void) +{ + post( pdp_juxta_version ); + pdp_juxta_class = class_new(gensym("pdp_juxta"), (t_newmethod)pdp_juxta_new, + (t_method)pdp_juxta_free, sizeof(t_pdp_juxta), CLASS_NOINLET, A_NULL); + + class_addmethod(pdp_juxta_class, (t_method)pdp_juxta_input_0, gensym("pdp1"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_juxta_class, (t_method)pdp_juxta_input_1, gensym("pdp2"), A_SYMBOL, A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_lens.c b/modules/pdp_lens.c new file mode 100644 index 0000000..a46312a --- /dev/null +++ b/modules/pdp_lens.c @@ -0,0 +1,339 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is an adaptation of lens effect from effectv + * Originally written by Fukuchi Kentaro & others + * Pd-fication by Yves Degoyon + */ + + + +#include "pdp.h" +#include <math.h> + +static char *pdp_lens_version = "pdp_lens: version 0.1, port of lens from effectv( Fukuchi Kentaro ) adapted by Yves Degoyon (ydegoyon@free.fr)"; + +typedef struct pdp_lens_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + t_float x_zoom; // zoom factor + t_int x_cx; // coordinates of lens center + t_int x_cy; // coordinates of lens center + t_int x_csize; // width of the lens + t_int x_xd; + t_int x_yd; + t_int x_mode; + t_int *x_lens; + t_int x_init; + +} t_pdp_lens; + +static void pdp_lens_preset(t_pdp_lens *x, t_int oldsize, t_int newsize) +{ + int px, py, r; + + if ( x->x_lens ) freebytes(x->x_lens, oldsize * oldsize * sizeof( t_int) ); + x->x_lens = (t_int *) getbytes( newsize * newsize * sizeof( t_int ) ); + r = x->x_csize / 2; + + /* it is sufficient to generate 1/4 of the lens and reflect this + * around; a sphere is mirrored on both the x and y axes */ + for (py = 0; py < r; py++) { + for (px = 0; px < r; px++) { + int ix, iy, offset, dist; + dist = px*px + py*py - r*r; + if(dist < 0) { + double shift = x->x_zoom/sqrt(x->x_zoom*x->x_zoom - dist); + ix = px * shift - px; + iy = py * shift - py; + } else { + ix = 0; + iy = 0; + } + offset = (iy * x->x_vwidth + ix); + x->x_lens[(r - py)*x->x_csize + r - px] = -offset; + x->x_lens[(r + py)*x->x_csize + r + px] = offset; + offset = (-iy * x->x_vwidth + ix); + x->x_lens[(r + py)*x->x_csize + r - px] = -offset; + x->x_lens[(r - py)*x->x_csize + r + px] = offset; + } + } +} + +static void pdp_lens_cliplens(t_pdp_lens *x) +{ + if (x->x_cy<0-(x->x_csize/2)+1)x->x_cy=0-(x->x_csize/2)+1; + if (x->x_cy>=x->x_vheight-x->x_csize/2-1)x->x_cy=x->x_vheight-x->x_csize/2-1; + + if (x->x_cx<0-(x->x_csize/2)+1) x->x_cx=0-x->x_csize/2+1; + if(x->x_cx>=x->x_vwidth-x->x_csize/2-1) x->x_cx=x->x_vwidth-x->x_csize/2-1; +} + +static void pdp_lens_zoom(t_pdp_lens *x, t_floatarg fzoom ) +{ + if ( fzoom>0 ) + { + x->x_zoom = fzoom; + if (x->x_zoom<5) x->x_zoom=5; + if (x->x_zoom>200) x->x_zoom=200; + pdp_lens_preset(x, x->x_csize, x->x_csize); + } +} + +static void pdp_lens_csize(t_pdp_lens *x, t_floatarg fcsize ) +{ + if ( fcsize>0 ) + { + x->x_csize = (int)fcsize; + if (x->x_csize>x->x_vheight) x->x_csize = x->x_vheight; + if (x->x_csize<3) x->x_csize = 3; + pdp_lens_preset(x, x->x_csize, x->x_csize); + pdp_lens_cliplens(x); + } +} + +static void pdp_lens_cy(t_pdp_lens *x, t_floatarg fcy ) +{ + if ( fcy>0 ) + { + x->x_cy = (int)fcy; + pdp_lens_cliplens(x); + } +} + +static void pdp_lens_cx(t_pdp_lens *x, t_floatarg fcx ) +{ + if ( fcx>0 ) + { + x->x_cx = (int)fcx; + pdp_lens_cliplens(x); + } +} + +static void pdp_lens_mode(t_pdp_lens *x, t_floatarg fmode ) +{ + if ( ( fmode == 0 ) || ( fmode == 1 ) ) + { + x->x_mode = (int)fmode; + } +} + +static void pdp_lens_process_yv12(t_pdp_lens *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + int i; + + unsigned int totalnbpixels; + unsigned int u_offset; + unsigned int v_offset; + unsigned int totnbpixels; + short int *poy, *pou, *pov, *pny, *pnu, *pnv; + int px, py; + int noy, pos, posu, nox; + int *p; + + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + + if ( x->x_init == -1 ) + { + pdp_lens_preset( x, x->x_csize, x->x_csize ); + x->x_init = 1; + } + + totalnbpixels = x->x_vsize; + u_offset = x->x_vsize; + v_offset = x->x_vsize + (x->x_vsize>>2); + totnbpixels = x->x_vsize + (x->x_vsize>>1); + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + memcpy(newdata, data, (x->x_vsize + (x->x_vsize>>1))<<1); + + p = x->x_lens; + poy = data; + pou = data + x->x_vsize; + pov = data + x->x_vsize + (x->x_vsize>>2); + pny = newdata; + pnu = newdata + x->x_vsize; + pnv = newdata + x->x_vsize + (x->x_vsize>>2); + for (py = 0; py < x->x_csize; py++) + { + for (px = 0; px < x->x_csize; px++) + { + noy=(py+x->x_cy); + nox=(px+x->x_cx); + if ((nox>=0)&&(noy>=0)&&(nox<x->x_vwidth)&&(noy<x->x_vheight)){ + pos = (noy * x->x_vwidth) + nox; + posu = ((noy>>1) * (x->x_vwidth>>1)) + (nox>>1); + if ( ( ( pos + *p )< x->x_vsize ) && ( pos < x->x_vsize ) ) + { + *(pny+pos) = *(poy + pos + *p); + *(pnu+posu) = *(pou + posu + *p ); + *(pnv+posu) = *(pov + posu + *p ); + } + } + p++; + } + } + + if (x->x_mode==1) + { + x->x_cx+= x->x_xd; x->x_cy+=x->x_yd; + if (x->x_cx > (x->x_vwidth - x->x_csize - 5) || x->x_cx < 5) x->x_xd = -x->x_xd; + if (x->x_cy > (x->x_vwidth - x->x_csize - 5) || x->x_cy < 5) x->x_yd = -x->x_yd; + } + + return; +} + +static void pdp_lens_sendpacket(t_pdp_lens *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_lens_process(t_pdp_lens *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_lens_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_lens_process_yv12, pdp_lens_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // pdp_lens_process_packet(x); + break; + + default: + /* don't know the type, so dont pdp_lens_process */ + break; + + } + } +} + +static void pdp_lens_input_0(t_pdp_lens *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_lens_process(x); + + } +} + +static void pdp_lens_free(t_pdp_lens *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); +} + +t_class *pdp_lens_class; + +void *pdp_lens_new(void) +{ + int i; + + t_pdp_lens *x = (t_pdp_lens *)pd_new(pdp_lens_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("cx")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("cy")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("csize")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("zoom")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("mode")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_cx = x->x_cy = 16; + x->x_xd = x->x_yd = 5; + x->x_csize = 150; + x->x_zoom = 30; + x->x_init = -1; + x->x_mode = 0; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_lens_setup(void) +{ +// post( pdp_lens_version ); + pdp_lens_class = class_new(gensym("pdp_lens"), (t_newmethod)pdp_lens_new, + (t_method)pdp_lens_free, sizeof(t_pdp_lens), 0, A_NULL); + + class_addmethod(pdp_lens_class, (t_method)pdp_lens_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_lens_class, (t_method)pdp_lens_cx, gensym("cx"), A_FLOAT, A_NULL); + class_addmethod(pdp_lens_class, (t_method)pdp_lens_cy, gensym("cy"), A_FLOAT, A_NULL); + class_addmethod(pdp_lens_class, (t_method)pdp_lens_csize, gensym("csize"), A_FLOAT, A_NULL); + class_addmethod(pdp_lens_class, (t_method)pdp_lens_zoom, gensym("zoom"), A_FLOAT, A_NULL); + class_addmethod(pdp_lens_class, (t_method)pdp_lens_mode, gensym("mode"), A_FLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_live~.c b/modules/pdp_live~.c new file mode 100644 index 0000000..aa8398d --- /dev/null +++ b/modules/pdp_live~.c @@ -0,0 +1,789 @@ +/* + * Pure Data Packet module. + * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org> + * + * 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. + * + */ + +/* This object is a stream decoder object + * A lot of this object code is inspired by the excellent ffmpeg.c + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * The rest is written by Yves Degoyon ( ydegoyon@free.fr ) + */ + + +#include "pdp.h" +#include "yuv.h" +#include <pthread.h> +#include <stdio.h> +#include <unistd.h> +#include <math.h> +#include <time.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <avformat.h> + +#define VIDEO_BUFFER_SIZE (1024*1024) +#define MAX_AUDIO_PACKET_SIZE (128 * 1024) +#define MIN_AUDIO_SIZE (64 * 1024) +#define AUDIO_PACKET_SIZE (2*1152) + +#define DEFAULT_CHANNELS 1 +#define DEFAULT_FRAME_RATE 25 +#define DEFAULT_WIDTH 320 +#define DEFAULT_HEIGHT 240 +#define DEFAULT_PRIORITY 0 + +static char *pdp_live_version = "pdp_live~: version 0.1, a video stream decoder ( ydegoyon@free.fr)."; + +typedef struct pdp_live_struct +{ + t_object x_obj; + t_float x_f; + + t_int x_packet0; + t_int x_dropped; + + t_pdp *x_header; + short int *x_data; + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + t_outlet *x_pdp_out; // output decoded pdp packets + t_outlet *x_outlet_left; // left audio output + t_outlet *x_outlet_right; // right audio output + t_outlet *x_outlet_streaming; // indicates the action of streaming + t_outlet *x_outlet_nbframes; // number of frames emitted + + pthread_t x_connectchild; // thread used for connecting to a stream + pthread_t x_decodechild; // stream decoding thread + t_int x_usethread; // flag to activate decoding in a thread + t_int x_priority; // priority of decoding thread + + char *x_url; + t_int x_streaming; // streaming flag + t_int x_nbframes; // number of frames emitted + t_int x_framerate; // framerate + t_int x_samplerate; // audio sample rate + t_int x_audiochannels; // audio channels + t_int x_audioon; // enough audio data to start playing + struct timeval x_starttime; // streaming starting time + t_int x_cursec; // current second + t_int x_secondcount; // number of frames received in the current second + t_int x_nbvideostreams; // number of video streams + t_int x_nbaudiostreams; // number of audio streams + + /* AV data structures */ + AVFormatContext *x_avcontext; + AVFormatParameters x_avparameters; // unused but the call is necessary to allocate structures + AVPacket x_pkt; // packet received on the stream + AVPicture x_picture_decoded; + t_int x_newpicture; + + /* audio structures */ + t_int x_audio; // flag to activate the decoding of audio + short x_audio_buf[4*MAX_AUDIO_PACKET_SIZE]; /* buffer for audio from stream*/ + short x_audio_in[4*MAX_AUDIO_PACKET_SIZE]; /* buffer for resampled PCM audio */ + t_int x_audioin_position; // writing position for incoming audio + ReSampleContext *x_audio_resample_ctx; // structures for audio resample + +} t_pdp_live; + +static void pdp_live_priority(t_pdp_live *x, t_floatarg fpriority ) +{ + x->x_priority = (int)fpriority; +} + +static void pdp_live_threadify(t_pdp_live *x, t_floatarg fusethread ) +{ + if ( ( fusethread == 0 ) || ( fusethread == 1 ) ) + { + x->x_usethread = (int)fusethread; + } +} + +static void pdp_live_audio(t_pdp_live *x, t_floatarg faudio ) +{ + if ( ( faudio == 0.0 ) || ( faudio == 1 ) ) + { + x->x_audio = (int)faudio; + } +} + +static t_int pdp_live_decode_packet(t_pdp_live *x) +{ + t_int chunksize=0, length; + t_int audiosize, sizeout, imagesize, pictureok; + AVFrame frame; + uint8_t *pcktptr; + struct timeval etime; + + if ( !x->x_streaming ) + { + return -1; + } + + // read new packet on the stream + if (av_read_packet(x->x_avcontext, &x->x_pkt) < 0) + { + // post( "pdp_live~ : decoding thread : nothing to decode" ); + return -1; + } + // post( "pdp_live~ : read packet ( size=%d )", x->x_pkt.size ); + + if (x->x_pkt.stream_index >= x->x_avcontext->nb_streams) + { + post("pdp_live~ : stream received out of range !! "); + return 0; + } + + length = x->x_pkt.size; + pcktptr = x->x_pkt.data; + while (length > 0) + { + switch(x->x_avcontext->streams[x->x_pkt.stream_index]->codec.codec_type) + { + case CODEC_TYPE_AUDIO: + if ( !x->x_audio ) + { + av_free_packet(&x->x_pkt); + return 0; + } + chunksize = avcodec_decode_audio(&x->x_avcontext->streams[x->x_pkt.stream_index]->codec, + &x->x_audio_buf[0], &audiosize, + pcktptr, length); + if (chunksize < 0) + { + post("pdp_live~ : could not decode audio input (ret=%d)", chunksize ); + av_free_packet(&x->x_pkt); + continue; + } + // some bug in mpeg audio decoder gives + // data_size < 0, it seems they are overflows + if (audiosize <= 0) + { + /* no audio frame */ + pcktptr += chunksize; + length -= chunksize; + // post("pdp_live~ : audio overflow in decoder!"); + continue; + } + + // resample received audio + // post( "pdp_live~ : resampling from %dHz-%dch to %dHz-%dch (in position=%d)", + // x->x_avcontext->streams[x->x_pkt.stream_index]->codec.sample_rate, + // x->x_avcontext->streams[x->x_pkt.stream_index]->codec.channels, + // (int)sys_getsr(), 2, x->x_audioin_position ); + + x->x_audiochannels = x->x_avcontext->streams[x->x_pkt.stream_index]->codec.channels; + x->x_samplerate = x->x_avcontext->streams[x->x_pkt.stream_index]->codec.sample_rate; + if (x->x_audio_resample_ctx) audio_resample_close(x->x_audio_resample_ctx); + x->x_audio_resample_ctx = + audio_resample_init(DEFAULT_CHANNELS, + x->x_avcontext->streams[x->x_pkt.stream_index]->codec.channels, + (int)sys_getsr(), + x->x_avcontext->streams[x->x_pkt.stream_index]->codec.sample_rate); + + sizeout = audio_resample(x->x_audio_resample_ctx, + &x->x_audio_in[x->x_audioin_position], + &x->x_audio_buf[0], + audiosize/(x->x_avcontext->streams[x->x_pkt.stream_index]->codec.channels * sizeof(short))); + sizeout = sizeout * DEFAULT_CHANNELS; + + if ( ( x->x_audioin_position + sizeout ) < 3*MAX_AUDIO_PACKET_SIZE ) + { + x->x_audioin_position = x->x_audioin_position + sizeout; + } + else + { + post( "pdp_live~ : audio overflow : packet ignored..."); + } + if ( ( x->x_audioin_position > MIN_AUDIO_SIZE ) && (!x->x_audioon) ) + { + x->x_audioon = 1; + // post( "pdp_live~ : audio on" ); + } + break; + + case CODEC_TYPE_VIDEO: + + imagesize = (x->x_avcontext->streams[x->x_pkt.stream_index]->codec.width * + x->x_avcontext->streams[x->x_pkt.stream_index]->codec.height * 3) / 2; // yuv planar + + // do not believe the declared framerate + // x->x_framerate = x->x_avcontext->streams[x->x_pkt.stream_index]->codec.frame_rate / 10000; + + // calculate actual frame rate + if ( gettimeofday(&etime, NULL) == -1) + { + post("pdp_live~ : could not read time" ); + } + if ( ( etime.tv_sec - x->x_starttime.tv_sec ) > 0 ) + { + x->x_framerate = x->x_nbframes / ( etime.tv_sec - x->x_starttime.tv_sec ); + } + if ( x->x_framerate == 0 ) x->x_framerate = 1; + // post ("pdp_live~ : frame rate is %d", x->x_framerate ); + + chunksize = avcodec_decode_video( + &x->x_avcontext->streams[x->x_pkt.stream_index]->codec, + &frame, &pictureok, + pcktptr, length); + if ( x->x_avcontext->streams[x->x_pkt.stream_index]->codec.pix_fmt != PIX_FMT_YUV420P ) + { + post( "pdp_live~ : unsupported image format : %d", + x->x_avcontext->streams[x->x_pkt.stream_index]->codec.pix_fmt ); + pictureok = 0; + } + // post( "pdp_live~ : decoded new frame : type=%d format=%d (w=%d) (h=%d) (linesizes=%d,%d,%d,%d)", + // frame.pict_type, + // x->x_avcontext->streams[x->x_pkt.stream_index]->codec.pix_fmt, + // x->x_avcontext->streams[x->x_pkt.stream_index]->codec.width, + // x->x_avcontext->streams[x->x_pkt.stream_index]->codec.height, + // frame.linesize[0], + // frame.linesize[1], + // frame.linesize[2], + // frame.linesize[3] ); + x->x_picture_decoded = *(AVPicture*)&frame; + x->x_avcontext->streams[x->x_pkt.stream_index]->quality= frame.quality; + if (chunksize < 0) + { + av_free_packet(&x->x_pkt); + post("pdp_live~ : could not decode video frame (ret=%d)", chunksize ); + return 0; + } + if (!pictureok) + { + // no picture yet + pcktptr += chunksize; + length -= chunksize; + continue; + } + else + { + x->x_newpicture=1; + x->x_vwidth = x->x_avcontext->streams[x->x_pkt.stream_index]->codec.width; + x->x_vheight = x->x_avcontext->streams[x->x_pkt.stream_index]->codec.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + } + break; + } + pcktptr += chunksize; + length -= chunksize; + if ( !x->x_streaming ) break; + } + av_free_packet(&x->x_pkt); + + // post( "pdp_live~ : decoded one packet" ); + return 0; + +} + +static void *pdp_decode_stream_from_url(void *tdata) +{ + t_pdp_live *x = (t_pdp_live*)tdata; + struct sched_param schedprio; + t_int pmin, pmax; + struct timespec twait; + + twait.tv_sec = 0; + twait.tv_nsec = 10000000; // 10 ms + + schedprio.sched_priority = 0; + if ( sched_setscheduler(0,SCHED_OTHER,&schedprio) == -1) + { + post("pdp_live~ : couldn't set scheduler for decoding thread.\n"); + } + if ( setpriority( PRIO_PROCESS, 0, x->x_priority ) < 0 ) + { + post("pdp_live~ : couldn't set priority to %d for decoding thread.\n", x->x_priority ); + } + else + { + post("pdp_live~ : priority set to %d for thread %d.\n", x->x_priority, x->x_decodechild ); + } + + if ( ! (x->x_avcontext->iformat->flags & AVFMT_NOHEADER ) ) + { + if (x->x_avcontext->iformat->read_header(x->x_avcontext, &x->x_avparameters) < 0) + { + post( "pdp_live~ : couldn't read header" ); + } + post( "pdp_live~ : read header." ); + } + + while ( x->x_streaming ) + { + while ( x->x_newpicture ) nanosleep( &twait, NULL ); + + // decode incoming packets + if ( pdp_live_decode_packet( x ) < 0 ) + { + nanosleep( &twait, NULL ); // nothing to read, just wait + } + } + + post( "pdp_live~ : decoding thread %d exiting....", x->x_decodechild ); + x->x_decodechild = 0; + pthread_exit(NULL); +} + +static void *pdp_live_connect_to_url(void *tdata) +{ + int i, err; + t_pdp_live *x = (t_pdp_live*)tdata; + pthread_attr_t decode_child_attr; + + memset(&x->x_avparameters, 0, sizeof(AVFormatParameters)); + x->x_avparameters.sample_rate = sys_getsr(); + x->x_avparameters.channels = DEFAULT_CHANNELS; + x->x_avparameters.frame_rate = DEFAULT_FRAME_RATE; + x->x_avparameters.width = DEFAULT_WIDTH; + x->x_avparameters.height = DEFAULT_HEIGHT; + x->x_avparameters.image_format = PIX_FMT_YUV420P; + + post( "pdp_live~ : opening url : %s", x->x_url ); + err = av_open_input_file(&x->x_avcontext, x->x_url, x->x_avcontext->iformat, 0, &x->x_avparameters); + if (err < 0) + { + if ( err == -1 ) post( "pdp_live~ : unknown error" ); + if ( err == -2 ) post( "pdp_live~ : i/o error" ); + if ( err == -3 ) post( "pdp_live~ : number syntax expected in filename" ); + if ( err == -4 ) post( "pdp_live~ : invalid data found" ); + if ( err == -5 ) post( "pdp_live~ : not enough memory" ); + if ( err == -6 ) post( "pdp_live~ : unknown format ( stream not found? )" ); + x->x_connectchild = 0; + x->x_avcontext = av_mallocz(sizeof(AVFormatContext)); + pthread_exit(NULL); + } + /* If not enough info to get the stream parameters, we decode the + first frames to get it. (used in mpeg case for example) */ + err = av_find_stream_info(x->x_avcontext); + if (err < 0) + { + post( "pdp_live~ : %s: could not find codec parameters\n", x->x_url); + x->x_connectchild = 0; + av_close_input_file(x->x_avcontext); + x->x_avcontext = av_mallocz(sizeof(AVFormatContext)); + pthread_exit(NULL); + } + + // post( "pdp_live~ : stream reader : %x", x->x_avcontext->iformat ); + + /* copy stream format */ + x->x_nbvideostreams = 0; + x->x_nbaudiostreams = 0; + + for(i=0;i<x->x_avcontext->nb_streams;i++) + { + AVStream *st; + + if ( x->x_avcontext->streams[i]->codec.codec_type == CODEC_TYPE_UNKNOWN ) + { + post( "pdp_live~ : stream #%d # type : unknown", i ); + } + if ( x->x_avcontext->streams[i]->codec.codec_type == CODEC_TYPE_AUDIO ) + { + post( "pdp_live~ : stream #%d # type : audio # id : %d # bitrate : %d", + i, x->x_avcontext->streams[i]->codec.codec_id, x->x_avcontext->streams[i]->codec.bit_rate ); + post( "pdp_live~ : sample rate : %d # channels : %d", + x->x_avcontext->streams[i]->codec.sample_rate, x->x_avcontext->streams[i]->codec.channels ); + x->x_nbaudiostreams++; + } + if ( x->x_avcontext->streams[i]->codec.codec_type == CODEC_TYPE_VIDEO ) + { + post( "pdp_live~ : stream #%d # type : video # id : %d # bitrate : %d", + i, x->x_avcontext->streams[i]->codec.codec_id, + x->x_avcontext->streams[i]->codec.bit_rate ); + post( "pdp_live~ : framerate : %d # width : %d # height : %d", + x->x_avcontext->streams[i]->codec.frame_rate/10000, + x->x_avcontext->streams[i]->codec.width, + x->x_avcontext->streams[i]->codec.height ); + x->x_nbvideostreams++; + } + } + + /* open each decoder */ + for(i=0;i<x->x_avcontext->nb_streams;i++) + { + AVCodec *codec; + post("pdp_live~ : opening decoder for stream #%d", i); + codec = avcodec_find_decoder(x->x_avcontext->streams[i]->codec.codec_id); + if (!codec) + { + post("pdp_live~ : unsupported codec for output stream #%d\n", i ); + x->x_streaming = 0; + x->x_connectchild = 0; + av_close_input_file(x->x_avcontext); + x->x_avcontext = av_mallocz(sizeof(AVFormatContext)); + pthread_exit(NULL); + } + if (avcodec_open(&x->x_avcontext->streams[i]->codec, codec) < 0) + { + post("pdp_live~ : error while opening codec for stream #%d - maybe incorrect parameters such as bit_rate, rate, width or height\n", i); + x->x_streaming = 0; + x->x_connectchild = 0; + av_close_input_file(x->x_avcontext); + x->x_avcontext = av_mallocz(sizeof(AVFormatContext)); + pthread_exit(NULL); + } + else + { + post("pdp_live~ : opened decoder for stream #%d", i); + } + } + + if ( gettimeofday(&x->x_starttime, NULL) == -1) + { + post("pdp_live~ : could not set start time" ); + } + x->x_streaming = 1; + x->x_nbframes = 0; + + x->x_connectchild = 0; + + if ( x->x_usethread ) + { + // launch decoding thread + if ( pthread_attr_init( &decode_child_attr ) < 0 ) + { + post( "pdp_live~ : could not launch decoding thread" ); + perror( "pthread_attr_init" ); + av_close_input_file(x->x_avcontext); + x->x_avcontext = av_mallocz(sizeof(AVFormatContext)); + pthread_exit(NULL); + } + if ( pthread_create( &x->x_decodechild, &decode_child_attr, pdp_decode_stream_from_url, x ) < 0 ) + { + post( "pdp_live~ : could not launch decoding thread" ); + perror( "pthread_create" ); + av_close_input_file(x->x_avcontext); + x->x_avcontext = av_mallocz(sizeof(AVFormatContext)); + pthread_exit(NULL); + } + else + { + post( "pdp_live~ : decoding thread %d launched", (int)x->x_decodechild ); + } + } + + pthread_exit(NULL); +} + +static void pdp_live_disconnect(t_pdp_live *x) +{ + t_int ret, i, count=0; + struct timespec twait; + + twait.tv_sec = 0; + twait.tv_nsec = 100000000; // 100 ms + + if (!x->x_streaming) + { + post("pdp_live~ : close request but no stream is played ... ignored" ); + return; + } + + if ( x->x_streaming ) + { + x->x_streaming = 0; + x->x_newpicture = 0; + post("pdp_live~ : waiting for the end of decoding thread..." ); + while ( x->x_decodechild && ( count < 100 ) ) + { + count++; + sleep( 1 ); + } + if ( x->x_decodechild ) + { + post("pdp_live~ : zombie thread, i guess" ); + } + post("pdp_live~ : closing input file..." ); + av_close_input_file(x->x_avcontext); + x->x_avcontext = av_mallocz(sizeof(AVFormatContext)); + } + + outlet_float( x->x_outlet_streaming, x->x_streaming ); + x->x_nbframes = 0; + outlet_float( x->x_outlet_nbframes, x->x_nbframes ); + + if (x->x_audio_resample_ctx) + { + audio_resample_close(x->x_audio_resample_ctx); + x->x_audio_resample_ctx = NULL; + } + +} + +static void pdp_live_connect(t_pdp_live *x, t_symbol *s) +{ + t_int ret, i; + pthread_attr_t connect_child_attr; + + if ( ( x->x_streaming ) || ( x->x_connectchild != 0 ) ) + { + post("pdp_live~ : connection request but a connection is pending ... disconnecting" ); + pdp_live_disconnect(x); + } + + if ( x->x_url ) free( x->x_url ); + x->x_url = (char*) malloc( strlen( s->s_name ) + 1 ); + strcpy( x->x_url, s->s_name ); + + // launch connection thread + if ( pthread_attr_init( &connect_child_attr ) < 0 ) { + post( "pdp_live~ : could not launch connection thread" ); + perror( "pthread_attr_init" ); + return; + } + if ( pthread_attr_setdetachstate( &connect_child_attr, PTHREAD_CREATE_DETACHED ) < 0 ) { + post( "pdp_live~ : could not launch connection thread" ); + perror( "pthread_attr_setdetachstate" ); + return; + } + if ( pthread_create( &x->x_connectchild, &connect_child_attr, pdp_live_connect_to_url, x ) < 0 ) { + post( "pdp_live~ : could not launch connection thread" ); + perror( "pthread_create" ); + return; + } + else + { + post( "pdp_live~ : connection thread %d launched", (int)x->x_connectchild ); + } + + return; +} + + /* decode the stream to fill up buffers */ +static t_int *pdp_live_perform(t_int *w) +{ + t_float *out1 = (t_float *)(w[1]); // left audio inlet + t_float *out2 = (t_float *)(w[2]); // right audio inlet + t_pdp_live *x = (t_pdp_live *)(w[3]); + int n = (int)(w[4]); // number of samples + short int *pY, *pU, *pV; + uint8_t *psY, *psU, *psV; + t_int pixRGB, px, py; + short sampleL, sampleR; + struct timeval etime; + t_int sn; + + // decode a packet if not in thread mode + if ( !x->x_usethread ) + { + pdp_live_decode_packet( x ); + } + + // just read the buffer + if ( x->x_audioon ) + { + sn=0; + n=n*DEFAULT_CHANNELS; + while (n--) + { + sampleL=x->x_audio_in[ sn++ ]; + *(out1) = ((t_float)sampleL)/32768.0; + if ( DEFAULT_CHANNELS == 1 ) + { + *(out2) = *(out1); + } + if ( DEFAULT_CHANNELS == 2 ) + { + sampleR=x->x_audio_in[ sn++ ]; + *(out2) = ((t_float)sampleR)/32768.0; + } + out1++; + out2++; + } + x->x_audioin_position-=sn; + memcpy( &x->x_audio_in[0], &x->x_audio_in[sn], 4*MAX_AUDIO_PACKET_SIZE-sn ); + // post( "pdp_live~ : audio in position : %d", x->x_audioin_position ); + if ( x->x_audioin_position <= sn ) + { + x->x_audioon = 0; + // post( "pdp_live~ : audio off" ); + } + } + else + { + // post("pdp_live~ : no available audio" ); + while (n--) + { + *(out1++) = 0.0; + *(out2++) = 0.0; + } + } + + // check if the framerate has been exceeded + if ( gettimeofday(&etime, NULL) == -1) + { + post("pdp_live~ : could not read time" ); + } + if ( etime.tv_sec != x->x_cursec ) + { + x->x_cursec = etime.tv_sec; + x->x_secondcount = 0; + } + if ( x->x_secondcount >= x->x_framerate ) + { + // return (w+5); + } + + // output image if there's a new one decoded + if ( x->x_newpicture ) + { + // create a new pdp packet from PIX_FMT_YUV420P image format + x->x_packet0 = pdp_packet_new_image_YCrCb( x->x_vwidth, x->x_vheight ); + x->x_header = pdp_packet_header(x->x_packet0); + x->x_data = (short int *)pdp_packet_data(x->x_packet0); + + pY = x->x_data; + pV = x->x_data+x->x_vsize; + pU = x->x_data+x->x_vsize+(x->x_vsize>>2); + + psY = x->x_picture_decoded.data[0]; + psU = x->x_picture_decoded.data[1]; + psV = x->x_picture_decoded.data[2]; + + for ( py=0; py<x->x_vheight; py++) + { + for ( px=0; px<x->x_vwidth; px++) + { + *(pY) = ( *(psY+px) << 7 ); + *(pV) = ( ((*(psV+(px>>1)))-128) << 8 ); + *(pU) = ( ((*(psU+(px>>1)))-128) << 8 ); + pY++; + if ( (px%2==0) && (py%2==0) ) + { + pV++; pU++; + } + } + psY += x->x_picture_decoded.linesize[0]; + if ( py%2==0 ) psU += x->x_picture_decoded.linesize[1]; + if ( py%2==0 ) psV += x->x_picture_decoded.linesize[2]; + } + + pdp_packet_pass_if_valid(x->x_pdp_out, &x->x_packet0); + + // update streaming status + outlet_float( x->x_outlet_streaming, x->x_streaming ); + x->x_nbframes++; + x->x_secondcount++; + outlet_float( x->x_outlet_nbframes, x->x_nbframes ); + + x->x_newpicture = 0; + } + + return (w+5); +} + +static void pdp_live_dsp(t_pdp_live *x, t_signal **sp) +{ + dsp_add(pdp_live_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, sp[0]->s_n); +} + +static void pdp_live_free(t_pdp_live *x) +{ + int i; + + if ( x->x_streaming ) + { + pdp_live_disconnect(x); + sleep(3); + } + post( "pdp_live~ : freeing object" ); + pdp_packet_mark_unused(x->x_packet0); + if (x->x_audio_resample_ctx) + { + audio_resample_close(x->x_audio_resample_ctx); + x->x_audio_resample_ctx = NULL; + } + av_free_static(); +} + +t_class *pdp_live_class; + +void *pdp_live_new(void) +{ + int i; + + t_pdp_live *x = (t_pdp_live *)pd_new(pdp_live_class); + + x->x_pdp_out = outlet_new(&x->x_obj, &s_anything); + + x->x_outlet_left = outlet_new(&x->x_obj, &s_signal); + x->x_outlet_right = outlet_new(&x->x_obj, &s_signal); + + x->x_outlet_streaming = outlet_new(&x->x_obj, &s_float); + x->x_outlet_nbframes = outlet_new(&x->x_obj, &s_float); + + x->x_packet0 = -1; + x->x_connectchild = 0; + x->x_decodechild = 0; + x->x_usethread = 1; + x->x_priority = DEFAULT_PRIORITY; + x->x_nbframes = 0; + x->x_framerate = DEFAULT_FRAME_RATE; + x->x_samplerate = 0; + x->x_audiochannels = 0; + x->x_cursec = 0; + x->x_secondcount = 0; + x->x_audio_resample_ctx = NULL; + x->x_nbvideostreams = 0; + x->x_audioin_position = 0; + x->x_newpicture = 0; + + x->x_avcontext = av_mallocz(sizeof(AVFormatContext)); + if ( !x->x_avcontext ) + { + post( "pdp_live~ : severe error : could not allocate video structures." ); + return NULL; + } + + // activate codecs + av_register_all(); + + memset( &x->x_audio_buf[0], 0x0, 4*MAX_AUDIO_PACKET_SIZE*sizeof(short) ); + memset( &x->x_audio_in[0], 0x0, 4*MAX_AUDIO_PACKET_SIZE*sizeof(short) ); + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_live_tilde_setup(void) +{ + post( pdp_live_version ); + pdp_live_class = class_new(gensym("pdp_live~"), (t_newmethod)pdp_live_new, + (t_method)pdp_live_free, sizeof(t_pdp_live), 0, A_NULL); + + class_addmethod(pdp_live_class, (t_method)pdp_live_dsp, gensym("dsp"), 0); + class_addmethod(pdp_live_class, (t_method)pdp_live_connect, gensym("connect"), A_SYMBOL, A_NULL); + class_addmethod(pdp_live_class, (t_method)pdp_live_disconnect, gensym("disconnect"), A_NULL); + class_addmethod(pdp_live_class, (t_method)pdp_live_priority, gensym("priority"), A_FLOAT, A_NULL); + class_addmethod(pdp_live_class, (t_method)pdp_live_audio, gensym("audio"), A_FLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_lumafilt.c b/modules/pdp_lumafilt.c new file mode 100644 index 0000000..62f1a87 --- /dev/null +++ b/modules/pdp_lumafilt.c @@ -0,0 +1,255 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This effect filters some levels of luminosity + * Useful to isolate some objects + * Written by Yves Degoyon + */ + + + +#include "pdp.h" +#include <math.h> + +#define MAX_LUMA 256 + +static char *pdp_lumafilt_version = "pdp_lumafilt: version 0.1, written by Yves Degoyon (ydegoyon@free.fr)"; + +typedef struct pdp_lumafilt_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + t_int x_filter[MAX_LUMA]; // transform number + +} t_pdp_lumafilt; + +static void pdp_lumafilt_free_ressources(t_pdp_lumafilt *x) +{ + // nothing +} + +static void pdp_lumafilt_allocate(t_pdp_lumafilt *x) +{ + // nothing +} + +static void pdp_lumafilt_filter(t_pdp_lumafilt *x, t_floatarg fluma, t_floatarg fonoff ) +{ + if ( ( (int)fluma >= 0 ) && ( (int)fluma < MAX_LUMA ) ) + { + if ( ((int)fonoff == 0 ) || ((int)fonoff == 1 ) ) + { + x->x_filter[ (int)fluma ] = (int)fonoff; + } + } +} + +static void pdp_lumafilt_mfilter(t_pdp_lumafilt *x, t_floatarg flumas, t_floatarg flumae, t_floatarg fonoff ) +{ + t_int li; + + if ( ( (int)flumas >= 0 ) && ( (int)flumas < MAX_LUMA ) && + ( (int)flumae >= 0 ) && ( (int)flumae < MAX_LUMA ) && + ( flumas < flumae ) ) + { + if ( ((int)fonoff == 0 ) || ((int)fonoff == 1 ) ) + { + for ( li=(int)flumas; li<=(int)flumae; li++ ) + { + x->x_filter[ li ] = (int)fonoff; + } + } + } +} + +static void pdp_lumafilt_process_yv12(t_pdp_lumafilt *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + t_int px, py, luma; + short int *pnY, *pnU, *pnV; + + /* allocate all ressources */ + if ( (int)(header->info.image.width*header->info.image.height) != x->x_vsize ) + { + pdp_lumafilt_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_lumafilt_allocate(x); + post( "pdp_lumafilt : reallocated buffers" ); + } + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + pnY = newdata; + pnV = newdata+x->x_vsize; + pnU = newdata+x->x_vsize+(x->x_vsize>>2); + + memcpy( newdata, data, (x->x_vsize + (x->x_vsize>>1))<<1 ); + + for (py = 0; py < x->x_vheight; py++) { + for (px = 0; px < x->x_vwidth; px++) { + luma = (*(pnY)>>7); + if ( ( luma >0 ) && ( luma < MAX_LUMA ) ) // paranoid + { + if ( x->x_filter[luma] ) + { + *(pnY) = 0; + *(pnU) = 0; + *(pnV) = 0; + } + } + else + { + post( "pdp_lumafilt : luminosity value out of bounds : %d", luma ); + } + pnY++; + if ( (px%2==0) && (py%2==0) ) + { + *pnU++; *pnV++; + } + } + } + + return; +} + +static void pdp_lumafilt_sendpacket(t_pdp_lumafilt *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_lumafilt_process(t_pdp_lumafilt *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_lumafilt_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_lumafilt_process_yv12, pdp_lumafilt_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_lumafilt_process */ + break; + + } + } +} + +static void pdp_lumafilt_input_0(t_pdp_lumafilt *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_lumafilt_process(x); + } +} + +static void pdp_lumafilt_free(t_pdp_lumafilt *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); + pdp_lumafilt_free_ressources(x); +} + +t_class *pdp_lumafilt_class; + +void *pdp_lumafilt_new(void) +{ + int fi; + + t_pdp_lumafilt *x = (t_pdp_lumafilt *)pd_new(pdp_lumafilt_class); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + for ( fi=0; fi<MAX_LUMA; fi++ ) + { + x->x_filter[fi] = 0; + } + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_lumafilt_setup(void) +{ +// post( pdp_lumafilt_version ); + pdp_lumafilt_class = class_new(gensym("pdp_lumafilt"), (t_newmethod)pdp_lumafilt_new, + (t_method)pdp_lumafilt_free, sizeof(t_pdp_lumafilt), 0, A_NULL); + + class_addmethod(pdp_lumafilt_class, (t_method)pdp_lumafilt_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_lumafilt_class, (t_method)pdp_lumafilt_filter, gensym("filter"), A_DEFFLOAT, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_lumafilt_class, (t_method)pdp_lumafilt_mfilter, gensym("mfilter"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_mgrid.c b/modules/pdp_mgrid.c new file mode 100644 index 0000000..3f3939c --- /dev/null +++ b/modules/pdp_mgrid.c @@ -0,0 +1,336 @@ +/* + * PiDiP module + * Copyright (c) by Yves Degoyon ( ydegoyon@free.fr ) + * + * 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. + * + */ + +/* This object is a motion detection grid + */ + +#include "pdp.h" +#include <math.h> + +#define DEFAULT_X_DIM 10 +#define DEFAULT_Y_DIM 10 +#define DEFAULT_THRESHOLD 20 +#define DEFAULT_COLOR 128 + +static char *pdp_mgrid_version = "pdp_mgrid: a motion detection grid version 0.1 written by Yves Degoyon (ydegoyon@free.fr)"; + +typedef struct pdp_mgrid_struct +{ + t_object x_obj; + t_float x_f; + + t_int x_packet0; + t_int x_dropped; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + short int *x_previous_frame; + t_int x_xdim; + t_int x_ydim; + t_int x_threshold; + short int x_color; + t_int x_firstimage; + + t_outlet *x_pdp_output; // output packets + t_outlet *x_xmotion; // output x coordinate of block which has been detected + t_outlet *x_ymotion; // output y coordinate of block which has been detected + + +} t_pdp_mgrid; + +static void pdp_mgrid_free_ressources(t_pdp_mgrid *x) +{ + if ( x->x_previous_frame ) freebytes ( x->x_previous_frame, ( x->x_vsize + ( x->x_vsize>>1 ) ) << 1 ); +} + +static void pdp_mgrid_allocate(t_pdp_mgrid *x) +{ + x->x_previous_frame = (short int *) getbytes ( ( x->x_vsize + ( x->x_vsize>>1 ) ) << 1 ); + + if ( !x->x_previous_frame ) + { + post( "pdp_mgrid : severe error : cannot allocate buffer !!! "); + return; + } +} + +static void pdp_mgrid_x_dim(t_pdp_mgrid *x, t_floatarg fxdim ) +{ + if ( x->x_previous_frame == NULL ) + { + post( "pdp_mgrid : tried to set grid dimension but image dimensions are unknown" ); + return; + } + if ( ( fxdim >= 0 ) && ( fxdim < (x->x_vwidth/3) ) ) + { + x->x_xdim = (int)fxdim; + } +} + +static void pdp_mgrid_y_dim(t_pdp_mgrid *x, t_floatarg fydim ) +{ + if ( x->x_previous_frame == NULL ) + { + post( "pdp_mgrid : tried to set grid dimension but image dimensions are unknown" ); + return; + } + + if ( ( fydim >= 0 ) && ( fydim < (x->x_vheight/3) ) ) + { + x->x_ydim = (int)fydim; + } +} + +static void pdp_mgrid_threshold(t_pdp_mgrid *x, t_floatarg fthreshold ) +{ + if ( fthreshold > 0 ) + { + x->x_threshold = (int)fthreshold; + } +} + +static void pdp_mgrid_color(t_pdp_mgrid *x, t_floatarg fcolor ) +{ + if ( ( fcolor >= 0 ) && ( fcolor < 255 ) ) + { + x->x_color = (int)fcolor; + } +} + +static void pdp_mgrid_process_yv12(t_pdp_mgrid *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_int i, cf; + t_int px=0, py=0, xcell=0, ycell=0; + t_int celldiff=0, cellwidth=0, cellheight=0; + t_int yindex=0, uindex=0, vindex=0; + + /* allocate all ressources */ + if ( ( (int)header->info.image.width != x->x_vwidth ) || + ( (int)header->info.image.height != x->x_vheight ) ) + { + pdp_mgrid_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_mgrid_allocate(x); + x->x_firstimage = 1; + post( "pdp_mgrid : reallocated buffers" ); + } + + // draw horizontal lines + if ( x->x_ydim > 0 ) + { + for(py=0; py<x->x_vheight; py+=(x->x_vheight/x->x_ydim)) + { + if ( py >= x->x_vheight ) break; + for(px=0; px<x->x_vwidth; px++) + { + data[py*x->x_vwidth+px] = + ( ( data[py*x->x_vwidth+px] >> 7 ) ^ x->x_color) << 7; + } + } + } + + // draw vertical lines + if ( x->x_xdim > 0 ) + { + for(px=0; px<x->x_vwidth; px+=(x->x_vwidth/x->x_xdim)) + { + if ( px >= x->x_vwidth ) break; + for(py=0; py<x->x_vheight; py++) + { + data[py*x->x_vwidth+px] = + ( ( data[py*x->x_vwidth+px] >> 7 ) ^ x->x_color) << 7; + } + } + } + + if ( !x->x_firstimage ) + { + // detect cell where a movement occurred + ycell=0; + celldiff=0; + if ( x->x_xdim > 0 ) + { + cellwidth=(x->x_vwidth/x->x_xdim); + } + else + { + cellwidth=x->x_vwidth; + } + if ( x->x_ydim > 0 ) + { + cellheight=(x->x_vheight/x->x_ydim); + } + else + { + cellheight=x->x_vheight; + } + for(xcell=0; xcell<x->x_xdim; xcell++) + { + for(ycell=0; ycell<x->x_ydim; ycell++) + { + celldiff=0; + for ( px=xcell*cellwidth; px<(xcell+1)*cellwidth; px++ ) + { + if ( px >= x->x_vwidth ) break; + for ( py=ycell*cellheight; py<(ycell+1)*cellheight; py++ ) + { + if ( py >= x->x_vheight ) break; + yindex = py*x->x_vwidth+px; + uindex = x->x_vsize + ((py*x->x_vwidth>>2)+(px>>1)); + vindex = x->x_vsize + (x->x_vsize>>2) + ((py*x->x_vwidth>>2)+(px>>1)); + + // this calculation although more accurate is heavy + // celldiff += sqrt( pow(((data[ yindex ]>>7) - (x->x_previous_frame[ yindex ]>>7)), 2) + // + pow(((data[ uindex ]>>8) - (x->x_previous_frame[ uindex ]>>8)), 2) + // + pow(((data[ vindex ]>>8) - (x->x_previous_frame[ vindex ]>>8)), 2)); + celldiff += abs(((data[ yindex ]>>7) - (x->x_previous_frame[ yindex ]>>7))) + + abs(((data[ uindex ]>>8) - (x->x_previous_frame[ uindex ]>>8))) + + abs(((data[ vindex ]>>8) - (x->x_previous_frame[ vindex ]>>8))); + } + } + if ( celldiff > x->x_threshold*cellwidth*cellheight ) + { + outlet_float(x->x_xmotion, xcell+1); + outlet_float(x->x_ymotion, ycell+1); + } + // post( "pdp_mgrid : cell [%d,%d] diff=%d", xcell, ycell, celldiff ); + } + } + } + else + { + x->x_firstimage = 0; + } + + memcpy(x->x_previous_frame, data, (x->x_vsize + (x->x_vsize>>1))<<1 ); + + pdp_packet_pass_if_valid(x->x_pdp_output, &x->x_packet0); + + return; +} + +static void pdp_mgrid_process(t_pdp_mgrid *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_mgrid_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + pdp_mgrid_process_yv12(x); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_mgrid_process */ + break; + + } + } +} + +static void pdp_mgrid_input_0(t_pdp_mgrid *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + pdp_mgrid_process(x); + + } +} + +static void pdp_mgrid_free(t_pdp_mgrid *x) +{ + int i; + + pdp_packet_mark_unused(x->x_packet0); + pdp_mgrid_free_ressources(x); +} + +t_class *pdp_mgrid_class; + +void *pdp_mgrid_new(void) +{ + int i; + + t_pdp_mgrid *x = (t_pdp_mgrid *)pd_new(pdp_mgrid_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("threshold")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("dimx")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("dimy")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("color")); + + x->x_pdp_output = outlet_new(&x->x_obj, &s_anything); + x->x_xmotion = outlet_new(&x->x_obj, &s_float); + x->x_ymotion = outlet_new(&x->x_obj, &s_float); + + x->x_packet0 = -1; + + x->x_previous_frame = NULL; + x->x_xdim = DEFAULT_X_DIM; + x->x_ydim = DEFAULT_Y_DIM; + x->x_threshold = DEFAULT_THRESHOLD; + x->x_color = DEFAULT_COLOR; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_mgrid_setup(void) +{ + post( pdp_mgrid_version ); + pdp_mgrid_class = class_new(gensym("pdp_mgrid"), (t_newmethod)pdp_mgrid_new, + (t_method)pdp_mgrid_free, sizeof(t_pdp_mgrid), 0, A_NULL); + + class_addmethod(pdp_mgrid_class, (t_method)pdp_mgrid_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_mgrid_class, (t_method)pdp_mgrid_threshold, gensym("threshold"), A_FLOAT, A_NULL); + class_addmethod(pdp_mgrid_class, (t_method)pdp_mgrid_x_dim, gensym("dimx"), A_FLOAT, A_NULL); + class_addmethod(pdp_mgrid_class, (t_method)pdp_mgrid_y_dim, gensym("dimy"), A_FLOAT, A_NULL); + class_addmethod(pdp_mgrid_class, (t_method)pdp_mgrid_color, gensym("color"), A_FLOAT, A_NULL); + + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_mosaic.c b/modules/pdp_mosaic.c new file mode 100644 index 0000000..1fb3487 --- /dev/null +++ b/modules/pdp_mosaic.c @@ -0,0 +1,312 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is an adaptation of mosaic effect from effectv + * Originally written by Fukuchi Kentaro & others + * Pd-fication by Yves Degoyon + */ + + + +#include "pdp.h" +#include <math.h> + +#define MAGIC_THRESHOLD 30 +#define CENSOR_LEVEL 20 + +static char *pdp_mosaic_version = "pdp_mosaic: version 0.1, port of mosaic from effectv( Fukuchi Kentaro ) adapted by Yves Degoyon (ydegoyon@free.fr)"; + +typedef struct pdp_mosaic_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + t_int x_censor_level; + t_int x_ssize; + short int *x_diff; + short int *x_bdata; + t_int x_snapshot; + +} t_pdp_mosaic; + + +static void pdp_mosaic_ssize(t_pdp_mosaic *x, t_floatarg fssize ) +{ + if ( ( fssize > 1 ) && ( fssize < x->x_vwidth ) ) + { + x->x_ssize = (int)fssize; + } +} + +static void pdp_mosaic_level(t_pdp_mosaic *x, t_floatarg flevel ) +{ + if ( flevel > 0 ) + { + x->x_censor_level = (int)flevel; + } +} + +static void pdp_mosaic_background(t_pdp_mosaic *x ) +{ + x->x_snapshot = 1; +} + +static void pdp_mosaic_free_ressources(t_pdp_mosaic *x) +{ + if ( x->x_diff != NULL ) freebytes( x->x_diff, (x->x_vsize + (x->x_vsize>>1))<<1 ); + if ( x->x_bdata != NULL ) freebytes( x->x_bdata, (( x->x_vsize + (x->x_vsize>>1))<<1)); +} + +static void pdp_mosaic_allocate(t_pdp_mosaic *x) +{ + int i; + + x->x_diff = (short int*) getbytes((x->x_vsize + (x->x_vsize>>1))<<1); + x->x_bdata = (short int *) getbytes((( x->x_vsize + (x->x_vsize>>1))<<1)); + if( !x->x_bdata || ! x->x_diff ) { + post( "pdp_mosaic : severe error : cannot allocate buffers" ); + } + +} + +/* check if there is a real difference with background image */ +static void pdp_mosaic_diff(t_pdp_mosaic *x, short int *src) +{ + int i; + int Yy=0, Yu=0, Yv=0; + int Yby=0, Ybu=0, Ybv=0; + short int *p=NULL; + short int *pb=NULL; + short int *r=NULL; + int v; + + p = src; + pb = x->x_bdata; + r = x->x_diff; + for(i=0; i<(x->x_vsize); i++) + { + Yy = (*p); + Yu = (*(p+x->x_vsize+(i>>2))); + if ( x->x_vsize+(x->x_vsize>>2)+(i>>2) > x->x_vsize+(x->x_vsize>>1) ) + { + post ("pdp_mosaic : overflow : offset=%d limit=%d", x->x_vsize+(x->x_vsize>>2)+(i>>2), + x->x_vsize+(x->x_vsize>>1) ); + return; + } + Yv = (*(p+x->x_vsize+(x->x_vsize>>2)+(i>>2))); + Yby = (*pb); + Ybu = (*(pb+x->x_vsize+(i>>2))); + Ybv = (*(pb+x->x_vsize+(x->x_vsize>>2)+(i>>2))); + if ( !r ) { post( "pdp_mosaic : hey, buffers are not allocated !!" ); return; }; + *r = ( (Yy - Yby) + (Yu - Ybu) + (Yv - Ybv) ); + r++; + } + +} + +static void pdp_mosaic_process_yv12(t_pdp_mosaic *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + int i; + + int px=0, py=0, xx, yy, y, u, v; + int count; + + /* allocate all ressources */ + if ( (int)(header->info.image.width*header->info.image.height) != x->x_vsize ) + { + pdp_mosaic_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_mosaic_allocate(x); + post( "pdp_mosaic : reallocated buffers" ); + } + + if ( x->x_bdata && x->x_snapshot ) + { + x->x_snapshot = 0; + memcpy( x->x_bdata, data, (x->x_vsize + (x->x_vsize>>1))<<1 ); + } + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + pdp_mosaic_diff(x, data); + + memcpy( newdata, data, (x->x_vsize + (x->x_vsize>>1))<<1 ); + + for(py=0; py<(x->x_vheight-x->x_ssize-1); py+=x->x_ssize) + { + for(px=0; px<(x->x_vwidth-x->x_ssize-1); px+=x->x_ssize) + { + count = 0; + for(yy=0; yy<x->x_ssize; yy++) + { + for(xx=0; xx<x->x_ssize; xx++) + { + count += *(x->x_diff + (py+yy)*x->x_vwidth + (px+xx) ); + count += *(x->x_diff + x->x_vsize + (((py+yy)*x->x_vwidth)>>2) + ((px+xx)>>1) ); + count += *(x->x_diff + x->x_vsize + (x->x_vsize>>2) + (((py+yy)*x->x_vwidth)>>2) + ((px+xx)>>1) ); + } + } + if(count > x->x_censor_level) + { + // post( "pdp_mosaic : censored" ); + y = *(data + (py+3)*x->x_vwidth + (px+3)); + u = *(data + x->x_vsize + (((py+3)*x->x_vwidth)>>2) + ((px+3)>>1) ); + v = *(data + x->x_vsize + (((py+3)*x->x_vwidth)>>2) + ((px+3)>>1) ); + for(yy=0; yy<x->x_ssize; yy++) + { + for(xx=0; xx<x->x_ssize; xx++) + { + *(newdata + (py+yy)*x->x_vwidth + (px+xx)) = y; + *(newdata + x->x_vsize + (((py+yy)*x->x_vwidth)>>2) + ((px+xx)>>1) ) = u; + *(newdata + x->x_vsize + (x->x_vsize>>2) + (((py+yy)*x->x_vwidth)>>2) + ((px+xx)>>1) ) = v; + } + } + } + } + } + + return; +} + +static void pdp_mosaic_sendpacket(t_pdp_mosaic *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + + +static void pdp_mosaic_process(t_pdp_mosaic *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_mosaic_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_mosaic_process_yv12, pdp_mosaic_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + break; + + default: + /* don't know the type, so dont pdp_mosaic_process */ + break; + + } + } +} + +static void pdp_mosaic_input_0(t_pdp_mosaic *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_mosaic_process(x); + } +} + +static void pdp_mosaic_free(t_pdp_mosaic *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); + pdp_mosaic_free_ressources(x); +} + +t_class *pdp_mosaic_class; + +void *pdp_mosaic_new(void) +{ + int i; + + t_pdp_mosaic *x = (t_pdp_mosaic *)pd_new(pdp_mosaic_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_bang, gensym("background")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("level")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_vsize = -1; + x->x_snapshot = 1; + x->x_ssize = 8; // square size + x->x_censor_level = CENSOR_LEVEL; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_mosaic_setup(void) +{ +// post( pdp_mosaic_version ); + pdp_mosaic_class = class_new(gensym("pdp_mosaic"), (t_newmethod)pdp_mosaic_new, + (t_method)pdp_mosaic_free, sizeof(t_pdp_mosaic), 0, A_NULL); + + class_addmethod(pdp_mosaic_class, (t_method)pdp_mosaic_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_mosaic_class, (t_method)pdp_mosaic_background, gensym("background"), A_NULL); + class_addmethod(pdp_mosaic_class, (t_method)pdp_mosaic_level, gensym("level"), A_FLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_nervous.c b/modules/pdp_nervous.c new file mode 100644 index 0000000..df76821 --- /dev/null +++ b/modules/pdp_nervous.c @@ -0,0 +1,283 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is an adaptation of warp effect from effectv + * Copyright (C) 2002 TANNENBAUM Edo + * Pd-fication by Yves Degoyon + */ + + + +#include "pdp.h" +#include <math.h> + +#define DEFAULT_PLANES 32 + +static int fastrand_val=0; +#define inline_fastrand() (fastrand_val=fastrand_val*1103515245+12345) + + +static char *pdp_nervous_version = "pdp_nervous: version 0.1, port of nervous from effectv( Fukuchi Kentaro ) adapted by Yves Degoyon (ydegoyon@free.fr)"; + +static char* the_wave_table = NULL; + +typedef struct pdp_nervous_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + t_int x_mode; + short int *x_buffer; + short int **x_planetable; + t_int x_planes; + t_int x_plane; + t_int x_stock; + t_int x_timer; + t_int x_stride; + t_int x_readplane; + +} t_pdp_nervous; + +static void pdp_nervous_mode(t_pdp_nervous *x, t_floatarg fmode ) +{ + if ( ( fmode == 0 ) || ( fmode == 1 ) ) + { + x->x_mode = (int)fmode; + } +} + +static void pdp_nervous_free_ressources(t_pdp_nervous *x) +{ + if ( x->x_buffer ) free ( x->x_buffer ); + if ( x->x_planetable ) free ( x->x_planetable ); +} + +static void pdp_nervous_allocate(t_pdp_nervous *x) +{ + int i; + + // allocate space for the frame buffers. A lot of memory is required - + // with the default settings, it totals nearly 5 megs. + x->x_buffer = (short int *) getbytes ( ( ( x->x_vsize + ( x->x_vsize>>1 ) ) << 1 ) * 2 * x->x_planes); + x->x_planetable = (short int**) getbytes ( x->x_planes*sizeof(short int*) ); + + // set up the array of pointers to the frame buffers + for(i=0;i<x->x_planes;i++) + { + x->x_planetable[i] = &x->x_buffer[ ( ( x->x_vsize + ( x->x_vsize>>1 ) ) << 1 ) * i]; + } + + if ( !x->x_buffer ) + { + post( "pdp_nervous : severe error : cannot allocate buffers !!! "); + return; + } +} + +static void pdp_nervous_planes(t_pdp_nervous *x, t_floatarg fplanes ) +{ + if ( ( fplanes > 1 ) && ( fplanes < 100 ) ) + { + pdp_nervous_free_ressources(x); + x->x_planes = (int)fplanes; + x->x_plane = x->x_planes-1; + x->x_readplane = 0; + x->x_stock = 0; + pdp_nervous_allocate(x); + } +} + +static void pdp_nervous_process_yv12(t_pdp_nervous *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + int i; + + /* allocate all ressources */ + if ( (int)(header->info.image.width*header->info.image.height) != x->x_vsize ) + { + pdp_nervous_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + x->x_plane = x->x_planes-1; + pdp_nervous_allocate(x); + post( "pdp_nervous : reallocated buffers" ); + } + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + memcpy(x->x_planetable[x->x_plane], data, ( x->x_vsize + (x->x_vsize>>1) ) << 1 ); + if(x->x_stock < x->x_planes) { + x->x_stock++; + } + + if(x->x_mode) + { + if(x->x_timer) + { + x->x_readplane = x->x_readplane + x->x_stride; + while(x->x_readplane < 0) x->x_readplane += x->x_stock; + while(x->x_readplane >= x->x_stock) x->x_readplane -= x->x_stock; + x->x_timer--; + } + else + { + x->x_readplane = inline_fastrand() % x->x_stock; + if ( x->x_readplane < 0 ) x->x_readplane = 0; + x->x_stride = inline_fastrand() % 5 - 2; + if(x->x_stride >= 0) x->x_stride++; + x->x_timer = inline_fastrand() % 6 + 2; + } + } + else + { + if(x->x_stock > 0) x->x_readplane = ( inline_fastrand() % x->x_stock ); + if ( x->x_readplane < 0 ) x->x_readplane = 0; + } + memcpy(newdata, x->x_planetable[x->x_readplane], ( x->x_vsize + ( x->x_vsize>>1) ) << 1 ); + x->x_plane = ( x->x_plane + 1 ) % x->x_planes; + + return; +} + +static void pdp_nervous_sendpacket(t_pdp_nervous *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_nervous_process(t_pdp_nervous *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_nervous_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_nervous_process_yv12, pdp_nervous_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_nervous_process */ + break; + + } + } +} + +static void pdp_nervous_input_0(t_pdp_nervous *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_nervous_process(x); + } +} + +static void pdp_nervous_free(t_pdp_nervous *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); + pdp_nervous_free_ressources(x); +} + +t_class *pdp_nervous_class; + +void *pdp_nervous_new(void) +{ + int i; + + t_pdp_nervous *x = (t_pdp_nervous *)pd_new(pdp_nervous_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("planes")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("mode")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_mode = 0; + x->x_buffer = NULL; + x->x_planes = DEFAULT_PLANES; + x->x_readplane = 0; + x->x_stock = 0; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_nervous_setup(void) +{ +// post( pdp_nervous_version ); + pdp_nervous_class = class_new(gensym("pdp_nervous"), (t_newmethod)pdp_nervous_new, + (t_method)pdp_nervous_free, sizeof(t_pdp_nervous), 0, A_NULL); + + class_addmethod(pdp_nervous_class, (t_method)pdp_nervous_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_nervous_class, (t_method)pdp_nervous_mode, gensym("mode"), A_FLOAT, A_NULL); + class_addmethod(pdp_nervous_class, (t_method)pdp_nervous_planes, gensym("planes"), A_FLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_noquark.c b/modules/pdp_noquark.c new file mode 100644 index 0000000..399b11f --- /dev/null +++ b/modules/pdp_noquark.c @@ -0,0 +1,279 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is an adaptation of warp effect from effectv + * Originally written by Fukuchi Kentaro & others + * Pd-fication by Yves Degoyon + */ + + + +#include "pdp.h" +#include <math.h> + +#define DEFAULT_PLANES 16 +#define DEFAULT_TOLERANCE 5 + +static int fastrand_val=0; +#define inline_fastrand() (fastrand_val=fastrand_val*1103515245+12345) + + +static char *pdp_noquark_version = "pdp_noquark: version 0.1, port of quark from effectv( Fukuchi Kentaro ) adapted by Yves Degoyon (ydegoyon@free.fr)"; + +static char* the_wave_table = NULL; + +typedef struct pdp_noquark_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + short int *x_buffer; + short int **x_planetable; + t_int x_plane; + t_int x_planes; + t_int x_tolerance; + +} t_pdp_noquark; + +static void pdp_noquark_free_ressources(t_pdp_noquark *x) +{ + if ( x->x_buffer ) free ( x->x_buffer ); + if ( x->x_planetable ) free ( x->x_planetable ); +} + +static void pdp_noquark_allocate(t_pdp_noquark *x) +{ + int i; + + // allocate space for the frame buffers. A lot of memory is required - + // with the default settings, it totals nearly 5 megs. + x->x_buffer = (short int *) getbytes ( ( ( x->x_vsize + ( x->x_vsize>>1 ) ) << 1 ) * 2 * x->x_planes); + x->x_planetable = (short int**) getbytes( x->x_planes*sizeof( short int* ) ); + + // set up the array of pointers to the frame buffers + for(i=0;i<x->x_planes;i++) + { + x->x_planetable[i] = &x->x_buffer[ ( ( x->x_vsize + ( x->x_vsize>>1 ) ) << 1 ) * i]; + } + + if ( !x->x_buffer ) + { + post( "pdp_noquark : severe error : cannot allocate buffers !!! "); + return; + } +} + +static void pdp_noquark_planes(t_pdp_noquark *x, t_floatarg fplanes) +{ + if ( ( (int)fplanes > 1 ) && ( (int)fplanes < 100 ) ) + { + pdp_noquark_free_ressources(x); + x->x_planes = (int) fplanes; + x->x_plane=x->x_planes-1; + pdp_noquark_allocate(x); + } +} + +static void pdp_noquark_tolerance(t_pdp_noquark *x, t_floatarg ftolerance) +{ + if ( (int)ftolerance > 1 ) + { + x->x_tolerance = (int) ftolerance; + } +} + +static void pdp_noquark_process_yv12(t_pdp_noquark *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + t_int px, py, cf, diff, rx, ry; + + /* allocate all ressources */ + if ( (int)(header->info.image.width*header->info.image.height) != x->x_vsize ) + { + pdp_noquark_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + x->x_plane = x->x_planes-1; + pdp_noquark_allocate(x); + post( "pdp_noquark : reallocated buffers" ); + } + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + memcpy(x->x_planetable[x->x_plane], data, (x->x_vsize + (x->x_vsize>>1))<<1 ); + for(py=0; py<x->x_vheight; py++) + { + for(px=0; px<x->x_vwidth; px++) + { + cf = (x->x_plane + (inline_fastrand()>>24))&(x->x_planes-1); + diff = (((x->x_planetable[cf])[py*x->x_vwidth+px] - data[py*x->x_vwidth+px])>>7) + + ((((x->x_planetable[cf])[x->x_vsize+((py>>1)*(x->x_vwidth>>1)+(px>>1))] - + data[x->x_vsize+((py>>1)*(x->x_vwidth>>1)+(px>>1))] )>>8)) + + ((((x->x_planetable[cf])[x->x_vsize+(x->x_vsize>>2)+((py>>1)*(x->x_vwidth>>1)+(px>>1))] - + data[x->x_vsize+(x->x_vsize>>2)+((py>>1)*(x->x_vwidth>>1)+(px>>1))] )>>8)); + if ( abs ( diff ) > x->x_tolerance ) + { + newdata[py*x->x_vwidth+px] = data[py*x->x_vwidth+px]; + newdata[x->x_vsize+((py>>1)*(x->x_vwidth>>1)+(px>>1))] = data[x->x_vsize+((py>>1)*(x->x_vwidth>>1)+(px>>1))]; + newdata[x->x_vsize+(x->x_vsize>>2)+((py>>1)*(x->x_vwidth>>1)+(px>>1))] = + data[x->x_vsize+(x->x_vsize>>2)+((py>>1)*(x->x_vwidth>>1)+(px>>1))]; + } + else + { + rx = inline_fastrand()&x->x_vwidth; + ry = inline_fastrand()&x->x_vheight; + newdata[py*x->x_vwidth+px] = data[ry*x->x_vwidth+rx]; + newdata[x->x_vsize+((py>>1)*(x->x_vwidth>>1)+(px>>1))] = + data[x->x_vsize+((ry>>1)*(x->x_vwidth>>1)+(rx>>1))]; + newdata[x->x_vsize+(x->x_vsize>>2)+((py>>1)*(x->x_vwidth>>1)+(px>>1))] = + data[x->x_vsize+(x->x_vsize>>2)+((ry>>1)*(x->x_vwidth>>1)+(rx>>1))]; + } + /* The reason why I use high order 8 bits is written in utils.c + (or, 'man rand') */ + } + } + x->x_plane--; + if ( x->x_plane < 0 ) x->x_plane = x->x_planes-1; + + return; +} + +static void pdp_noquark_sendpacket(t_pdp_noquark *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_noquark_process(t_pdp_noquark *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_noquark_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_noquark_process_yv12, pdp_noquark_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_noquark_process */ + break; + + } + } +} + +static void pdp_noquark_input_0(t_pdp_noquark *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_noquark_process(x); + } +} + +static void pdp_noquark_free(t_pdp_noquark *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); + pdp_noquark_free_ressources(x); +} + +t_class *pdp_noquark_class; + +void *pdp_noquark_new(void) +{ + int i; + + t_pdp_noquark *x = (t_pdp_noquark *)pd_new(pdp_noquark_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("planes")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("tolerance")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + x->x_planes = DEFAULT_PLANES; + x->x_tolerance = DEFAULT_TOLERANCE; + + x->x_buffer = NULL; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_noquark_setup(void) +{ +// post( pdp_noquark_version ); + pdp_noquark_class = class_new(gensym("pdp_noquark"), (t_newmethod)pdp_noquark_new, + (t_method)pdp_noquark_free, sizeof(t_pdp_noquark), 0, A_NULL); + + class_addmethod(pdp_noquark_class, (t_method)pdp_noquark_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_noquark_class, (t_method)pdp_noquark_planes, gensym("planes"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_noquark_class, (t_method)pdp_noquark_tolerance, gensym("tolerance"), A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_o.c b/modules/pdp_o.c new file mode 100644 index 0000000..34b2b18 --- /dev/null +++ b/modules/pdp_o.c @@ -0,0 +1,589 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon <ydegoyon@free.fr> + * + * 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. + * + */ + +/* This object is a video streaming emitter + * -- compressed with a very simple codec ( smoothing + huffman + bz2 ) + * It sends PDP packet to a pdp_i receiving object + */ + + +#include "pdp.h" +#include "pdp_streaming.h" +#include <math.h> +#include <time.h> +#include <unistd.h> +#include <sys/time.h> +#include <netinet/in.h> +#include <netdb.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <quicktime/quicktime.h> +#include <quicktime/colormodels.h> +#include <bzlib.h> // bz2 compression routines + +#define DEFAULT_FRAME_RATE 25 + +static char *pdp_o_version = "pdp_o: version 0.1, a video stream emitter, written by ydegoyon@free.fr"; + +typedef struct pdp_o_struct +{ + t_object x_obj; + t_float x_f; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + t_int x_hsize; // size of huffman coded data + + t_int x_packet0; + t_int x_dropped; + t_int x_queue_id; + + t_int x_emitflag; + + /* connection data */ + int x_fd; // info about connection status + t_int x_framessent; + t_int x_framesdropped; + t_int x_secondcount; + t_int x_bandwidthcount; + t_int x_cursec; + t_int x_framerate; + t_int x_smoothing; + + t_hpacket x_hpacket; // packet header + + short int *x_previous_frame; + char *x_diff_frame; + char *x_hdata; // huffman coded data + char *x_cdata; // compressed data to be sent + + t_outlet *x_connection_status; // indicates status + t_outlet *x_frames; // outlet for the number of frames emitted + t_outlet *x_framesd; // outlet for the number of frames dropped + t_outlet *x_bandwidth; // outlet for bandwidth + +} t_pdp_o; + +static void pdp_o_free_ressources(t_pdp_o *x) +{ + if ( x->x_diff_frame ) freebytes( x->x_diff_frame, x->x_vsize + (x->x_vsize>>1) ); + if ( x->x_previous_frame ) freebytes( x->x_previous_frame, (x->x_vsize + (x->x_vsize>>1))<<1 ); + if ( x->x_cdata ) freebytes( x->x_cdata, (x->x_vsize + (x->x_vsize>>1))*1.01+600 ); // size is taken from bzlib manual + if ( x->x_hdata ) freebytes( x->x_hdata, ((x->x_vsize + (x->x_vsize>>1))<<1) ); // size is taken from bzlib manual +} + +static void pdp_o_allocate(t_pdp_o *x) +{ + x->x_diff_frame = (char*) getbytes( x->x_vsize + (x->x_vsize>>1) ); + memset( x->x_diff_frame, 0x00, x->x_vsize + (x->x_vsize>>1) ); + x->x_previous_frame = (short int*) getbytes( (x->x_vsize + (x->x_vsize>>1))<<1 ); + memset( x->x_previous_frame, 0x00, (x->x_vsize + (x->x_vsize>>1))<<1 ); + x->x_cdata = (char*) getbytes( (x->x_vsize + (x->x_vsize>>1))*1.01+600 ); + memset( x->x_cdata, 0x00, (x->x_vsize + (x->x_vsize>>1))*1.01+600 ); + x->x_hdata = (char*) getbytes( (x->x_vsize + (x->x_vsize>>1))<<1 ); + memset( x->x_hdata, 0x00, (x->x_vsize + (x->x_vsize>>1))<<1 ); + strcpy( x->x_hpacket.tag, PDP_PACKET_TAG ); +} + + /* disconnect from receiver */ +static void pdp_o_disconnect(t_pdp_o *x) +{ + int ret; + + if(x->x_fd >= 0) /* close socket */ + { + close(x->x_fd); + x->x_fd = -1; + outlet_float( x->x_connection_status, 0 ); + post("pdp_o : connection closed"); + } + +} + + /* set the emission frame rate */ +static void pdp_o_framerate(t_pdp_o *x, t_floatarg fframerate) +{ + if ( fframerate > 1 ) + { + x->x_framerate = (int)fframerate; + } +} + + /* set the smoothing factor */ +static void pdp_o_smoothing(t_pdp_o *x, t_floatarg fsmoothing) +{ + if ( ( fsmoothing >= 0 ) && ( fsmoothing < 255 ) ) + { + x->x_smoothing = (int)fsmoothing; + } +} + + /* smoothe image */ +static void pdp_o_smoothe(t_pdp_o *x, short int *source, t_int size ) +{ + t_int i; + char evalue, eevalue; + char value; + + if ( x->x_smoothing == 0 ) return; + + for(i=0;i<size;i++) + { + value = (source[i])>>7; + evalue = (value/x->x_smoothing)*x->x_smoothing; + eevalue = ((value/x->x_smoothing)+1)*x->x_smoothing; + + if ( abs( value - evalue ) < x->x_smoothing/2 ) + { + source[i] = evalue<<7; + } + else + { + source[i] = eevalue<<7; + } + } + + for(i=size;i<(size+(size>1));i++) + { + value = ((source[i])>>8)+128; + evalue = (value/x->x_smoothing)*x->x_smoothing; + eevalue = ((value/x->x_smoothing)+1)*x->x_smoothing; + + if ( abs( value - evalue ) < x->x_smoothing/2 ) + { + source[i] = (evalue)<<8; + } + else + { + source[i] = (eevalue)<<8; + } + } +} + + /* huffman coding */ +static int pdp_o_huffman(t_pdp_o *x, char *source, char *dest, t_int size, t_int *csize ) +{ + t_int i; + char value = source[0]; + char count = 0; + t_int tcount=0; + char *pcount=dest; + char *pvalue=dest+1; + + *(csize)=2; + dest++; + for( i=0; i<size; i++) + { + if ( (source[i] == value) && (count<127) ) + { + count++; + } + else + { + value=source[i]; + *(pcount)=count; + *(pvalue) = value; + tcount+=count; + count=1; + pcount+=2; + pvalue+=2; + *(csize)+=2; + } + } + *(pcount)=count; + tcount+=count; + + // huffman is no good for that image + if ( (*csize) >= size ) + { + *csize = size; + memcpy( dest, source, size ); + return REGULAR; + } + else + { + // post( "pdp_o : huffman : compression ratio %d/%d : %f (total count=%d)", size, (*csize), + // (t_float)size/(t_float)(*csize), tcount ); + return HUFFMAN; + } +} + + + /* connect to a receiver on <hostname> <port> */ +static void pdp_o_connect(t_pdp_o *x, t_symbol *shostname, t_floatarg fportno) +{ + struct sockaddr_in csocket; + struct hostent *hp; + int portno = fportno; /* get port from message box */ + + /* variables used for communication with the receiver */ + const char *buf = 0; + unsigned int len; + int sockfd; + int ret; + + // close previous connection if existing + pdp_o_disconnect(x); + + sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd < 0) + { + error("pdp_o : error while attempting to create socket"); + perror( "socket" ); + return; + } + + /* connect socket using hostname provided in command line */ + csocket.sin_family = AF_INET; + hp = gethostbyname(shostname->s_name); + if (hp == 0) + { + post("pdp_o : ip address of receiver could not be found"); + perror( "gethostbyname" ); + close(sockfd); + return; + } + memcpy((char *)&csocket.sin_addr, (char *)hp->h_addr, hp->h_length); + + /* assign client port number */ + csocket.sin_port = htons((unsigned short)fportno); + + /* try to connect. */ + post("pdp_o : connecting to port %d", (int)fportno); + if (connect(sockfd, (struct sockaddr *) &csocket, sizeof (csocket)) < 0) + { + error("mp3streamout~: connection failed!\n"); + perror( "connect" ); + close(sockfd); + return; + } + + x->x_fd = sockfd; + x->x_framessent = 0; + x->x_framesdropped = 0; + outlet_float( x->x_connection_status, 1 ); + post( "pdp_o : connected to receiver : %s:%d", shostname->s_name, (int)fportno ); + +} + + /* refresh means forcing the emission of a full frame */ +static void pdp_o_refresh(t_pdp_o *x) +{ + strcpy( x->x_hpacket.tag, PDP_PACKET_TAG ); + memset( x->x_previous_frame, 0x00, (x->x_vsize + (x->x_vsize>>1))<<1 ); +} + + /* start emitting */ +static void pdp_o_start(t_pdp_o *x) +{ + if ( x->x_emitflag == 1 ) { + post("pdp_o : start received but emission is started ... ignored."); + return; + } + + x->x_emitflag = 1; + post("pdp_o : emission started"); +} + + /* stop emitting */ +static void pdp_o_stop(t_pdp_o *x) +{ + if ( x->x_emitflag == 0 ) { + post("mp3write~: stop received but emission is stopped ... ignored."); + return; + } + + x->x_emitflag = 0; + + post("pdp_o : emission stopped"); +} + +static void pdp_o_process_yv12(t_pdp_o *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_int count, i, ret=0; + + /* setting video track */ + if ( x->x_emitflag ) + { + if ( ( (int)(header->info.image.width) != x->x_vwidth ) || + ( (int)(header->info.image.height) != x->x_vheight ) + ) + { + pdp_o_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_o_allocate(x); + } + + // smoothe image + pdp_o_smoothe(x, data, x->x_vsize ); + + for ( i=0; i<x->x_vsize; i++ ) + { + t_int downvalue; + + downvalue = (data[i]>>7); + if ( ( downvalue > 128 ) || + ( downvalue < -128 ) ) + { + // post( "pdp_o : y value out of range : %d", downvalue ); + } + if ( data[i] != x->x_previous_frame[i] ) + { + x->x_diff_frame[i] = (char)downvalue; + } + else + { + x->x_diff_frame[i] = 0; + } + } + for ( i=x->x_vsize; i<(x->x_vsize+(x->x_vsize>>1)); i++ ) + { + t_int downvalue; + + downvalue = (data[i]>>8); + if ( ( downvalue > 128 ) || + ( downvalue < -128 ) ) + { + // post( "pdp_o : y value out of range : %d", downvalue ); + } + if ( data[i] != x->x_previous_frame[i] ) + { + x->x_diff_frame[i] = (char)downvalue; + } + else + { + x->x_diff_frame[i] = 0; + } + } + + x->x_hpacket.width = x->x_vwidth; + x->x_hpacket.height = x->x_vheight; + if ( gettimeofday(&x->x_hpacket.etime, NULL) == -1) + { + post("pdp_o : could not set emit time" ); + } + if ( x->x_hpacket.etime.tv_sec != x->x_cursec ) + { + x->x_cursec = x->x_hpacket.etime.tv_sec; + x->x_secondcount = 0; + x->x_bandwidthcount = 0; + } + + // do not send the frame if too many frames + // have been sent in the current second + if ( x->x_secondcount < x->x_framerate ) + { + + // try a huffman coding + x->x_hpacket.encoding = pdp_o_huffman(x, x->x_diff_frame, x->x_hdata, x->x_vsize+(x->x_vsize>>1), &x->x_hsize ); + + x->x_hpacket.clength = (x->x_vsize+(x->x_vsize>>1))*1.01+600; + // compress the graphic data + if ( ( ret = BZ2_bzBuffToBuffCompress( x->x_cdata, + &x->x_hpacket.clength, + (char*) x->x_hdata, + x->x_hsize, + 9, 0, 0 ) ) == BZ_OK ) + { + // post( "pdp_o : bz2 compression (%d)->(%d)", x->x_hsize, x->x_hpacket.clength ); + + x->x_secondcount++; + + // memorize last emitted frame + memcpy( x->x_previous_frame, data, (x->x_vsize+(x->x_vsize>>1))<<1 ); + + // send header + count = send(x->x_fd, &x->x_hpacket, sizeof(x->x_hpacket), MSG_NOSIGNAL); + if(count < 0) + { + error("pdp_o : could not send encoded data to the peer (%d)", count); + perror( "send" ); + pdp_o_disconnect(x); + } + else + { + if((count > 0)&&(count != sizeof(x->x_hpacket))) + { + error("pdp_o : %d bytes skipped", sizeof(x->x_hpacket) - count); + } + x->x_bandwidthcount += count/1024; + } + + // send data + count = send(x->x_fd, x->x_cdata, x->x_hpacket.clength, MSG_NOSIGNAL); + if(count < 0) + { + error("pdp_o : could not send encoded data to the peer (%d)", count); + perror( "send" ); + pdp_o_disconnect(x); + } + else + { + if((count > 0)&&(count != (int)x->x_hpacket.clength)) + { + error("pdp_o : %d bytes skipped", x->x_hpacket.clength - count); + } + ++x->x_framessent; + x->x_bandwidthcount += count/1024; + } + + // unless after a refresh, next packets are diffs + strcpy( x->x_hpacket.tag, PDP_PACKET_DIFF ); + + } + else + { + post( "pdp_o : bz2 compression failed (ret=%d)", ret ); + } + } + else + { + ++x->x_framesdropped; + // post( "pdp_o : frames dropped ( framerate limit )" ); + } + } + + return; +} + +static void pdp_o_killpacket(t_pdp_o *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; +} + +static void pdp_o_process(t_pdp_o *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_o_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding) + { + + case PDP_IMAGE_YV12: + pdp_queue_add(x, pdp_o_process_yv12, pdp_o_killpacket, &x->x_queue_id); + outlet_float( x->x_framesd, x->x_framesdropped ); + outlet_float( x->x_frames, x->x_framessent ); + outlet_float( x->x_bandwidth, x->x_bandwidthcount ); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_o_process */ + break; + + } + } + +} + +static void pdp_o_input_0(t_pdp_o *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_o_process(x); + + } +} + +static void pdp_o_free(t_pdp_o *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); + // close connection if existing + pdp_o_disconnect(x); +} + +t_class *pdp_o_class; + +void *pdp_o_new(void) +{ + int i; + + t_pdp_o *x = (t_pdp_o *)pd_new(pdp_o_class); + x->x_connection_status = outlet_new (&x->x_obj, &s_float); + x->x_frames = outlet_new (&x->x_obj, &s_float); + x->x_framesd = outlet_new (&x->x_obj, &s_float); + x->x_bandwidth = outlet_new (&x->x_obj, &s_float); + + x->x_packet0 = -1; + x->x_queue_id = -1; + + x->x_framessent = 0; + x->x_framerate = DEFAULT_FRAME_RATE; + x->x_smoothing = 0; + x->x_secondcount = 0; + x->x_bandwidthcount = 0; + x->x_cursec = 0; + x->x_fd = -1; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_o_setup(void) +{ + post( pdp_o_version ); + pdp_o_class = class_new(gensym("pdp_o"), (t_newmethod)pdp_o_new, + (t_method)pdp_o_free, sizeof(t_pdp_o), 0, A_NULL); + + class_addmethod(pdp_o_class, (t_method)pdp_o_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_o_class, (t_method)pdp_o_connect, gensym("connect"), A_SYMBOL, A_FLOAT, A_NULL); + class_addmethod(pdp_o_class, (t_method)pdp_o_disconnect, gensym("disconnect"), A_NULL); + class_addmethod(pdp_o_class, (t_method)pdp_o_start, gensym("start"), A_NULL); + class_addmethod(pdp_o_class, (t_method)pdp_o_stop, gensym("stop"), A_NULL); + class_addmethod(pdp_o_class, (t_method)pdp_o_refresh, gensym("refresh"), A_NULL); + class_addmethod(pdp_o_class, (t_method)pdp_o_framerate, gensym("framerate"), A_FLOAT, A_NULL); + class_addmethod(pdp_o_class, (t_method)pdp_o_smoothing, gensym("smoothing"), A_FLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_puzzle.c b/modules/pdp_puzzle.c new file mode 100644 index 0000000..0c0520f --- /dev/null +++ b/modules/pdp_puzzle.c @@ -0,0 +1,421 @@ +/* + * PiDiP module + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is a port of puzzle effect from EffecTV + * Originally written by Fukuchi Kentaro <nullset@dookie.net> + * Pd-fication by Yves Degoyon ( ydegoyon@free.fr ) + * The origin of PuzzleTV is ``Video Puzzle'' by Suutarou in 1993. + * It runs on Fujitsu FM-TOWNS. + */ + + +#include "pdp.h" +#include <math.h> + +#define DEFAULT_BLOCK_NUMBER 5 + +static unsigned int fastrand_val; +#define inline_fastrand() (fastrand_val=fastrand_val*1103515245+12345) + +static char *pdp_puzzle_version = "pdp_puzzle: version 0.1, port of puzzle from EffecTV by Fukuchi Kentaro, adapted by ydegoyon@free.fr "; + +typedef struct pdp_puzzle_struct +{ + t_object x_obj; + t_float x_f; + + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_outlet *x_outlet0; + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + /* puzzle parameters */ + t_int *x_blockpos; + t_int *x_blockoffset; + t_int *x_ublockoffset; + t_int *x_vblockoffset; + t_int x_nbblocks; + t_int x_blockwidth; + t_int x_blockheight; + t_int x_blockw; + t_int x_blockh; + t_int x_blocknum; + t_int x_spacepos; + t_int x_spacex; + t_int x_spacey; + +} t_pdp_puzzle; + +static void pdp_puzzle_init_tables(t_pdp_puzzle *x) +{ + t_int i, a, b, c; + + for(i=0; i<x->x_blocknum; i++) + { + x->x_blockpos[i] = i; + } + for(i=0; i<20*x->x_blockw; i++) + { + /* the number of shuffling times is a rule of thumb. */ + a = inline_fastrand()%(x->x_blocknum-1); + b = inline_fastrand()%(x->x_blocknum-1); + if(a == b) b = (b+1)%(x->x_blocknum-1); + c = x->x_blockpos[a]; + x->x_blockpos[a] = x->x_blockpos[b]; + x->x_blockpos[b] = c; + } + x->x_spacepos = x->x_blocknum-1; + x->x_spacex = x->x_blockw-1; + x->x_spacey = x->x_blockh-1; + + return; +} + +static void pdp_puzzle_up(t_pdp_puzzle *x ) +{ + t_int tmp, nextpos=-1; + + if(x->x_spacey>0) + { + nextpos = x->x_spacepos - x->x_blockw; + x->x_spacey--; + } + if(nextpos>=0) + { + tmp = x->x_blockpos[x->x_spacepos]; + x->x_blockpos[x->x_spacepos] = x->x_blockpos[nextpos]; + x->x_blockpos[nextpos] = tmp; + x->x_spacepos = nextpos; + } +} + +static void pdp_puzzle_down(t_pdp_puzzle *x ) +{ + t_int tmp, nextpos=-1; + + if(x->x_spacey<x->x_blockh-1) + { + nextpos = x->x_spacepos + x->x_blockw; + x->x_spacey++; + } + if(nextpos>=0) + { + tmp = x->x_blockpos[x->x_spacepos]; + x->x_blockpos[x->x_spacepos] = x->x_blockpos[nextpos]; + x->x_blockpos[nextpos] = tmp; + x->x_spacepos = nextpos; + } +} + +static void pdp_puzzle_left(t_pdp_puzzle *x ) +{ + t_int tmp, nextpos=-1; + + if(x->x_spacex>0) + { + nextpos = x->x_spacepos - 1; + x->x_spacex--; + } + if(nextpos>=0) + { + tmp = x->x_blockpos[x->x_spacepos]; + x->x_blockpos[x->x_spacepos] = x->x_blockpos[nextpos]; + x->x_blockpos[nextpos] = tmp; + x->x_spacepos = nextpos; + } +} + +static void pdp_puzzle_right(t_pdp_puzzle *x ) +{ + t_int tmp, nextpos=-1; + + if(x->x_spacex<x->x_blockw-1) + { + nextpos = x->x_spacepos + 1; + x->x_spacex++; + } + if(nextpos>=0) + { + tmp = x->x_blockpos[x->x_spacepos]; + x->x_blockpos[x->x_spacepos] = x->x_blockpos[nextpos]; + x->x_blockpos[nextpos] = tmp; + x->x_spacepos = nextpos; + } +} + +static void pdp_puzzle_free_ressources(t_pdp_puzzle *x) +{ + if ( x->x_blockpos ) freebytes( x->x_blockpos, x->x_blocknum*sizeof(int) ); + if ( x->x_blockoffset ) freebytes( x->x_blockoffset, x->x_blocknum*sizeof(int) ); + if ( x->x_ublockoffset ) freebytes( x->x_ublockoffset, x->x_blocknum*sizeof(int) ); + if ( x->x_vblockoffset ) freebytes( x->x_vblockoffset, x->x_blocknum*sizeof(int) ); +} + +static void pdp_puzzle_allocate(t_pdp_puzzle *x) +{ + t_int px, py; + + x->x_blockwidth = x->x_vwidth / x->x_nbblocks; + x->x_blockheight = x->x_vheight / x->x_nbblocks; + x->x_blockw = x->x_nbblocks; + x->x_blockh = x->x_nbblocks; + x->x_blocknum = x->x_blockw * x->x_blockh; + + x->x_blockpos = (int *) getbytes( x->x_blocknum*sizeof(int) ); + x->x_blockoffset = (int *) getbytes( x->x_blocknum*sizeof(int) ); + x->x_ublockoffset = (int *) getbytes( x->x_blocknum*sizeof(int) ); + x->x_vblockoffset = (int *) getbytes( x->x_blocknum*sizeof(int) ); + if( x->x_blockpos == NULL || x->x_blockoffset == NULL || + x->x_ublockoffset == NULL || x->x_vblockoffset == NULL ) + { + post( "pdp_puzzle : severe error : cannot allocate buffers !!! "); + return; + } + + for(py=0; py<x->x_blockh; py++) + { + for(px=0; px<x->x_blockw; px++) + { + x->x_blockoffset[py*x->x_blockw+px] = py*x->x_blockheight*x->x_vwidth + px*x->x_blockwidth; + x->x_vblockoffset[py*x->x_blockw+px] = x->x_vsize + (py*x->x_blockheight>>1)*(x->x_vwidth>>1) + (px*x->x_blockwidth>>1); + x->x_ublockoffset[py*x->x_blockw+px] = x->x_vsize + (x->x_vsize>>2) + (py*x->x_blockheight>>1)*(x->x_vwidth>>1) + (px*x->x_blockwidth>>1); + } + } +} + +static void pdp_puzzle_nbblocks(t_pdp_puzzle *x, t_floatarg fnbblocks ) +{ + if ( ( fnbblocks > 1 ) && ( fnbblocks < x->x_vwidth/10 ) ) + { + x->x_nbblocks = fnbblocks; + post( "pdp_puzzle : number of blocks set to : %d", x->x_nbblocks ); + pdp_puzzle_free_ressources(x); + pdp_puzzle_allocate(x); + pdp_puzzle_init_tables(x); + } +} + +static void pdp_puzzle_process_yv12(t_pdp_puzzle *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + t_int px, py, xx, yy, i; + short int *pY, *qY, *pU, *pV, *qU, *qV; + + /* allocate all ressources */ + if ( ((int)header->info.image.width != x->x_vwidth) || + ((int)header->info.image.height != x->x_vheight) ) + { + pdp_puzzle_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_puzzle_allocate(x); + post( "pdp_puzzle : reallocated buffers" ); + pdp_puzzle_init_tables(x); + post( "pdp_puzzle : initialized tables" ); + } + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + i = 0; + for(py=0; py<x->x_blockh; py++) + { + for(px=0; px<x->x_blockw; px++) + { + pY = &data[x->x_blockoffset[x->x_blockpos[i]]]; + pU = &data[x->x_ublockoffset[x->x_blockpos[i]]]; + pV = &data[x->x_vblockoffset[x->x_blockpos[i]]]; + qY = &newdata[x->x_blockoffset[i]]; + qU = &newdata[x->x_ublockoffset[i]]; + qV = &newdata[x->x_vblockoffset[i]]; + if(x->x_spacepos == i) + { + for(yy=0; yy<x->x_blockheight; yy++) + { + for(xx=0; xx<x->x_blockwidth; xx++) + { + *(qY++) = 0; + if ( (xx%2==0) && (yy%2==0) ) + { + *(qU++) = 0; + *(qV++) = 0; + } + } + qY+=x->x_vwidth-x->x_blockwidth; + if ( yy%2==0 ) + { + qU+=(x->x_vwidth-x->x_blockwidth)>>1; + qV+=(x->x_vwidth-x->x_blockwidth)>>1; + } + } + } + else + { + for(yy=0; yy<x->x_blockheight; yy++) + { + for(xx=0; xx<x->x_blockwidth; xx++) + { + *(qY++) = *(pY++); + if ( (xx%2==0) && (yy%2==0) ) + { + *(qU++) = *(pU++); + *(qV++) = *(pV++); + } + } + qY+=x->x_vwidth-x->x_blockwidth; + pY+=x->x_vwidth-x->x_blockwidth; + if ( yy%2==0 ) + { + qU+=(x->x_vwidth-x->x_blockwidth)>>1; + pU+=(x->x_vwidth-x->x_blockwidth)>>1; + qV+=(x->x_vwidth-x->x_blockwidth)>>1; + pV+=(x->x_vwidth-x->x_blockwidth)>>1; + } + } + } + i++; + } + } + + return; +} + +static void pdp_puzzle_sendpacket(t_pdp_puzzle *x) +{ + /* delete source packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_puzzle_process(t_pdp_puzzle *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_puzzle_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding) + { + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_puzzle_process_yv12, pdp_puzzle_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_puzzle_process */ + break; + + } + } + +} + +static void pdp_puzzle_input_0(t_pdp_puzzle *x, t_symbol *s, t_floatarg f) +{ + + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_puzzle_process(x); + + } + +} + +static void pdp_puzzle_free(t_pdp_puzzle *x) +{ + int i; + + pdp_puzzle_free_ressources(x); + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); +} + +t_class *pdp_puzzle_class; + +void *pdp_puzzle_new(void) +{ + int i; + + t_pdp_puzzle *x = (t_pdp_puzzle *)pd_new(pdp_puzzle_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("nbblocks")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_nbblocks = DEFAULT_BLOCK_NUMBER; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_puzzle_setup(void) +{ +// post( pdp_puzzle_version ); + pdp_puzzle_class = class_new(gensym("pdp_puzzle"), (t_newmethod)pdp_puzzle_new, + (t_method)pdp_puzzle_free, sizeof(t_pdp_puzzle), 0, A_NULL); + + class_addmethod(pdp_puzzle_class, (t_method)pdp_puzzle_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_puzzle_class, (t_method)pdp_puzzle_up, gensym("up"), A_NULL); + class_addmethod(pdp_puzzle_class, (t_method)pdp_puzzle_down, gensym("down"), A_NULL); + class_addmethod(pdp_puzzle_class, (t_method)pdp_puzzle_left, gensym("left"), A_NULL); + class_addmethod(pdp_puzzle_class, (t_method)pdp_puzzle_right, gensym("right"), A_NULL); + class_addmethod(pdp_puzzle_class, (t_method)pdp_puzzle_nbblocks, gensym("nbblocks"), A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_quark.c b/modules/pdp_quark.c new file mode 100644 index 0000000..4942ce4 --- /dev/null +++ b/modules/pdp_quark.c @@ -0,0 +1,268 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is an adaptation of warp effect from effectv + * Originally written by Fukuchi Kentaro & others + * Pd-fication by Yves Degoyon + */ + + + +#include "pdp.h" +#include <math.h> + +#define DEFAULT_PLANES 16 + +static int fastrand_val=0; +#define inline_fastrand() (fastrand_val=fastrand_val*1103515245+12345) + + +static char *pdp_quark_version = "pdp_quark: version 0.1, port of quark from effectv( Fukuchi Kentaro ) adapted by Yves Degoyon (ydegoyon@free.fr)"; + +static char* the_wave_table = NULL; + +typedef struct pdp_quark_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + short int *x_buffer; + short int **x_planetable; + t_int x_plane; + t_int x_planes; + t_int x_tolerance; + +} t_pdp_quark; + +static void pdp_quark_free_ressources(t_pdp_quark *x) +{ + if ( x->x_buffer ) free ( x->x_buffer ); + if ( x->x_planetable ) free ( x->x_planetable ); +} + +static void pdp_quark_allocate(t_pdp_quark *x) +{ + int i; + + // allocate space for the frame buffers. A lot of memory is required - + // with the default settings, it totals nearly 5 megs. + x->x_buffer = (short int *) getbytes ( ( ( x->x_vsize + ( x->x_vsize>>1 ) ) << 1 ) * 2 * x->x_planes); + x->x_planetable = (short int**) getbytes( x->x_planes*sizeof( short int* ) ); + + // set up the array of pointers to the frame buffers + for(i=0;i<x->x_planes;i++) + { + x->x_planetable[i] = &x->x_buffer[ ( ( x->x_vsize + ( x->x_vsize>>1 ) ) << 1 ) * i]; + } + + if ( !x->x_buffer ) + { + post( "pdp_quark : severe error : cannot allocate buffers !!! "); + return; + } +} + +static void pdp_quark_planes(t_pdp_quark *x, t_floatarg fplanes) +{ + if ( ( (int)fplanes > 1 ) && ( (int)fplanes < 100 ) ) + { + pdp_quark_free_ressources(x); + x->x_planes = (int) fplanes; + x->x_plane=x->x_planes-1; + pdp_quark_allocate(x); + } +} + +static void pdp_quark_tolerance(t_pdp_quark *x, t_floatarg ftolerance) +{ + if ( (int)ftolerance > 1 ) + { + x->x_tolerance = (int) ftolerance; + } +} + +static void pdp_quark_process_yv12(t_pdp_quark *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + t_int i, cf, diff; + + /* allocate all ressources */ + if ( (int)(header->info.image.width*header->info.image.height) != x->x_vsize ) + { + pdp_quark_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + x->x_plane = x->x_planes-1; + pdp_quark_allocate(x); + post( "pdp_quark : reallocated buffers" ); + } + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + memcpy(x->x_planetable[x->x_plane], data, (x->x_vsize + (x->x_vsize>>1))<<1 ); + for(i=0; i<x->x_vsize+(x->x_vsize>>1); i++) + { + cf = (x->x_plane + (inline_fastrand()>>24))&(x->x_planes-1); + if ( i<x->x_vsize ) + { + diff = ((x->x_planetable[cf])[i] - data[i])>>7; + } + else + { + diff = (((x->x_planetable[cf])[i] - data[i] )>>8)+128; + } + if ( abs ( diff ) > x->x_tolerance ) + { + newdata[i] = (x->x_planetable[cf])[i]; + } + else + { + newdata[i] = data[i]; + } + /* The reason why I use high order 8 bits is written in utils.c + (or, 'man rand') */ + } + x->x_plane--; + if ( x->x_plane < 0 ) x->x_plane = x->x_planes-1; + + return; +} + +static void pdp_quark_sendpacket(t_pdp_quark *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_quark_process(t_pdp_quark *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_quark_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_quark_process_yv12, pdp_quark_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_quark_process */ + break; + + } + } +} + +static void pdp_quark_input_0(t_pdp_quark *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_quark_process(x); + } +} + +static void pdp_quark_free(t_pdp_quark *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); + pdp_quark_free_ressources(x); +} + +t_class *pdp_quark_class; + +void *pdp_quark_new(void) +{ + int i; + + t_pdp_quark *x = (t_pdp_quark *)pd_new(pdp_quark_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("planes")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("tolerance")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + x->x_planes = DEFAULT_PLANES; + + x->x_buffer = NULL; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_quark_setup(void) +{ +// post( pdp_quark_version ); + pdp_quark_class = class_new(gensym("pdp_quark"), (t_newmethod)pdp_quark_new, + (t_method)pdp_quark_free, sizeof(t_pdp_quark), 0, A_NULL); + + class_addmethod(pdp_quark_class, (t_method)pdp_quark_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_quark_class, (t_method)pdp_quark_planes, gensym("planes"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_quark_class, (t_method)pdp_quark_tolerance, gensym("tolerance"), A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_radioactiv.c b/modules/pdp_radioactiv.c new file mode 100644 index 0000000..c39dd4b --- /dev/null +++ b/modules/pdp_radioactiv.c @@ -0,0 +1,516 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is an adaptation of radioactiv effect from effectv + * Originally written by Fukuchi Kentaro & others + * Pd-fication by Yves Degoyon + */ + + + +#include "pdp.h" +#include <math.h> + +#define COLORS 32 +#define MAGIC_THRESHOLD 40 +#define RATIO 0.95 +#define DELTA (255/(COLORS/2-1)) + +#define VIDEO_HWIDTH (x->x_buf_width/2) +#define VIDEO_HHEIGHT (x->x_buf_height/2) + +static char *pdp_radioactiv_version = "pdp_radioactiv: version 0.1, port of radioactiv effect from effectv( Fukuchi Kentaro ) adapted by Yves Degoyon (ydegoyon@free.fr)"; + +typedef struct pdp_radioactiv_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + unsigned char *x_blurzoombuf; + t_int *x_blurzoomx; + t_int *x_blurzoomy; + t_int x_buf_width_blocks; + t_int x_buf_width; + t_int x_buf_height; + t_int x_buf_area; + t_int x_buf_margin_right; + t_int x_buf_margin_left; + t_int x_palette[COLORS]; + t_int x_mode; /* 0=normal 1=strobe 2=strobe2 3=trigger */ + t_int x_snap_time; + t_int x_snap_interval; + short int *x_snapframe; + short int *x_diff; + short int *x_bdata; + t_int x_snapshot; + +} t_pdp_radioactiv; + +static void pdp_radioactiv_free_ressources(t_pdp_radioactiv *x) +{ + if ( x->x_blurzoombuf ) freebytes ( x->x_blurzoombuf, x->x_buf_area*2 ); + if ( x->x_blurzoomx ) freebytes ( x->x_blurzoomx, x->x_buf_width*sizeof(t_int) ); + if ( x->x_blurzoomy ) freebytes ( x->x_blurzoomy, x->x_buf_height*sizeof(t_int) ); + if ( x->x_snapframe ) freebytes ( x->x_snapframe, ( ( x->x_vsize + x->x_vsize>>1 ) << 1 ) ); + if ( x->x_diff ) freebytes( x->x_diff, (x->x_vsize + (x->x_vsize>>1))<<1 ); + if ( x->x_bdata ) freebytes( x->x_bdata, (( x->x_vsize + (x->x_vsize>>1))<<1)); +} + +static void pdp_radioactiv_allocate(t_pdp_radioactiv *x) +{ + int i; + + x->x_buf_width_blocks = (x->x_vwidth / 32); + x->x_buf_width = x->x_buf_width_blocks * 32; + x->x_buf_height = x->x_vheight; + x->x_buf_area = x->x_buf_width * x->x_buf_height; + x->x_buf_margin_left = (x->x_vwidth - x->x_buf_width)/2; + x->x_buf_margin_right = x->x_vwidth - x->x_buf_width - x->x_buf_margin_left; + + x->x_blurzoombuf = (unsigned char *) getbytes (x->x_buf_area*2); + x->x_blurzoomx = (t_int *) getbytes (x->x_buf_width*sizeof(t_int)); + x->x_blurzoomy = (t_int *) getbytes (x->x_buf_height*sizeof(t_int)); + x->x_snapframe = (short int *) getbytes ( ( ( x->x_vsize + x->x_vsize>>1 ) << 1 ) ); + x->x_diff = (short int*) getbytes((x->x_vsize + (x->x_vsize>>1))<<1); + x->x_bdata = (short int *) getbytes((( x->x_vsize + (x->x_vsize>>1))<<1)); + + if ( !x->x_blurzoombuf || !x->x_blurzoomx || !x->x_blurzoomy || + !x->x_snapframe || !x->x_diff || !x->x_bdata ) + { + post( "pdp_radioactiv : severe error : cannot allocate buffers !!!" ); + return; + } +} + +/* check if there is a real difference with background image */ +static void pdp_radioactiv_diff(t_pdp_radioactiv *x, short int *src) +{ + int i; + int Yy=0, Yu=0, Yv=0; + int Yby=0, Ybu=0, Ybv=0; + short int *p=NULL; + short int *pb=NULL; + short int *r=NULL; + int v; + + p = src; + pb = x->x_bdata; + r = x->x_diff; + for(i=0; i<(x->x_vsize); i++) + { + Yy = (*p); + Yu = (*(p+x->x_vsize+(i>>2))); + if ( x->x_vsize+(x->x_vsize>>2)+(i>>2) > x->x_vsize+(x->x_vsize>>1) ) + { + post ("pdp_mosaic : overflow : offset=%d limit=%d", x->x_vsize+(x->x_vsize>>2)+(i>>2), + x->x_vsize+(x->x_vsize>>1) ); + return; + } + Yv = (*(p+x->x_vsize+(x->x_vsize>>2)+(i>>2))); + Yby = (*pb); + Ybu = (*(pb+x->x_vsize+(i>>2))); + Ybv = (*(pb+x->x_vsize+(x->x_vsize>>2)+(i>>2))); + if ( !r ) { post( "pdp_mosaic : hey, buffers are not allocated !!" ); return; }; + *r = ( (Yy - Yby) + (Yu - Ybu) + (Yv - Ybv) ); + r++; + } + +} + +static void pdp_radioactiv_make_palette(t_pdp_radioactiv *x) +{ + int i; + + for(i=0; i<COLORS/2; i++) + { + x->x_palette[i] = i*DELTA; + } + for(i=0; i<COLORS/2; i++) + { + x->x_palette[i+COLORS/2] = 255 | (i*DELTA)<<16 | (i*DELTA)<<8; + } + for(i=0; i<COLORS; i++) + { + x->x_palette[i] = x->x_palette[i] & 0xfefeff; + } +} + +/* this table assumes that video_width is times of 32 */ +static void pdp_radioactiv_set_table(t_pdp_radioactiv *x) +{ + unsigned int bits; + int px, py, tx, ty, xx; + int ptr=0, prevptr=0; + + prevptr = (int)(0.5+RATIO*(-VIDEO_HWIDTH)+VIDEO_HWIDTH); + for(xx=0; xx<(x->x_buf_width_blocks); xx++) + { + bits = 0; + for(px=0; px<32; px++) + { + ptr = (int)(0.5+RATIO*((xx*32)+px-VIDEO_HWIDTH)+VIDEO_HWIDTH); + bits = bits>>1; + if(ptr != prevptr) bits |= 0x80000000; + prevptr = ptr; + } + x->x_blurzoomx[xx] = bits; + } + + ty = (int)(0.5+RATIO*(-VIDEO_HHEIGHT)+VIDEO_HHEIGHT); + tx = (int)(0.5+RATIO*(-VIDEO_HWIDTH)+VIDEO_HWIDTH); + xx=(int)(0.5+RATIO*(x->x_buf_width-1-VIDEO_HWIDTH)+VIDEO_HWIDTH); + x->x_blurzoomy[0] = ty * x->x_buf_width + tx; + prevptr = ty * x->x_buf_width + xx; + for(py=1; py<x->x_buf_height; py++) + { + ty = (int)(0.5+RATIO*(py-VIDEO_HHEIGHT)+VIDEO_HHEIGHT); + x->x_blurzoomy[py] = ty * x->x_buf_width + tx - prevptr; + prevptr = ty * x->x_buf_width + xx; + } +} + +static void pdp_radioactiv_mode(t_pdp_radioactiv *x, t_floatarg fmode ) +{ + if ( ( fmode > 0 ) || ( fmode < 4 ) ) + { + x->x_mode = (int)fmode; + if(x->x_mode == 3) + { + x->x_snap_time = 1; + } + else + { + x->x_snap_time = 0; + } + } +} + +static void pdp_radioactiv_snap_time(t_pdp_radioactiv *x, t_floatarg fsnaptime ) +{ + if ( fsnaptime > 0 ) + { + x->x_snap_time = (t_int) fsnaptime; + } +} + +static void pdp_radioactiv_snap_interval(t_pdp_radioactiv *x, t_floatarg fsnapinterval ) +{ + if ( fsnapinterval > 1 ) + { + x->x_snap_interval = (t_int) fsnapinterval; + } +} + +static void pdp_radioactiv_blur(t_pdp_radioactiv *x) +{ + int px, py; + int width; + unsigned char *p, *q; + unsigned char v; + + width = x->x_buf_width; + p = x->x_blurzoombuf + width + 1; + q = p + x->x_buf_area; + + for(py=x->x_buf_height-2; py>0; py--) + { + for(px=x->x_vwidth-2; px>0; px--) + { + v = (*(p-width) + *(p-1) + *(p+1) + *(p+width))/4 - 1; + if(v == 255) v = 0; + *q = v; + p++; + q++; + } + p += 2; + q += 2; + } +} + +static void pdp_radioactiv_zoom(t_pdp_radioactiv *x) +{ + int b, px, py; + unsigned char *p, *q; + int blocks, height; + int dx; + + p = x->x_blurzoombuf + x->x_buf_area; + q = x->x_blurzoombuf; + height = x->x_buf_height; + blocks = x->x_buf_width_blocks; + + for(py=0; py<height; py++) + { + p += x->x_blurzoomy[py]; + for(b=0; b<blocks; b++) + { + dx = x->x_blurzoomx[b]; + for(px=0; px<32; px++) + { + p += (dx & 1); + *q++ = *p; + dx = dx>>1; + } + } + } +} + +static void pdp_radioactiv_blurzoom(t_pdp_radioactiv *x) +{ + pdp_radioactiv_blur(x); + pdp_radioactiv_zoom(x); +} + +static void pdp_radioactiv_process_yv12(t_pdp_radioactiv *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + int i; + + int px, py; + short int a, b; + unsigned char *p; + short int *diff, *src; + + /* allocate all ressources */ + if ( (int)(header->info.image.width*header->info.image.height) != x->x_vsize ) + { + pdp_radioactiv_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_radioactiv_allocate(x); + post( "pdp_radioactiv : reallocating buffers" ); + pdp_radioactiv_set_table(x); + post( "pdp_radioactiv : set table" ); + } + + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + + if ( x->x_bdata && x->x_snapshot ) + { + x->x_snapshot = 0; + memcpy( x->x_bdata, data, (x->x_vsize + (x->x_vsize>>1))<<1 ); + } + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + memcpy( newdata, data, (x->x_vsize + (x->x_vsize>>1))<<1); + + if(x->x_mode != 2 || x->x_snap_time <= 0) + { + pdp_radioactiv_diff(x, data); + if(x->x_mode == 0 || x->x_snap_time <= 0) + { + diff = x->x_diff + x->x_buf_margin_left; + p = x->x_blurzoombuf; + for(py=0; py<x->x_buf_height; py++) + { + for(px=0; px<x->x_buf_width; px++) + { + p[px] |= diff[px] >> 3; + } + diff += x->x_vwidth; + p += x->x_buf_width; + } + if( ( x->x_mode == 1 ) || ( x->x_mode == 2 )) + { + memcpy(x->x_snapframe, data, ( ( x->x_vsize + x->x_vsize>>1 ) << 1 ) ); + } + } + } + pdp_radioactiv_blurzoom(x); + + if( ( x->x_mode == 1 ) || ( x->x_mode == 2 )) + { + src = x->x_snapframe; + } + else + { + src = data; + } + + p = x->x_blurzoombuf; + for(py=0; py<x->x_vheight; py++) + { + for(px=0; px<x->x_buf_margin_left; px++) + { + *newdata++ = *src++; + } + for(px=0; px<x->x_buf_width; px++) + { + a = *src++ & 0xfeff; + b = x->x_palette[*p++]; + a += b; + b = a & 0x0100; + *newdata++ = a | (b - (b >> 8)); + } + for(px=0; px<x->x_buf_margin_right; px++) + { + *newdata++ = *src++; + } + } + + if( ( x->x_mode == 1 ) || ( x->x_mode == 2 ) ) + { + x->x_snap_time--; + if(x->x_snap_time < 0) { + x->x_snap_time = x->x_snap_interval; + } + } + + return; +} + +static void pdp_radioactiv_sendpacket(t_pdp_radioactiv *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_radioactiv_process(t_pdp_radioactiv *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_radioactiv_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_radioactiv_process_yv12, pdp_radioactiv_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // pdp_radioactiv_process_packet(x); + break; + + default: + /* don't know the type, so dont pdp_radioactiv_process */ + break; + + } + } +} + +static void pdp_radioactiv_input_0(t_pdp_radioactiv *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_radioactiv_process(x); + + } +} + +static void pdp_radioactiv_free(t_pdp_radioactiv *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); + pdp_radioactiv_free_ressources(x); + +} + +t_class *pdp_radioactiv_class; + +void *pdp_radioactiv_new(void) +{ + int i; + + t_pdp_radioactiv *x = (t_pdp_radioactiv *)pd_new(pdp_radioactiv_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("mode")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("snaptime")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("snapinterval")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_mode = 0; /* 0=normal/1=strobe/2=strobe2/3=trigger */ + x->x_blurzoombuf = NULL; + x->x_snapframe = NULL; + x->x_snap_time = 0; + x->x_snap_interval = 3; + x->x_blurzoombuf = NULL; + x->x_blurzoomx = NULL; + x->x_blurzoomy = NULL; + x->x_snapframe = NULL; + x->x_diff = NULL; + + pdp_radioactiv_make_palette(x); + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_radioactiv_setup(void) +{ +// post( pdp_radioactiv_version ); + pdp_radioactiv_class = class_new(gensym("pdp_radioactiv"), (t_newmethod)pdp_radioactiv_new, + (t_method)pdp_radioactiv_free, sizeof(t_pdp_radioactiv), 0, A_NULL); + + class_addmethod(pdp_radioactiv_class, (t_method)pdp_radioactiv_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_radioactiv_class, (t_method)pdp_radioactiv_mode, gensym("mode"), A_FLOAT, A_NULL); + class_addmethod(pdp_radioactiv_class, (t_method)pdp_radioactiv_snap_time, gensym("snaptime"), A_FLOAT, A_NULL); + class_addmethod(pdp_radioactiv_class, (t_method)pdp_radioactiv_snap_interval, gensym("snapinterval"), A_FLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_rec~.c b/modules/pdp_rec~.c new file mode 100644 index 0000000..7f879d0 --- /dev/null +++ b/modules/pdp_rec~.c @@ -0,0 +1,705 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon <ydegoyon@free.fr> + * + * 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. + * + */ + +/* This object is a video recording object + * It records its input in quicktime format + */ + + +#include "pdp.h" +#include <math.h> +#include <time.h> +#include <sys/time.h> +#include <quicktime/quicktime.h> +#include <quicktime/colormodels.h> + +#define DEFAULT_FRAME_RATE 25 +#define DEFAULT_CHANNELS 2 +#define DEFAULT_BITS 8 +#define DEFAULT_QUALITY 75 // from 1 to 100 +#define MAX_COMP_LENGTH 8 +#define MAX_AUDIO_PACKET_SIZE (128 * 1024) + +static char *pdp_rec_version = "pdp_rec~: version 0.1, a video/audio recording object, written by ydegoyon@free.fr"; + +typedef struct pdp_rec_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + quicktime_t *x_qtfile; + unsigned char **x_yuvpointers; + unsigned char *x_yuvbuffer; + t_int x_framerate; + t_int x_forced_framerate; + t_int x_jpeg_quality; + t_int x_newfile; + char *x_compressor; + t_int x_recflag; + t_int x_frameswritten; + struct timeval x_tstart; + struct timeval x_tstop; + struct timeval x_tlastrec; + + /* audio structures */ + int16_t **x_audio_buf; /* buffer for incoming audio */ + t_int x_audioin_position; // writing position for incoming audio + char *x_acompressor; // audio compressor + t_int x_channels; // audio channels + t_int x_samplerate; // audio sample rate + t_int x_bits; // audio bits + +} t_pdp_rec; + +static void pdp_rec_free_ressources(t_pdp_rec *x) +{ + if ( x->x_yuvpointers ) freebytes ( x->x_yuvpointers, 3*sizeof( unsigned char** ) ); + if ( x->x_yuvbuffer ) freebytes ( x->x_yuvbuffer, x->x_vsize + (x->x_vsize>>1) ); + +} + +static void pdp_rec_allocate(t_pdp_rec *x) +{ + int i; + + x->x_yuvpointers = (unsigned char**) getbytes ( 3*sizeof(unsigned char**) ); + x->x_yuvbuffer = (unsigned char*) getbytes ( x->x_vsize + (x->x_vsize>>1) ); + x->x_yuvpointers[0] = &x->x_yuvbuffer[0]; + x->x_yuvpointers[2] = &x->x_yuvbuffer[x->x_vsize]; + x->x_yuvpointers[1] = &x->x_yuvbuffer[x->x_vsize + (x->x_vsize>>2)]; +} + + /* set video track whenever width or height is changed */ +static void pdp_rec_set_video(t_pdp_rec *x) +{ + t_int ret; + + if ( !x->x_qtfile ) { + post( "pdp_rec~ : no video recording file is opened !!"); + return; + } + + if( ( ret = quicktime_set_video(x->x_qtfile, 1, x->x_vwidth, x->x_vheight, x->x_framerate, x->x_compressor) ) != 0) { + post( "pdp_rec~ : error setting video track ret=%d", ret ); + } else { + post( "pdp_rec~ : video track set" ); + } + + quicktime_set_copyright(x->x_qtfile, ""); + quicktime_set_name(x->x_qtfile, "Pdp output"); + quicktime_set_info(x->x_qtfile, "File created with PDP/PiDiP"); + +} + + /* set framerate */ +static void pdp_rec_set_framerate(t_pdp_rec *x) +{ + t_int ret; + + if ( !x->x_qtfile ) { + post( "pdp_rec~ : no video recording file is opened !!"); + return; + } + + quicktime_set_framerate(x->x_qtfile, (float)x->x_framerate ); + post( "pdp_rec~ : framerate set to : %d", x->x_framerate ); + +} + + /* set audio track */ +static void pdp_rec_set_audio(t_pdp_rec *x) +{ + t_int ret; + + if ( !x->x_qtfile ) { + post( "pdp_rec~ : no video recording file is opened !!"); + return; + } + + if( ( ret = quicktime_set_audio(x->x_qtfile, x->x_channels, x->x_samplerate, x->x_bits, x->x_acompressor ) ) == 0) + { + post( "pdp_rec~ : error setting audio track ret=%d", ret ); + post( "pdp_rec~ : params : samplerate=%d : compressor=%s : channels=%d : bits=%d", + x->x_samplerate, x->x_acompressor, x->x_channels, x->x_bits ); + } else { + post( "pdp_rec~ : %d audio track(s) allocated.", ret ); + } + +} + + /* set color model : it's hard coded : only one model supported */ +static void pdp_rec_set_cmodel(t_pdp_rec *x) +{ + t_int ret; + + if ( !x->x_qtfile ) { + post( "pdp_rec~ : no video recording file is opened !!"); + return; + } + + quicktime_set_cmodel(x->x_qtfile, BC_YUV420P ); + post( "pdp_rec~ : color model set" ); + +} + +static void pdp_rec_set_jpeg(t_pdp_rec *x) +{ + if ( !x->x_qtfile ) + { + post( "pdp_rec~ : set jpeg : no video recording file is opened !!"); + return; + } + + if ( strcmp( x->x_compressor, QUICKTIME_JPEG ) ) + { + post( "pdp_rec~ : set jpeg : the codec is not jpeg right now !!"); + return; + } + quicktime_set_jpeg( x->x_qtfile, x->x_jpeg_quality, 1 ); + post( "pdp_rec~ : jpeg quality factor set : %d", x->x_jpeg_quality ); +} + +static void pdp_rec_frame_rate(t_pdp_rec *x, t_floatarg frate ) +{ + if ( frate >= 1 ) + { + x->x_framerate = (int) frate; + x->x_forced_framerate = 1; + post( "pdp_rec~ : frame rate set to %d : open a new file to activate it", x->x_framerate ); + } +} + +static void pdp_rec_jpeg(t_pdp_rec *x, t_floatarg fjpeg ) +{ + if ( ( fjpeg >= 1 ) && ( fjpeg <= 100 )) + { + x->x_jpeg_quality = (int) fjpeg; + post( "pdp_rec~ : jpeg quality set : open a new file to activate it" ); + } +} + +static void pdp_rec_compressor(t_pdp_rec *x, t_symbol *scompressor ) +{ + char scomp[ MAX_COMP_LENGTH ]; + + // check compressor as defined in quicktime.h + if ( + strcmp( scompressor->s_name, "divx") + && strcmp( scompressor->s_name, "dv") + && strcmp( scompressor->s_name, "raw") + && strcmp( scompressor->s_name, "jpeg") + // && strcmp( scompressor->s_name, "png") // crashes with libquicktime 0.9.1 + // && strcmp( scompressor->s_name, "mjpa") // no output with libquicktime 0.9.1 + && strcmp( scompressor->s_name, "yuv2") + // && strcmp( scompressor->s_name, "yuv4") // crashes with libquicktime 0.9.1 + ) + { + post( "pdp_rec~ : unsupported codec : %s", scompressor->s_name ); + return; + } + + // map message names to libquicktime names + if ( !strcmp( scompressor->s_name, "divx") ) + { + strcpy( scomp, QUICKTIME_DIVX ); + } + if ( !strcmp( scompressor->s_name, "dv") ) + { + strcpy( scomp, QUICKTIME_DV ); + } + if ( !strcmp( scompressor->s_name, "raw") ) + { + strcpy( scomp, QUICKTIME_RAW ); + } + if ( !strcmp( scompressor->s_name, "jpeg") ) + { + strcpy( scomp, QUICKTIME_JPEG ); + } + if ( !strcmp( scompressor->s_name, "png") ) + { + strcpy( scomp, QUICKTIME_PNG ); + } + if ( !strcmp( scompressor->s_name, "mjpa") ) + { + strcpy( scomp, QUICKTIME_MJPA ); + } + if ( !strcmp( scompressor->s_name, "yuv2") ) + { + strcpy( scomp, QUICKTIME_YUV2 ); + } + if ( !strcmp( scompressor->s_name, "yuv4") ) + { + strcpy( scomp, QUICKTIME_YUV4 ); + } + + if ( x->x_compressor ) + { + freebytes( x->x_compressor, strlen( x->x_compressor )+1 ); + } + x->x_compressor = (char *) getbytes( strlen( scomp ) + 1 ); + strcpy( x->x_compressor, scomp ); + post( "pdp_rec~ : compressor set to %s : open a new file to activate it", scomp ); +} + + /* set audio compressor */ +static void pdp_rec_acompressor(t_pdp_rec *x, t_symbol *scompressor ) +{ + char scomp[ MAX_COMP_LENGTH ]; + + // check compressor as defined in quicktime.h + if ( + strcmp( scompressor->s_name, "twos") + // && strcmp( scompressor->s_name, "ima4") // produces a lot of errors ( libquicktime 0.9.1 ) + && strcmp( scompressor->s_name, "raw") + // && strcmp( scompressor->s_name, "ulaw") // produces a lot of errors ( libquicktime 0.9.1 ) + // && strcmp( scompressor->s_name, "ogg") // produces a lot of errors ( libquicktime 0.9.1 ) + ) + { + post( "pdp_rec~ : unsupported codec : %s", scompressor->s_name ); + return; + } + + // map message names to libquicktime names + if ( !strcmp( scompressor->s_name, "raw") ) + { + strcpy( scomp, QUICKTIME_RAW ); + } + if ( !strcmp( scompressor->s_name, "ima4") ) + { + strcpy( scomp, QUICKTIME_IMA4 ); + } + if ( !strcmp( scompressor->s_name, "twos") ) + { + strcpy( scomp, QUICKTIME_TWOS ); + } + if ( !strcmp( scompressor->s_name, "ulaw") ) + { + strcpy( scomp, QUICKTIME_ULAW ); + } + if ( !strcmp( scompressor->s_name, "ogg") ) + { + strcpy( scomp, QUICKTIME_VORBIS ); + } + + if ( x->x_compressor ) + { + freebytes( x->x_compressor, strlen( x->x_compressor )+1 ); + } + x->x_compressor = (char *) getbytes( strlen( scomp ) + 1 ); + strcpy( x->x_compressor, scomp ); + post( "pdp_rec~ : audio compressor set to %s : open a new file to activate it", scomp ); +} + + /* close a video file */ +static void pdp_rec_close(t_pdp_rec *x) +{ + int ret; + + if ( x->x_qtfile ) { + if( ( ret = quicktime_close(x->x_qtfile) ) != 0 ) { + post( "pdp_rec~ : error closing file ret=%d", ret ); + } else { + post( "pdp_rec~ : closed video file" ); + x->x_qtfile = NULL; + } + } +} + + /* open a new video file */ +static void pdp_rec_open(t_pdp_rec *x, t_symbol *sfile) +{ + t_int ret=0; + + // close previous video file if existing + pdp_rec_close(x); + + if ( x->x_recflag ) { + x->x_recflag = 0; + } + + if ( ( x->x_qtfile = quicktime_open(sfile->s_name, 0, 1) ) == NULL ) + { + error( "pdp_rec~ : cannot open >%s<", sfile->s_name); + error( "pdp_rec~ : ret=%d", ret ); + x->x_qtfile = NULL; + return; + } else { + x->x_frameswritten = 0; + post( "pdp_rec~ : opened >%s<", sfile->s_name); + x->x_newfile = 1; + } + +} + + /* start recording */ +static void pdp_rec_start(t_pdp_rec *x) +{ + if ( !x->x_qtfile ) { + post("pdp_rec~ : start received but no file has been opened ... ignored."); + return; + } + + if ( x->x_recflag == 1 ) { + post("pdp_rec~ : start received but recording is started ... ignored."); + return; + } + + if ( gettimeofday(&x->x_tstart, NULL) == -1) + { + post("pdp_rec~ : could not set start time" ); + } + + x->x_recflag = 1; + post("pdp_rec~ : start recording"); +} + + /* stop recording */ +static void pdp_rec_stop(t_pdp_rec *x) +{ + if ( !x->x_qtfile ) { + post("pdp_rec~ : stop received but no file has been opened ... ignored."); + return; + } + + if ( x->x_recflag == 0 ) { + post("pdp_rec~ : stop received but recording is stopped ... ignored."); + return; + } + + if ( gettimeofday(&x->x_tstop, NULL) == -1) + { + post("pdp_rec~ : could set stop time" ); + } + + // calculate frame rate if it hasn't been set + if ( !x->x_forced_framerate ) + { + if ( ( x->x_tstop.tv_sec - x->x_tstart.tv_sec ) > 0 ) + { + x->x_framerate = x->x_frameswritten / ( x->x_tstop.tv_sec - x->x_tstart.tv_sec ); + } + else + { + x->x_framerate = DEFAULT_FRAME_RATE; + } + } + + pdp_rec_set_framerate(x); + + x->x_recflag = 0; + pdp_rec_close(x); + + post("pdp_rec~ : stop recording"); +} + + /* store audio data in PCM format in a buffer for now */ +static t_int *pdp_rec_perform(t_int *w) +{ + t_float *in1 = (t_float *)(w[1]); // left audio inlet + t_float *in2 = (t_float *)(w[2]); // right audio inlet + t_pdp_rec *x = (t_pdp_rec *)(w[3]); + int n = (int)(w[4]); // number of samples + t_float fsample; + t_int isample, i; + + if ( x->x_recflag ) + { + + // just fills the buffer + while (n--) + { + fsample=*(in1++); + if (fsample > 1.0) { fsample = 1.0; } + if (fsample < -1.0) { fsample = -1.0; } + isample=(short) (32767.0 * fsample); + x->x_audio_buf[0][x->x_audioin_position]=isample; + fsample=*(in2++); + if (fsample > 1.0) { fsample = 1.0; } + if (fsample < -1.0) { fsample = -1.0; } + isample=(short) (32767.0 * fsample); + x->x_audio_buf[1][x->x_audioin_position]=isample; + x->x_audioin_position=(x->x_audioin_position+1)%(2*MAX_AUDIO_PACKET_SIZE); + if ( x->x_audioin_position == 2*MAX_AUDIO_PACKET_SIZE-1 ) + { + post( "pdp_rec~ : reaching end of audio buffer" ); + } + } + + } + + return (w+5); +} + +static void pdp_rec_dsp(t_pdp_rec *x, t_signal **sp) +{ + dsp_add(pdp_rec_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, sp[0]->s_n); +} + +static void pdp_rec_process_yv12(t_pdp_rec *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_int i, ret; + t_int px, py; + unsigned short *poy, *pou, *pov; + struct timeval trec; + t_int nbaudiosamples, nbusecs, nbrecorded; + t_float fframerate=0.0; + + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + + /* setting video track */ + if ( x->x_qtfile && x->x_recflag ) + { + if ( ( (int)(header->info.image.width) != x->x_vwidth ) || + ( (int)(header->info.image.height) != x->x_vheight ) || + ( x->x_newfile ) ) + { + pdp_rec_free_ressources(x); + x->x_newfile = 0; + if ( x->x_qtfile ) { + pdp_rec_set_video(x); + pdp_rec_set_audio(x); + pdp_rec_set_cmodel(x); + if ( !strcmp( x->x_compressor, QUICKTIME_JPEG ) ) + { + pdp_rec_set_jpeg(x); + } + } + pdp_rec_allocate(x); + } + + if ( x->x_frameswritten == 0 ) + { + if ( gettimeofday(&x->x_tlastrec, NULL) == -1) + { + post("pdp_rec~ : could set stop time" ); + } + } + + for (i=0; i<x->x_vsize; i++) + { + x->x_yuvbuffer[i] = data[i]>>7; + } + for (i=x->x_vsize; i<(x->x_vsize+(x->x_vsize>>1)); i++) + { + x->x_yuvbuffer[i] = ((data[i]>>8)+128); + } + + if ( ( ret = quicktime_encode_video(x->x_qtfile, x->x_yuvpointers, 0) ) != 0 ) + { + post( "pdp_rec~ : error writing frame : ret=%d", ret ); + } + else + { + x->x_frameswritten++; + } + + // calculate the number of audio samples to output + if ( gettimeofday(&trec, NULL) == -1) + { + post("pdp_rec~ : could set stop time" ); + } + // calculate time diff in micro seconds + nbusecs = ( trec.tv_usec - x->x_tlastrec.tv_usec ) + ( trec.tv_sec - x->x_tlastrec.tv_sec )*1000000; + nbaudiosamples = (sys_getsr()*1000000)/nbusecs; + memcpy( &x->x_tlastrec, &trec, sizeof( struct timeval) ); + + if ( x->x_audioin_position > nbaudiosamples ) + { + nbrecorded = nbaudiosamples; + } + else + { + nbrecorded = x->x_audioin_position; + } + + if ( ( ret = quicktime_encode_audio(x->x_qtfile, x->x_audio_buf, NULL, nbrecorded) ) != 0 ) + { + post( "pdp_rec~ : error writing audio data : ret=%d", ret ); + } + else + { + memcpy( &x->x_audio_buf[0][0], &x->x_audio_buf[0][nbrecorded], x->x_audioin_position-nbrecorded ); + memcpy( &x->x_audio_buf[1][0], &x->x_audio_buf[1][nbrecorded], x->x_audioin_position-nbrecorded ); + x->x_audioin_position -= nbrecorded; + // post ( "pdp_rec~ : recorded %d samples.", nbrecorded ); + } + } + + return; +} + +static void pdp_rec_killpacket(t_pdp_rec *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; +} + +static void pdp_rec_process(t_pdp_rec *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_rec_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding) + { + + case PDP_IMAGE_YV12: + if ( x->x_qtfile && x->x_recflag ) + { + outlet_float( x->x_obj.ob_outlet, x->x_frameswritten ); + } + pdp_queue_add(x, pdp_rec_process_yv12, pdp_rec_killpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_rec_process */ + break; + + } + } + +} + +static void pdp_rec_input_0(t_pdp_rec *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)) + { + /* add the process method and callback to the process queue */ + pdp_rec_process(x); + } + +} + +static void pdp_rec_free(t_pdp_rec *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); + // close video file if existing + pdp_rec_close(x); + for ( i=0; i<x->x_channels; i++) + { + if ( x->x_audio_buf[i] ) freebytes( x->x_audio_buf[i], MAX_AUDIO_PACKET_SIZE*sizeof(int16_t) ); + } + if ( x->x_audio_buf ) freebytes( x->x_audio_buf, x->x_channels*sizeof(int16_t*) ); + +} + +t_class *pdp_rec_class; + +void *pdp_rec_new(void) +{ + t_int i; + + t_pdp_rec *x = (t_pdp_rec *)pd_new(pdp_rec_class); + inlet_new (&x->x_obj, &x->x_obj.ob_pd, gensym ("signal"), gensym ("signal")); + outlet_new (&x->x_obj, &s_float); + + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_qtfile = NULL; + x->x_framerate = DEFAULT_FRAME_RATE; + x->x_forced_framerate = 0; + x->x_compressor = (char*) getbytes( strlen(QUICKTIME_JPEG)+1 ); + strcpy( x->x_compressor, QUICKTIME_JPEG ); + + /* audio defaults */ + x->x_acompressor = (char*) getbytes( strlen(QUICKTIME_TWOS)+1 ); + strcpy( x->x_acompressor, QUICKTIME_TWOS ); + x->x_samplerate = sys_getsr(); + x->x_channels = DEFAULT_CHANNELS; + x->x_bits = DEFAULT_BITS; + + x->x_audio_buf = (int16_t**) getbytes( x->x_channels*sizeof(int16_t*) ); + for ( i=0; i<x->x_channels; i++) + { + x->x_audio_buf[i] = (int16_t*) getbytes( MAX_AUDIO_PACKET_SIZE*sizeof(int16_t) ); + } + + x->x_newfile = 0; + x->x_yuvbuffer = NULL; + x->x_yuvpointers = NULL; + x->x_jpeg_quality = DEFAULT_QUALITY; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_rec_tilde_setup(void) +{ + post( pdp_rec_version ); + pdp_rec_class = class_new(gensym("pdp_rec~"), (t_newmethod)pdp_rec_new, + (t_method)pdp_rec_free, sizeof(t_pdp_rec), 0, A_NULL); + + CLASS_MAINSIGNALIN(pdp_rec_class, t_pdp_rec, x_f ); + class_addmethod(pdp_rec_class, (t_method)pdp_rec_dsp, gensym("dsp"), 0); + class_addmethod(pdp_rec_class, (t_method)pdp_rec_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_rec_class, (t_method)pdp_rec_open, gensym("open"), A_SYMBOL, A_NULL); + class_addmethod(pdp_rec_class, (t_method)pdp_rec_close, gensym("close"), A_NULL); + class_addmethod(pdp_rec_class, (t_method)pdp_rec_frame_rate, gensym("framerate"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_rec_class, (t_method)pdp_rec_compressor, gensym("compressor"), A_SYMBOL, A_NULL); + class_addmethod(pdp_rec_class, (t_method)pdp_rec_acompressor, gensym("acompressor"), A_SYMBOL, A_NULL); + class_addmethod(pdp_rec_class, (t_method)pdp_rec_jpeg, gensym("jpeg"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_rec_class, (t_method)pdp_rec_start, gensym("start"), A_NULL); + class_addmethod(pdp_rec_class, (t_method)pdp_rec_stop, gensym("stop"), A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_rev.c b/modules/pdp_rev.c new file mode 100644 index 0000000..58f5753 --- /dev/null +++ b/modules/pdp_rev.c @@ -0,0 +1,261 @@ +/* + * PiDiP module + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is an adaptation of rev effect from effectv + * (c)2002 Ed Tannenbaum + * Pd-fication by Yves Degoyon + */ + + + +#include "pdp.h" +#include <math.h> + +static char *pdp_rev_version = "pdp_rev: version 0.1, port of rev from effectv( Fukuchi Kentaro ) adapted by Yves Degoyon (ydegoyon@free.fr)"; + +typedef struct pdp_rev_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + t_int x_vgrabtime; + t_int x_vgrab; + t_int x_linespace; + t_int x_vscale; + t_int x_vcolor; + +} t_pdp_rev; + +static void pdp_rev_vgrabtime(t_pdp_rev *x, t_floatarg fvgrabtime ) +{ + if ( fvgrabtime > 1 ) + { + x->x_vgrabtime = (int)fvgrabtime; + } +} + +static void pdp_rev_linespace(t_pdp_rev *x, t_floatarg flinespace ) +{ + if ( flinespace > 1 ) + { + x->x_linespace = (int)flinespace; + } +} + +static void pdp_rev_vscale(t_pdp_rev *x, t_floatarg fvscale ) +{ + if ( fvscale > 1 ) + { + x->x_vscale = (int)fvscale; + } +} + +static void pdp_rev_color(t_pdp_rev *x, t_floatarg fvcolor ) +{ + if ( ( fvcolor > 0 ) && ( fvcolor < 0xffff ) ) + { + x->x_vcolor = ((int)fvcolor)<<8; + } +} + +void pdp_rev_vasulka(t_pdp_rev *x, short int *src, short int *dst, int srcx, int srcy, int dstx, int dsty, int w, int h) +{ + short int *cdst=dst+((dsty*x->x_vwidth)+dstx); + short int *nsrc, *nusrc, *nvsrc; + int py,px,Y,U,V,yval; + int offset; + + // draw the offset lines + for (py=srcy; py<h+srcy; py+=x->x_linespace) + { + for(px=srcx; px<=w+srcx; px++) + { + nsrc=src+(py*x->x_vwidth)+px; + nusrc=src+(((py*x->x_vwidth)+px)>>2)+x->x_vsize; + nvsrc=src+(((py*x->x_vwidth)+px)>>2)+x->x_vsize+(x->x_vsize>>2); + // Calc Y Value for curpix + Y = (*nsrc); + U = (*nusrc); + V = (*nvsrc); + yval = py - ((short)(Y + U + V) / x->x_vscale) ; + offset = px + yval * x->x_vwidth; + if(offset >= 0 && offset < x->x_vsize ) + { + cdst[offset]=x->x_vcolor; + cdst[x->x_vsize+(offset>>2)]=x->x_vcolor; + cdst[x->x_vsize+(x->x_vsize>>2)+(offset>>2)]=x->x_vcolor; + } + } + } +} + +static void pdp_rev_process_yv12(t_pdp_rev *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + int i; + + unsigned int totalnbpixels; + + totalnbpixels = x->x_vsize; + + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + memcpy( newdata, data, (x->x_vsize + (x->x_vsize>>1))<<1 ); + + x->x_vgrab++; + if (x->x_vgrab >= x->x_vgrabtime) + { + x->x_vgrab=0; + pdp_rev_vasulka(x, data, newdata, 0, 0, 0, 0, x->x_vwidth, x->x_vheight); + } + + return; +} + +static void pdp_rev_sendpacket(t_pdp_rev *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_rev_process(t_pdp_rev *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_rev_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_rev_process_yv12, pdp_rev_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + break; + + default: + /* don't know the type, so dont pdp_rev_process */ + break; + + } + } + +} + +static void pdp_rev_input_0(t_pdp_rev *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)) + { + /* add the process method and callback to the process queue */ + pdp_rev_process(x); + } +} + +static void pdp_rev_free(t_pdp_rev *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); +} + +t_class *pdp_rev_class; + +void *pdp_rev_new(void) +{ + int i; + + t_pdp_rev *x = (t_pdp_rev *)pd_new(pdp_rev_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("vgrabtime")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("linespace")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("vscale")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("color")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_vgrabtime = 1; + x->x_vgrab = 0; + x->x_linespace = 6; + x->x_vscale = 50; + x->x_vcolor = 0xffff; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_rev_setup(void) +{ +// post( pdp_rev_version ); + pdp_rev_class = class_new(gensym("pdp_rev"), (t_newmethod)pdp_rev_new, + (t_method)pdp_rev_free, sizeof(t_pdp_rev), 0, A_NULL); + + class_addmethod(pdp_rev_class, (t_method)pdp_rev_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_rev_class, (t_method)pdp_rev_vgrabtime, gensym("vgrabtime"), A_FLOAT, A_NULL); + class_addmethod(pdp_rev_class, (t_method)pdp_rev_linespace, gensym("linespace"), A_FLOAT, A_NULL); + class_addmethod(pdp_rev_class, (t_method)pdp_rev_vscale, gensym("vscale"), A_FLOAT, A_NULL); + class_addmethod(pdp_rev_class, (t_method)pdp_rev_color, gensym("color"), A_FLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_ripple.c b/modules/pdp_ripple.c new file mode 100644 index 0000000..4f54b30 --- /dev/null +++ b/modules/pdp_ripple.c @@ -0,0 +1,567 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is an adaptation of ripple effect from effectv + * Originally written by Fukuchi Kentaro & others + * Pd-fication by Yves Degoyon + */ + + + +#include "pdp.h" +#include <math.h> + +#define MAGIC_THRESHOLD 30 + +static unsigned int fastrand_val; +#define inline_fastrand() (fastrand_val=fastrand_val*1103515245+12345) + +static int sqrtable[256]; +static int sqrt_init=1; +static const int point = 16; +static const int impact = 2; +static const int decay = 8; +static const int loopnum = 2; +static int period = 0; +static int rain_stat = 0; +static unsigned int drop_prob = 0; +static int drop_prob_increment = 0; +static int drops_per_frame_max = 0; +static int drops_per_frame = 0; +static int drop_power = 0; + +static char *pdp_ripple_version = "pdp_ripple: version 0.1, port of ripple from effectv( Fukuchi Kentaro ) adapted by Yves Degoyon (ydegoyon@free.fr)"; + +typedef struct pdp_ripple_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + t_int x_maph; + t_int x_mapw; + t_int x_mode; + t_int x_threshold; + t_int *x_map; + t_int *x_map1; + t_int *x_map2; + t_int *x_map3; + signed char *x_vtable; + short int *x_diff; + short int *x_bdata; + t_int x_snapshot; + +} t_pdp_ripple; + +static void pdp_ripple_mode(t_pdp_ripple *x, t_floatarg fmode ) +{ + if ( ( fmode == 0 ) || ( fmode == 1 ) ) + { + x->x_mode = (int)fmode; + } +} + +static void pdp_ripple_threshold(t_pdp_ripple *x, t_floatarg fthreshold ) +{ + x->x_threshold = (int)fthreshold; +} + +static void pdp_ripple_increment(t_pdp_ripple *x, t_floatarg fincrement ) +{ + drop_prob_increment = (int)fincrement; +} + +static void pdp_ripple_background(t_pdp_ripple *x ) +{ + x->x_snapshot = 1; +} + +static void pdp_ripple_free_ressources(t_pdp_ripple *x) +{ + if ( x->x_diff != NULL ) freebytes( x->x_diff, (x->x_vsize + (x->x_vsize>>1))<<1 ); + if ( x->x_bdata ) freebytes( x->x_bdata, (( x->x_vsize + (x->x_vsize>>1))<<1)); + if ( x->x_map ) freebytes(x->x_map, x->x_maph*x->x_mapw*3*sizeof(t_int)); + if ( x->x_vtable ) freebytes(x->x_vtable, x->x_maph*x->x_mapw*2*sizeof(signed char)); +} + +static void pdp_ripple_allocate(t_pdp_ripple *x) +{ + int i; + + x->x_diff = (short int*) getbytes((x->x_vsize + (x->x_vsize>>1))<<1); + x->x_bdata = (short int *)getbytes((( x->x_vsize + (x->x_vsize>>1))<<1)); + x->x_maph = x->x_vheight / 2 + 1; + x->x_mapw = x->x_vwidth / 2 + 1; + x->x_map = (int *)getbytes(x->x_maph*x->x_mapw*3*sizeof(t_int)); + x->x_vtable = (signed char *)getbytes(x->x_maph*x->x_mapw*2*sizeof(signed char)); + if( !x->x_map || x->x_vtable || !x->x_bdata || ! x->x_diff ) { + post( "pdp_ripple : severe error : cannot allocate buffers" ); + } + x->x_map1 = x->x_map; + x->x_map2 = x->x_map + x->x_maph * x->x_mapw; + x->x_map3 = x->x_map + x->x_mapw * x->x_maph * 2; + +} + +/* check if there is a real difference with background image */ +short int *pdp_ripple_diff(t_pdp_ripple *x, short int *src) +{ + int i; + int Y; + int Yb; + short int *p=NULL; + short int *pb=NULL; + short int *r=NULL; + int v; + + p = src; + pb = x->x_bdata; + r = x->x_diff; + for(i=0; i<(x->x_vsize); i++) { + Y = (*p); + Yb = (*pb); + *r = ( (Yb - Y) > x->x_threshold ) ? (Yb - Y) : 0; + p++; pb++; + r++; + } + + return x->x_diff; +} + +static void pdp_ripple_motion_detect(t_pdp_ripple *x, short int *src) +{ + short int *diff; + int width; + int *p, *q; + int px, py, h; + + diff = pdp_ripple_diff(x, src); + width = x->x_vwidth; + p = x->x_map1+x->x_mapw+1; + q = x->x_map2+x->x_mapw+1; + diff += width+2; + + for(py=x->x_maph-2; py>0; py--) + { + for(px=x->x_mapw-2; px>0; px--) + { + h = (int)*diff;// + (int)*(diff+1) + (int)*(diff+width) + (int)*(diff+width+1); + if(h>0) { + *p = h<<(point + impact - 8); + *q = *p; + } + p++; + q++; + diff += 2; + } + diff += width+2; + p+=2; + q+=2; + } +} + +static inline void pdp_ripple_drop(t_pdp_ripple *x, int power) +{ + int px, py; + int *p, *q; + + px = inline_fastrand()%(x->x_mapw-4)+2; + py = inline_fastrand()%(x->x_maph-4)+2; + p = x->x_map1 + py*x->x_mapw + px; + q = x->x_map2 + py*x->x_mapw + px; + *p = power; + *q = power; + *(p-x->x_mapw) = *(p-1) = *(p+1) = *(p+x->x_mapw) = power/2; + *(p-x->x_mapw-1) = *(p-x->x_mapw+1) = *(p+x->x_mapw-1) = *(p+x->x_mapw+1) = power/4; + *(q-x->x_mapw) = *(q-1) = *(q+1) = *(q+x->x_mapw) = power/2; + *(q-x->x_mapw-1) = *(q-x->x_mapw+1) = *(q+x->x_mapw-1) = *(p+x->x_mapw+1) = power/4; +} + +static void pdp_ripple_raindrop(t_pdp_ripple *x) +{ + int i; + + if(period == 0) + { + switch(rain_stat) + { + case 0: + period = (inline_fastrand()>>23)+100; + drop_prob = 0; + drop_prob_increment = 0x00ffffff/period; + drop_power = (-(inline_fastrand()>>28)-2)<<point; + drops_per_frame_max = 2<<(inline_fastrand()>>30); // 2,4,8 or 16 + rain_stat = 1; + break; + case 1: + drop_prob = 0x00ffffff; + drops_per_frame = 1; + drop_prob_increment = 1; + period = (drops_per_frame_max - 1) * 16; + rain_stat = 2; + break; + case 2: + period = (inline_fastrand()>>22)+1000; + drop_prob_increment = 0; + rain_stat = 3; + break; + case 3: + period = (drops_per_frame_max - 1) * 16; + drop_prob_increment = -1; + rain_stat = 4; + break; + case 4: + period = (inline_fastrand()>>24)+60; + drop_prob_increment = -(drop_prob/period); + rain_stat = 5; + break; + case 5: + default: + period = (inline_fastrand()>>23)+500; + drop_prob = 0; + rain_stat = 0; + break; + } + } + switch(rain_stat) + { + default: + case 0: + break; + case 1: + case 5: + if((inline_fastrand()>>8)<drop_prob) + { + pdp_ripple_drop(x, drop_power); + } + drop_prob += drop_prob_increment; + break; + case 2: + case 3: + case 4: + for(i=drops_per_frame/16; i>0; i--) + { + pdp_ripple_drop(x, drop_power); + } + drops_per_frame += drop_prob_increment; + break; + } + period--; +} + +static void pdp_ripple_process_yv12(t_pdp_ripple *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + int i; + + unsigned int totalnbpixels; + unsigned int u_offset; + unsigned int v_offset; + unsigned int totnbpixels; + + int px, py; + int dx, dy; + int h, v; + int width, height; + int *p, *q, *r; + signed char *vp; + + /* allocate all ressources */ + if ( (int)(header->info.image.width*header->info.image.height) != x->x_vsize ) + { + pdp_ripple_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_ripple_allocate(x); + post( "pdp_ripple : reallocated buffers" ); + } + + if ( x->x_bdata && x->x_snapshot ) + { + x->x_snapshot = 0; + memcpy( x->x_bdata, data, (x->x_vsize + (x->x_vsize<<1))<<1 ); + } + + totalnbpixels = x->x_vsize; + u_offset = x->x_vsize; + v_offset = x->x_vsize + (x->x_vsize>>2); + totnbpixels = x->x_vsize + (x->x_vsize>>1); + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + memcpy( newdata, data, (x->x_vsize + (x->x_vsize>>1))<<1 ); + + if ( x->x_mode ) + { + pdp_ripple_motion_detect(x, data); + } + else + { + pdp_ripple_raindrop(x); + } + + /* simulate surface wave */ + width = x->x_mapw; + height = x->x_maph; + + /* This function is called only 30 times per second. To increase a speed + * of wave, iterates this loop several times. */ + for(i=loopnum; i>0; i--) + { + /* wave simulation */ + p = x->x_map1 + width + 1; + q = x->x_map2 + width + 1; + r = x->x_map3 + width + 1; + for(py=height-2; py>0; py--) + { + for(px=width-2; px>0; px--) + { + h = *(p-width-1) + *(p-width+1) + *(p+width-1) + *(p+width+1) + + *(p-width) + *(p-1) + *(p+1) + *(p+width) - (*p)*9; + h = h >> 3; + v = *p - *q; + v += h - (v >> decay); + *r = v + *p; + p++; + q++; + r++; + } + p += 2; + q += 2; + r += 2; + } + + /* low pass filter */ + p = x->x_map3 + width + 1; + q = x->x_map2 + width + 1; + for(py=height-2; py>0; py--) + { + for(px=width-2; px>0; px--) + { + h = *(p-width) + *(p-1) + *(p+1) + *(p+width) + (*p)*60; + *q = h >> 6; + p++; + q++; + } + p+=2; + q+=2; + } + + p = x->x_map1; + x->x_map1 = x->x_map2; + x->x_map2 = p; + } + + vp = x->x_vtable; + p = x->x_map1; + for(py=height-1; py>0; py--) + { + for(px=width-1; px>0; px--) + { + /* difference of the height between two voxel. They are twiced to + * emphasise the wave. */ + vp[0] = sqrtable[((p[0] - p[1])>>(point-1))&0xff]; + vp[1] = sqrtable[((p[0] - p[width])>>(point-1))&0xff]; + p++; + vp+=2; + } + p++; + vp+=2; + } + + height = x->x_vheight; + width = x->x_vwidth; + vp = x->x_vtable; + + /* draw refracted image. The vector table is stretched. */ + for(py=0; py<height; py+=2) + { + for(px=0; px<width; px+=2) + { + h = (int)vp[0]; + v = (int)vp[1]; + dx = px + h; + dy = py + v; + if(dx<0) dx=0; + if(dy<0) dy=0; + if(dx>=width) dx=width-1; + if(dy>=height) dy=height-1; + newdata[0] = data[dy*width+dx]; + + i = dx; + + dx = px + 1 + (h+(int)vp[2])/2; + if(dx<0) dx=0; + if(dx>=width) dx=width-1; + newdata[1] = data[dy*width+dx]; + + dy = py + 1 + (v+(int)vp[x->x_mapw*2+1])/2; + if(dy<0) dy=0; + if(dy>=height) dy=height-1; + newdata[width] = data[dy*width+i]; + + newdata[width+1] = data[dy*width+dx]; + newdata+=2; + vp+=2; + } + newdata += width; + vp += 2; + } + + return; +} + +static void pdp_ripple_sendpacket(t_pdp_ripple *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_ripple_process(t_pdp_ripple *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_ripple_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_ripple_process_yv12, pdp_ripple_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // pdp_ripple_process_packet(x); + break; + + default: + /* don't know the type, so dont pdp_ripple_process */ + break; + + } + } +} + +static void pdp_ripple_input_0(t_pdp_ripple *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)) + { + /* add the process method and callback to the process queue */ + pdp_ripple_process(x); + } +} + +static void pdp_ripple_free(t_pdp_ripple *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); + pdp_ripple_free_ressources(x); +} + +t_class *pdp_ripple_class; + +void *pdp_ripple_new(void) +{ + int i; + + t_pdp_ripple *x = (t_pdp_ripple *)pd_new(pdp_ripple_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("mode")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_bang, gensym("background")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("threshold")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("increment")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_mode = 0; + x->x_vsize = -1; + x->x_snapshot = 1; + x->x_threshold = MAGIC_THRESHOLD; + + if ( sqrt_init ) + { + sqrt_init = 0; + for(i=0; i<128; i++) { + sqrtable[i] = i*i; + } + for(i=1; i<=128; i++) { + sqrtable[256-i] = -i*i; + } + } + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_ripple_setup(void) +{ +// post( pdp_ripple_version ); + pdp_ripple_class = class_new(gensym("pdp_ripple"), (t_newmethod)pdp_ripple_new, + (t_method)pdp_ripple_free, sizeof(t_pdp_ripple), 0, A_NULL); + + class_addmethod(pdp_ripple_class, (t_method)pdp_ripple_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_ripple_class, (t_method)pdp_ripple_mode, gensym("mode"), A_FLOAT, A_NULL); + class_addmethod(pdp_ripple_class, (t_method)pdp_ripple_background, gensym("background"), A_NULL); + class_addmethod(pdp_ripple_class, (t_method)pdp_ripple_threshold, gensym("threshold"), A_FLOAT, A_NULL); + class_addmethod(pdp_ripple_class, (t_method)pdp_ripple_increment, gensym("increment"), A_FLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_segsnd~.c b/modules/pdp_segsnd~.c new file mode 100644 index 0000000..f593af7 --- /dev/null +++ b/modules/pdp_segsnd~.c @@ -0,0 +1,412 @@ +/* + * PiDiP module + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object turns an image into sound + */ + +/* Listening to : + * The Deviants - Nothing Man + * 90 day men - My Trip To Venus + */ + +#include "pdp.h" +#include "yuv.h" +#include <math.h> +#include <ctype.h> +#include <Imlib2.h> // imlib2 is required + +static char *pdp_segsnd_version = "pdp_segsnd~: version 0.1 : turns an image into sound written by ydegoyon@free.fr "; + +typedef struct pdp_segsnd_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + t_int x_x1; // coordinates of fixed segment + t_int x_y1; + t_int x_x2; + t_int x_y2; + t_int x_random; + + short int *x_data; + + /* imlib data */ + Imlib_Image x_image; + +} t_pdp_segsnd; + +static void pdp_segsnd_x1(t_pdp_segsnd *x, t_floatarg fx ) +{ + if ( ( fx >= 0 ) && ( fx < x->x_x2 ) ) + { + x->x_x1 = fx; + } +} + +static void pdp_segsnd_y1(t_pdp_segsnd *x, t_floatarg fy ) +{ + if ( ( fy >= 0 ) && ( fy < x->x_y2 ) ) + { + x->x_y1 = fy; + } +} + +static void pdp_segsnd_x2(t_pdp_segsnd *x, t_floatarg fx ) +{ + if ( ( fx >= x->x_x1 ) && ( fx < x->x_vwidth ) ) + { + x->x_x2 = fx; + } +} + +static void pdp_segsnd_y2(t_pdp_segsnd *x, t_floatarg fy ) +{ + if ( ( fy >= x->x_y1 ) && ( fy < x->x_vheight ) ) + { + x->x_y2 = fy; + } +} + +static void pdp_segsnd_random(t_pdp_segsnd *x, t_floatarg frand ) +{ + if ( ( frand == 0 ) || ( frand == 1 ) ) + { + x->x_random = frand; + } +} + +static void pdp_segsnd_allocate(t_pdp_segsnd *x) +{ + x->x_image = imlib_create_image( x->x_vwidth, x->x_vheight ); + if ( x->x_image == NULL ) + { + post( "pdp_form : severe error : could not allocate image !!" ); + } + imlib_context_set_image(x->x_image); + x->x_data = (short int *)getbytes((( x->x_vsize + (x->x_vsize>>1))<<1)); +} + +static void pdp_segsnd_free_ressources(t_pdp_segsnd *x) +{ + if ( x->x_image != NULL ) imlib_free_image(); + x->x_image = NULL; + if ( x->x_data ) freebytes( x->x_data, (( x->x_vsize + (x->x_vsize>>1))<<1)); + x->x_data = NULL; +} + +static void pdp_segsnd_process_yv12(t_pdp_segsnd *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + t_int ti; + t_int px, py; + unsigned char y, u, v; + short int *pY, *pU, *pV; + DATA32 *imdata; + DATA32 bgcolor; + + if ( ( (int)(header->info.image.width) != x->x_vwidth ) || + ( (int)(header->info.image.height) != x->x_vheight ) ) + { + pdp_segsnd_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_segsnd_allocate(x); + } + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + memcpy( newdata, data, (x->x_vsize+(x->x_vsize>>1))<<1 ); + memcpy( x->x_data, data, ((x->x_vsize+(x->x_vsize>>1))<<1)); + + imlib_image_clear(); + imlib_context_set_direction(IMLIB_TEXT_TO_ANGLE); + imdata = imlib_image_get_data(); + bgcolor = imdata[0]; + + // post( "pdp_segsnd : x1=%d y1=%d x2=%d y2=%d", x->x_x1, x->x_y1, x->x_x2, x->x_y2 ); + if ( x->x_x1 != -1 ) + { + imlib_context_set_color( 255, 255, 255, 255 ); + imlib_image_draw_line( x->x_x1, x->x_y1, x->x_x2, x->x_y2, 1); + + pY = newdata; + pV = newdata+x->x_vsize; + pU = newdata+x->x_vsize+(x->x_vsize>>2); + for ( py=0; py<x->x_vheight; py++ ) + { + for ( px=0; px<x->x_vwidth; px++ ) + { + if ( imdata[py*x->x_vwidth+px] != bgcolor ) + { + y = yuv_RGBtoY(imdata[py*x->x_vwidth+px]); + u = yuv_RGBtoU(imdata[py*x->x_vwidth+px]); + v = yuv_RGBtoV(imdata[py*x->x_vwidth+px]); + + *(pY) = y<<7; + if ( (px%2==0) && (py%2==0) ) + { + *(pV) = (v-128)<<8; + *(pU) = (u-128)<<8; + } + } + pY++; + if ( (px%2==0) && (py%2==0) ) + { + pV++;pU++; + } + } + } + if ( x->x_random ) + { + x->x_x2 = ((t_float)rand()/RAND_MAX)*x->x_vwidth; + x->x_x1 = ((t_float)rand()/RAND_MAX)*x->x_x2; + x->x_y2 = ((t_float)rand()/RAND_MAX)*x->x_vheight; + x->x_y1 = ((t_float)rand()/RAND_MAX)*x->x_y2; + } + } + + return; +} + +static void pdp_segsnd_sendpacket(t_pdp_segsnd *x) +{ + /* delete source packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_segsnd_process(t_pdp_segsnd *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)) + { + + /* pdp_segsnd_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding) + { + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_segsnd_process_yv12, pdp_segsnd_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_segsnd_process */ + break; + + } + } + +} + +static void pdp_segsnd_input_0(t_pdp_segsnd *x, t_symbol *s, t_floatarg f) +{ + + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + { + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + } + // post( "pdp_segsnd : action=%s dropped=%d", s->s_name, x->x_dropped ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)) + { + + /* add the process method and callback to the process queue */ + pdp_segsnd_process(x); + + } + +} + +static void pdp_segsnd_free(t_pdp_segsnd *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); +} + +static t_int *pdp_segsnd_perform(t_int *w) +{ + t_float *out = (t_float *)(w[1]); // audio generated sound + t_pdp_segsnd *x = (t_pdp_segsnd *)(w[2]); + t_int n = (int)(w[3]); + t_int npoints, xi, px, py; + t_float a=0; + + // set initial coordinates + if ( ( x->x_x1 == -1 ) && (x->x_vwidth != -1 )) + { + x->x_x1 = 10; + x->x_y1 = 10; + if ( 10+n > (x->x_vwidth-1) ) + { + x->x_x2 = x->x_vwidth-1; + } + else + { + x->x_x2 = 10+n; + } + if ( 10+n > (x->x_vheight-1) ) + { + x->x_y2 = x->x_vheight-1; + } + else + { + x->x_y2 = 10+n; + } + } + // post( "pdp_segsnd : x1=%d y1=%d x2=%d y2=%d", x->x_x1, x->x_y1, x->x_x2, x->x_y2 ); + + // output image data + if ( x->x_x1 == -1 ) + { + npoints = 0; + } + else if ( x->x_x2-x->x_x1 > n ) + { + npoints = n; + } + else + { + npoints = x->x_x2-x->x_x1; + } + if ( (x->x_x2-x->x_x1) > 0 ) + { + a = (x->x_y2-x->x_y1)/(x->x_x2-x->x_x1); + } + // post( "pdp_segsnd : npoints=%d a=%f", npoints, a ); + // read pixels + for (xi=0; xi<npoints; xi++) + { + px = x->x_x1 + xi; + py = x->x_y1 + (int)(a*xi); + *out = (((t_float)(x->x_data[py*x->x_vwidth+px]>>7))-127)/128.0; // scaled to -1 ... 1 + out++; + } + // fill up with zeros + for (xi=npoints; xi<n; xi++) + { + *out++ = 0.0; + } + + return (w+4); +} + +static void pdp_segsnd_dsp(t_pdp_segsnd *x, t_signal **sp) +{ + dsp_add(pdp_segsnd_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); +} + +t_class *pdp_segsnd_class; + +void *pdp_segsnd_new(void) +{ + int i; + + t_pdp_segsnd *x = (t_pdp_segsnd *)pd_new(pdp_segsnd_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("x1")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("y1")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("x2")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("y2")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("random")); + + // pdp output + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + // sound output + outlet_new (&x->x_obj, &s_signal); + + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_vwidth = -1; + x->x_vheight = -1; + + x->x_image = NULL; + x->x_data = NULL; + x->x_x1 = -1; + x->x_y1 = -1; + x->x_x2 = -1; + x->x_y2 = -1; + x->x_random = 0; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_segsnd_tilde_setup(void) +{ + + post( pdp_segsnd_version ); + pdp_segsnd_class = class_new(gensym("pdp_segsnd~"), (t_newmethod)pdp_segsnd_new, + (t_method)pdp_segsnd_free, sizeof(t_pdp_segsnd), 0, A_NULL); + + class_addmethod(pdp_segsnd_class, (t_method)pdp_segsnd_dsp, gensym("dsp"), 0); + class_addmethod(pdp_segsnd_class, (t_method)pdp_segsnd_input_0, gensym("pdp"), + A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_segsnd_class, (t_method)pdp_segsnd_x1, gensym("x1"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_segsnd_class, (t_method)pdp_segsnd_y1, gensym("y1"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_segsnd_class, (t_method)pdp_segsnd_x2, gensym("x2"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_segsnd_class, (t_method)pdp_segsnd_y2, gensym("y2"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_segsnd_class, (t_method)pdp_segsnd_random, gensym("random"), A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_shagadelic.c b/modules/pdp_shagadelic.c new file mode 100644 index 0000000..dd24e03 --- /dev/null +++ b/modules/pdp_shagadelic.c @@ -0,0 +1,307 @@ +/* + * PiDiP module + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is a port of shagadelic effect from EffecTV + * Originally written by Fukuchi Kentaro + * Pd-fication by Yves Degoyon ( ydegoyon@free.fr ) + */ + + +#include "pdp.h" +#include <math.h> + +#define MAX_TABLES 6 +static unsigned int fastrand_val; +#define inline_fastrand() (fastrand_val=fastrand_val*1103515245+12345) + +static char *pdp_shagadelic_version = "pdp_shagadelic: version 0.1, port of cycle from EffecTV by clifford smith, adapted by ydegoyon@free.fr "; + +typedef struct pdp_shagadelic_struct +{ + t_object x_obj; + t_float x_f; + + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_outlet *x_outlet0; + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + /* shagadelic parameters */ + char *x_ripple; + char *x_spiral; + unsigned char x_phase; + t_int x_rx, x_ry; + t_int x_bx, x_by; + t_int x_rvx, x_rvy; + t_int x_bvx, x_bvy; + short int x_mask; + +} t_pdp_shagadelic; + +static void pdp_shagadelic_mask(t_pdp_shagadelic *x, t_floatarg fmask ) +{ + if ( ( fmask >= 0 ) || ( fmask < 65536 ) ) + { + x->x_mask = fmask; + } +} + +static int pdp_shagadelic_map_from_table(t_pdp_shagadelic *x, t_int px, t_int py, t_int t) +{ + int xd,yd; + + yd = py + (inline_fastrand() >> 30)-2; + xd = px + (inline_fastrand() >> 30)-2; + if (xd > x->x_vwidth) { + xd-=1; + } + return (xd+yd*x->x_vwidth); +} + +static void pdp_shagadelic_init_tables(t_pdp_shagadelic *x) +{ + t_int px, py, i; + double xx, yy; + + i = 0; + for(py=0; py<x->x_vheight*2; py++) + { + yy = py - x->x_vheight; + yy *= yy; + for(px=0; px<x->x_vwidth*2; px++) + { + xx = px - x->x_vwidth; + x->x_ripple[i++] = ((unsigned int)(sqrt(xx*xx+yy)*8))&255; + } + } + i = 0; + for(py=0; py<x->x_vheight; py++) + { + yy = py - x->x_vheight/2; + for(px=0; px<x->x_vwidth; px++) + { + xx = px - x->x_vwidth/2; + x->x_spiral[i++] = ((unsigned int) ((atan2(xx, yy)/M_PI*256*9) + (sqrt(xx*xx+yy*yy)*5)))&255; + } + } + + x->x_rx = inline_fastrand()%x->x_vwidth; + x->x_ry = inline_fastrand()%x->x_vheight; + x->x_bx = inline_fastrand()%x->x_vwidth; + x->x_by = inline_fastrand()%x->x_vheight; +} + +static void pdp_shagadelic_free_ressources(t_pdp_shagadelic *x) +{ + if (x->x_ripple) freebytes( x->x_ripple, x->x_vsize*4 ); + if (x->x_spiral) freebytes( x->x_spiral, x->x_vsize ); +} + +static void pdp_shagadelic_allocate(t_pdp_shagadelic *x) +{ + x->x_ripple = (char *) getbytes( x->x_vsize*4 ); + x->x_spiral = (char *) getbytes( x->x_vsize ); +} + +static void pdp_shagadelic_process_yv12(t_pdp_shagadelic *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + t_int i; + t_int px, py; + unsigned char y, u, v; + char *p_y, *p_u, *p_v; + + + /* allocate all ressources */ + if ( ((int)header->info.image.width != x->x_vwidth) || + ((int)header->info.image.height != x->x_vheight) ) + { + pdp_shagadelic_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_shagadelic_allocate(x); + post( "pdp_shagadelic : reallocated buffers" ); + pdp_shagadelic_init_tables(x); + post( "pdp_shagadelic : initialized tables" ); + } + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + p_y = &x->x_ripple[x->x_ry*x->x_vwidth*2 + x->x_rx]; + p_u = x->x_spiral; + p_v = &x->x_ripple[x->x_by*x->x_vwidth*2 + x->x_bx]; + + for(py=0; py<x->x_vheight; py++) + { + for(px=0; px<x->x_vwidth; px++) + { + y = (char)(*p_y+x->x_phase*2)>>7; + u = (char)(*p_u+x->x_phase*3)>>7; + v = (char)(*p_v-x->x_phase)>>7; + *(newdata+py*x->x_vwidth+px) = *(data) & (y<<7) & x->x_mask; + *(newdata+x->x_vsize+((py*x->x_vwidth+px)>>2)) = *(data) & ((u-128)<<8) & x->x_mask; + *(newdata+x->x_vsize+(x->x_vsize>>2)+((py*x->x_vwidth+px)>>2)) = *(data) & ((v-128)<<8) & x->x_mask; + p_y++; + p_u++; + p_v++; + data++; + } + p_y += x->x_vwidth; + p_v += x->x_vwidth; + } + + x->x_phase -= 8; + if((x->x_rx+x->x_rvx)<0 || (x->x_rx+x->x_rvx)>=x->x_vwidth) x->x_rvx =-x->x_rvx; + if((x->x_ry+x->x_rvy)<0 || (x->x_ry+x->x_rvy)>=x->x_vheight) x->x_rvy =-x->x_rvy; + if((x->x_bx+x->x_bvx)<0 || (x->x_bx+x->x_bvx)>=x->x_vwidth) x->x_bvx =-x->x_bvx; + if((x->x_by+x->x_bvy)<0 || (x->x_by+x->x_bvy)>=x->x_vheight) x->x_bvy =-x->x_bvy; + + x->x_rx += x->x_rvx; + x->x_ry += x->x_rvy; + x->x_bx += x->x_bvx; + x->x_by += x->x_bvy; + + return; +} + +static void pdp_shagadelic_sendpacket(t_pdp_shagadelic *x) +{ + /* delete source packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_shagadelic_process(t_pdp_shagadelic *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_shagadelic_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding) + { + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_shagadelic_process_yv12, pdp_shagadelic_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_shagadelic_process */ + break; + + } + } + +} + +static void pdp_shagadelic_input_0(t_pdp_shagadelic *x, t_symbol *s, t_floatarg f) +{ + + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_shagadelic_process(x); + + } + +} + +static void pdp_shagadelic_free(t_pdp_shagadelic *x) +{ + int i; + + pdp_shagadelic_free_ressources(x); + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); +} + +t_class *pdp_shagadelic_class; + +void *pdp_shagadelic_new(void) +{ + int i; + + t_pdp_shagadelic *x = (t_pdp_shagadelic *)pd_new(pdp_shagadelic_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("mask")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_rvx = -2; + x->x_rvy = -2; + x->x_bvx = 2; + x->x_bvy = 2; + x->x_phase = 0; + x->x_mask = 0xffff; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_shagadelic_setup(void) +{ +// post( pdp_shagadelic_version ); + pdp_shagadelic_class = class_new(gensym("pdp_shagadelic"), (t_newmethod)pdp_shagadelic_new, + (t_method)pdp_shagadelic_free, sizeof(t_pdp_shagadelic), 0, A_NULL); + + class_addmethod(pdp_shagadelic_class, (t_method)pdp_shagadelic_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_shagadelic_class, (t_method)pdp_shagadelic_mask, gensym("mask"), A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_simura.c b/modules/pdp_simura.c new file mode 100644 index 0000000..04fd74b --- /dev/null +++ b/modules/pdp_simura.c @@ -0,0 +1,443 @@ +/* + * Pure Data Packet module. + * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org> + * + * 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. + * + */ + +/* This object is an adaptation of simura effect from freej + * Originally written by Fukuchi Kentarou + * Pd-fication by Yves Degoyon + */ + + + +#include "pdp.h" +#include <math.h> + +static char *pdp_simura_version = "pdp_simura: version 0.1, port of simura from freej ( Fukuchi Kentarou ), adapted by Yves Degoyon (ydegoyon@free.fr)"; + +typedef struct pdp_simura_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + unsigned short int x_color; /* color for the mask */ + t_int x_mode; /* mirror mode */ + +} t_pdp_simura; + +static void pdp_simura_process_yv12(t_pdp_simura *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + int newpacket = -1, i; + + unsigned int w = header->info.image.width; + unsigned int hw = w/2; + unsigned int hhw = w/4; + unsigned int h = header->info.image.height; + unsigned int hh = h/2; + unsigned int hhh = h/4; + + unsigned int size = w*h; + unsigned int totalnbpixels = size; + unsigned int u_offset = size; + unsigned int v_offset = size + (size>>2); + unsigned int totnbpixels = size + (size>>1); + + unsigned int px, py; + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = w; + newheader->info.image.height = h; + + switch ( x->x_mode ) + { + case 0 : + // y component + for(py=0; py<h; py++){ + for(px=0; px<w; px++){ + newdata[py*w+px] = data[py*w+px]; + } + } + // u component + for(py=0; py<hh; py++){ + for(px=0; px<hw; px++){ + newdata[u_offset+py*hw+px] = data[u_offset+py*hw+px] ^ x->x_color; + } + } + // v component + for(py=0; py<hh; py++){ + for(px=0; px<hw; px++){ + newdata[v_offset+py*hw+px] = data[v_offset+py*hw+px] ^ x->x_color; + } + } + break; + case 1 : + // y component + for(py=0; py<(hh); py++){ + for(px=0; px<w; px++){ + newdata[py*(w)+px] = data[py*(w)+px]; + newdata[((h)-py-1)*(w)+px] = data[py*(w)+px]; + } + } + // u component + for(py=0; py<(hhh); py++){ + for(px=0; px<hw; px++){ + newdata[u_offset+py*(hw)+px] = data[u_offset+py*(hw)+px] ^ x->x_color; + newdata[u_offset+((hh)-py-1)*(hw)+px] = data[u_offset+py*(hw)+px] ^ x->x_color; + } + } + // v component + for(py=0; py<(hhh); py++){ + for(px=0; px<hw; px++){ + newdata[v_offset+py*(hw)+px] = data[v_offset+py*(hw)+px] ^ x->x_color; + newdata[v_offset+((hh)-py-1)*(hw)+px] = data[v_offset+py*(hw)+px] ^ x->x_color; + } + } + break; + case 2 : + // y component + for(py=(hh); py<h; py++){ + for(px=0; px<w; px++){ + newdata[py*(w)+px] = data[py*(w)+px]; + newdata[((h)-py-1)*(w)+px] = data[py*(w)+px]; + } + } + // u component + for(py=(hhh); py<hh; py++){ + for(px=0; px<hw; px++){ + newdata[u_offset+py*(hw)+px] = data[u_offset+py*(hw)+px] ^ x->x_color; + newdata[u_offset+((hh)-py-1)*(hw)+px] = data[u_offset+py*(hw)+px] ^ x->x_color; + } + } + // v component + for(py=(hhh); py<hh; py++){ + for(px=0; px<hw; px++){ + newdata[v_offset+py*(hw)+px] = data[v_offset+py*(hw)+px] ^ x->x_color; + newdata[v_offset+((hh)-py-1)*(hw)+px] = data[v_offset+py*(hw)+px] ^ x->x_color; + } + } + break; + case 3 : + // y component + for(py=0; py<h; py++){ + for(px=0; px<(hw); px++){ + newdata[py*(w)+px] = data[py*(w)+px]; + newdata[py*(w)+((w)-px-1)] = data[py*(w)+px]; + } + } + // u component + for(py=0; py<hh; py++){ + for(px=0; px<(hhw); px++){ + newdata[u_offset+py*(hw)+px] = data[u_offset+py*(hw)+px] ^ x->x_color; + newdata[u_offset+py*(hw)+((hw)-px-1)] = data[u_offset+py*(hw)+px] ^ x->x_color; + } + } + // v component + for(py=0; py<hh; py++){ + for(px=0; px<(hhw); px++){ + newdata[v_offset+py*(hw)+px] = data[v_offset+py*(hw)+px] ^ x->x_color; + newdata[v_offset+py*(hw)+((hw)-px-1)] = data[v_offset+py*(hw)+px] ^ x->x_color; + } + } + break; + case 4 : + // y component + for(py=0; py<h; py++){ + for(px=(hw); px<w; px++){ + newdata[py*(w)+px] = data[py*(w)+px]; + newdata[py*(w)+((w)-px-1)] = data[py*(w)+px]; + } + } + // u component + for(py=0; py<hh; py++){ + for(px=(hhw); px<hw; px++){ + newdata[u_offset+py*(hw)+px] = data[u_offset+py*(hw)+px] ^ x->x_color; + newdata[u_offset+py*(hw)+((hw)-px-1)] = data[u_offset+py*(hw)+px] ^ x->x_color; + } + } + // u component + for(py=0; py<hh; py++){ + for(px=(hhw); px<hw; px++){ + newdata[u_offset+py*(hw)+px] = data[u_offset+py*(hw)+px] ^ x->x_color; + newdata[u_offset+py*(hw)+((hw)-px-1)] = data[u_offset+py*(hw)+px] ^ x->x_color; + } + } + break; + case 5 : + // y component + for(py=0; py<(hh); py++){ + for(px=0; px<(hw); px++){ + newdata[py*(w)+px] = data[py*(w)+px]; + newdata[py*(w)+((w)-px-1)] = data[py*(w)+px]; + newdata[((h)-py-1)*(w)+px] = data[py*(w)+px]; + newdata[((h)-py-1)*(w)+((w)-px-1)] = data[py*(w)+px]; + } + } + // u component + for(py=0; py<(hhh); py++){ + for(px=0; px<(hhw); px++){ + newdata[u_offset+py*(hw)+px] = data[u_offset+py*(hw)+px] ^ x->x_color; + newdata[u_offset+py*(hw)+((hw)-px-1)] = data[u_offset+py*(hw)+px] ^ x->x_color; + newdata[u_offset+((hh)-py-1)*(hw)+px] = data[u_offset+py*(hw)+px] ^ x->x_color; + newdata[u_offset+((hh)-py-1)*(w)+((hw)-px-1)] = data[u_offset+py*(hw)+px] ^ x->x_color; + } + } + // v component + for(py=0; py<(hhh); py++){ + for(px=0; px<(hhw); px++){ + newdata[v_offset+py*(hw)+px] = data[v_offset+py*(hw)+px] ^ x->x_color; + newdata[v_offset+py*(hw)+((hw)-px-1)] = data[v_offset+py*(hw)+px] ^ x->x_color; + newdata[v_offset+((hh)-py-1)*(hw)+px] = data[v_offset+py*(hw)+px] ^ x->x_color; + newdata[v_offset+((hh)-py-1)*(hw)+((hw)-px-1)] = data[v_offset+py*(hw)+px] ^ x->x_color; + } + } + break; + case 6 : + // y component + for(py=0; py<(hh); py++){ + for(px=(hw); px<w; px++){ + newdata[py*(w)+px] = data[py*(w)+px]; + newdata[py*(w)+((w)-px-1)] = data[py*(w)+px]; + newdata[((h)-py-1)*(w)+px] = data[py*(w)+px]; + newdata[((h)-py-1)*(w)+((w)-px-1)] = data[py*(w)+px]; + } + } + // u component + for(py=0; py<(hhh); py++){ + for(px=(hhw); px<(hw); px++){ + newdata[u_offset+py*(hw)+px] = data[u_offset+py*(hw)+px] ^ x->x_color; + newdata[u_offset+py*(hw)+((hw)-px-1)] = data[u_offset+py*(hw)+px] ^ x->x_color; + newdata[u_offset+((hh)-py-1)*(hw)+px] = data[u_offset+py*(hw)+px] ^ x->x_color; + newdata[u_offset+((hh)-py-1)*(hw)+((hw)-px-1)] = data[u_offset+py*(hw)+px] ^ x->x_color; + } + } + // v component + for(py=0; py<(hhh); py++){ + for(px=(hhw); px<(hw); px++){ + newdata[v_offset+py*(hw)+px] = data[v_offset+py*(hw)+px] ^ x->x_color; + newdata[v_offset+py*(hw)+((hw)-px-1)] = data[v_offset+py*(hw)+px] ^ x->x_color; + newdata[v_offset+((hh)-py-1)*(hw)+px] = data[v_offset+py*(hw)+px] ^ x->x_color; + newdata[v_offset+((hh)-py-1)*(hw)+((hw)-px-1)] = data[v_offset+py*(hw)+px] ^ x->x_color; + } + } + break; + case 7 : + // y component + for(py=(hh); py<(h); py++){ + for(px=0; px<(hw); px++){ + newdata[py*(w)+px] = data[py*(w)+px]; + newdata[py*(w)+((w)-px-1)] = data[py*(w)+px]; + newdata[((h)-py-1)*(w)+px] = data[py*(w)+px]; + newdata[((h)-py-1)*(w)+((w)-px-1)] = data[py*(w)+px]; + } + } + // u component + for(py=(hhh); py<(hh); py++){ + for(px=0; px<(hhw); px++){ + newdata[u_offset+py*(hw)+px] = data[u_offset+py*(hw)+px] ^ x->x_color; + newdata[u_offset+py*(hw)+((hw)-px-1)] = data[u_offset+py*(hw)+px] ^ x->x_color; + newdata[u_offset+((hh)-py-1)*(hw)+px] = data[u_offset+py*(hw)+px] ^ x->x_color; + newdata[u_offset+((hh)-py-1)*(hw)+((hw)-px-1)] = data[u_offset+py*(hw)+px] ^ x->x_color; + } + } + // v component + for(py=(hhh); py<(hh); py++){ + for(px=0; px<(hhw); px++){ + newdata[v_offset+py*(hw)+px] = data[v_offset+py*(hw)+px] ^ x->x_color; + newdata[v_offset+py*(hw)+((hw)-px-1)] = data[v_offset+py*(hw)+px] ^ x->x_color; + newdata[v_offset+((hh)-py-1)*(hw)+px] = data[v_offset+py*(hw)+px] ^ x->x_color; + newdata[v_offset+((hh)-py-1)*(hw)+((hw)-px-1)] = data[v_offset+py*(hw)+px]^ x->x_color; + } + } + break; + case 8 : + // y component + for(py=(hh); py<h; py++){ + for(px=(hw); px<w; px++){ + newdata[py*(w)+px] = data[py*(w)+px]; + newdata[py*(w)+((w)-px-1)] = data[py*(w)+px]; + newdata[((h)-py-1)*(w)+px] = data[py*(w)+px]; + newdata[((h)-py-1)*(w)+((w)-px-1)] = data[py*(w)+px]; + } + } + // u component + for(py=(hhh); py<(hh); py++){ + for(px=(hhw); px<(hw); px++){ + newdata[u_offset+py*(hw)+px] = data[u_offset+py*(hw)+px] ^ x->x_color; + newdata[u_offset+py*(hw)+((hw)-px-1)] = data[u_offset+py*(hw)+px] ^ x->x_color; + newdata[u_offset+((hh)-py-1)*(hw)+px] = data[u_offset+py*(hw)+px] ^ x->x_color; + newdata[u_offset+((hh)-py-1)*(hw)+((hw)-px-1)] = data[u_offset+py*(hw)+px] ^ x->x_color; + } + } + // v component + for(py=(hhh); py<(hh); py++){ + for(px=(hhw); px<(hw); px++){ + newdata[v_offset+py*(hw)+px] = data[v_offset+py*(hw)+px] ^ x->x_color; + newdata[v_offset+py*(hw)+((hw)-px-1)] = data[v_offset+py*(hw)+px] ^ x->x_color; + newdata[v_offset+((hh)-py-1)*(hw)+px] = data[v_offset+py*(hw)+px] ^ x->x_color; + newdata[v_offset+((hh)-py-1)*(hw)+((hw)-px-1)] = data[v_offset+py*(hw)+px] ^ x->x_color; + } + } + break; + } + // post( "pdp_simura : size=%d tsize=%d", size, (int)(size + (size>>1))<<1 ); + + /* delete source packet and replace with new packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = newpacket; + return; +} + +static void pdp_simura_sendpacket(t_pdp_simura *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_simura_process(t_pdp_simura *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_simura_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_simura_process_yv12, pdp_simura_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // pdp_simura_process_packet(x); + break; + + default: + /* don't know the type, so dont pdp_simura_process */ + break; + + } + } +} + +static void pdp_simura_input_0(t_pdp_simura *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)) + { + /* add the process method and callback to the process queue */ + pdp_simura_process(x); + } +} + +static void pdp_simura_color(t_pdp_simura *x, t_floatarg fcolor ) +{ + if ( (int)fcolor >0 && (int)fcolor < 0xFFFF ) + { + x->x_color = (unsigned short int)fcolor; + } + else + { + post( "pdp_simura : wrong color %d", (int) fcolor ); + } +} + +static void pdp_simura_mode(t_pdp_simura *x, t_floatarg fmode ) +{ + if ( (int)fmode >=0 && (int)fmode <= 8 ) + { + x->x_mode = (int)fmode; + } + else + { + post( "pdp_simura : wrong mode : %d : must be 0<=mode<=8", (int)fmode ); + } +} + + +static void pdp_simura_free(t_pdp_simura *x) +{ + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); +} + +t_class *pdp_simura_class; + +void *pdp_simura_new(void) +{ + int i; + + t_pdp_simura *x = (t_pdp_simura *)pd_new(pdp_simura_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("color")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("mode")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_color = 0; + x->x_mode = 0; // no mirror + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_simura_setup(void) +{ +// post( pdp_simura_version ); + + pdp_simura_class = class_new(gensym("pdp_simura"), (t_newmethod)pdp_simura_new, + (t_method)pdp_simura_free, sizeof(t_pdp_simura), 0, A_NULL); + + class_addmethod(pdp_simura_class, (t_method)pdp_simura_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_simura_class, (t_method)pdp_simura_color, gensym("color"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_simura_class, (t_method)pdp_simura_mode, gensym("mode"), A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_smuck.c b/modules/pdp_smuck.c new file mode 100644 index 0000000..968bea4 --- /dev/null +++ b/modules/pdp_smuck.c @@ -0,0 +1,228 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is an adaptation of smuck effect from veejay + * But it it inspired by effectv's transform ( mode 5 ) + * Originally written by Niels Elburg + * Pd-fication by Yves Degoyon + */ + + + +#include "pdp.h" +#include <math.h> + +#define MAX_N 100 + +static int fastrand_val=0; +#define inline_fastrand() (fastrand_val=fastrand_val*1103515245+12345) + +static char *pdp_smuck_version = "pdp_smuck: version 0.1, port of smuck from veejay( Fukuchi Kentaro ) adapted by Yves Degoyon (ydegoyon@free.fr)"; + +typedef struct pdp_smuck_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + t_int x_n; // transform number + +} t_pdp_smuck; + +static void pdp_smuck_free_ressources(t_pdp_smuck *x) +{ + // nothing +} + +static void pdp_smuck_allocate(t_pdp_smuck *x) +{ + // nothing +} + +static void pdp_smuck_n(t_pdp_smuck *x, t_floatarg fn ) +{ + if ( ( fn >= 0 ) && ( fn < MAX_N ) ) + { + x->x_n = fn; + } +} + +static void pdp_smuck_process_yv12(t_pdp_smuck *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + t_int px, py, pxx, pyy; + short int *pnY, *pnU, *pnV; + + /* allocate all ressources */ + if ( (int)(header->info.image.width*header->info.image.height) != x->x_vsize ) + { + pdp_smuck_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_smuck_allocate(x); + post( "pdp_smuck : reallocated buffers" ); + } + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + pnY = newdata; + pnV = newdata+x->x_vsize; + pnU = newdata+x->x_vsize+(x->x_vsize>>2); + + for (py = 0; py < x->x_vheight; py++) { + for (px = 0; px < x->x_vwidth; px++) { + pyy = py + (inline_fastrand() >> x->x_n) - 2; + pxx = px + (inline_fastrand() >> x->x_n) - 2; + if (pxx > x->x_vwidth) + pxx = x->x_vwidth; + if ( pxx < 0 ) pxx = 0; + if (pyy > x->x_vheight) + pyy = x->x_vheight; + if ( pyy < 0 ) pyy = 0; + *pnY++ = *( data + pyy*x->x_vwidth + pxx ); + if ( (px%2==0) && (py%2==0) ) + { + *pnU++ = *( data + x->x_vsize + ( (pyy>>1)*(x->x_vwidth>>1) + (pxx>>2) ) ); + *pnV++ = *( data + x->x_vsize + (x->x_vsize>>2) + ( (pyy>>1)*(x->x_vwidth>>1) + (pxx>>2) ) ); + } + } + } + + return; +} + +static void pdp_smuck_sendpacket(t_pdp_smuck *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_smuck_process(t_pdp_smuck *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_smuck_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_smuck_process_yv12, pdp_smuck_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_smuck_process */ + break; + + } + } +} + +static void pdp_smuck_input_0(t_pdp_smuck *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_smuck_process(x); + } +} + +static void pdp_smuck_free(t_pdp_smuck *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); + pdp_smuck_free_ressources(x); +} + +t_class *pdp_smuck_class; + +void *pdp_smuck_new(void) +{ + int i; + + t_pdp_smuck *x = (t_pdp_smuck *)pd_new(pdp_smuck_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("n")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_n = 30; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_smuck_setup(void) +{ +// post( pdp_smuck_version ); + pdp_smuck_class = class_new(gensym("pdp_smuck"), (t_newmethod)pdp_smuck_new, + (t_method)pdp_smuck_free, sizeof(t_pdp_smuck), 0, A_NULL); + + class_addmethod(pdp_smuck_class, (t_method)pdp_smuck_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_smuck_class, (t_method)pdp_smuck_n, gensym("n"), A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_spigot.c b/modules/pdp_spigot.c new file mode 100644 index 0000000..3b79bb1 --- /dev/null +++ b/modules/pdp_spigot.c @@ -0,0 +1,168 @@ +/* + * Pure Data Packet module. + * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org> + * + * 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. + * + */ + +/* This object is video packet routing utility + * Written by Yves Degoyon ( ydegoyon@free.fr ) + */ + + +#include "pdp.h" +#include <math.h> + +static char *pdp_spigot_version = "pdp_spigot: version 0.1, a video packets routing utility"; + +typedef struct pdp_spigot_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_outlet *x_outlet1; + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + t_int x_packet0; + t_int x_toggle; + +} t_pdp_spigot; + +static void pdp_spigot_toggle(t_pdp_spigot *x, t_floatarg ftoggle ) +{ + if ( ( ftoggle == 0 ) || ( ftoggle == 1 ) ) + { + x->x_toggle = ftoggle; + } +} + +static void pdp_spigot_process_packet(t_pdp_spigot *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = 0; + short int *newdata = 0; + t_int newpacket = -1, i; + + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + + return; +} + +static void pdp_spigot_process(t_pdp_spigot *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_spigot_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding) + { + + case PDP_IMAGE_YV12: + pdp_spigot_process_packet(x); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_spigot_process */ + break; + + } + } + + /* propagate if valid */ + if(x->x_packet0 != -1){ + if ( x->x_toggle ) + { + pdp_packet_pass_if_valid(x->x_outlet1, &x->x_packet0); + } + else + { + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet0); + } + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + } + +} + +static void pdp_spigot_input_0(t_pdp_spigot *x, t_symbol *s, t_floatarg f) +{ + if (s == gensym("register_rw")){ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = pdp_packet_convert_rw((int)f, pdp_gensym("image/YCrCb/*") ); + } + else if (s == gensym("process")){ + pdp_spigot_process(x); + } +} + +static void pdp_spigot_free(t_pdp_spigot *x) +{ + pdp_packet_mark_unused(x->x_packet0); +} + +t_class *pdp_spigot_class; + +void *pdp_spigot_new(void) +{ + int i; + + t_pdp_spigot *x = (t_pdp_spigot *)pd_new(pdp_spigot_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("toggle")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + x->x_outlet1 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_spigot_setup(void) +{ +// post( pdp_spigot_version ); + pdp_spigot_class = class_new(gensym("pdp_spigot"), (t_newmethod)pdp_spigot_new, + (t_method)pdp_spigot_free, sizeof(t_pdp_spigot), 0, A_NULL); + + class_addmethod(pdp_spigot_class, (t_method)pdp_spigot_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_spigot_class, (t_method)pdp_spigot_toggle, gensym("toggle"), A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_spiral.c b/modules/pdp_spiral.c new file mode 100644 index 0000000..a97442b --- /dev/null +++ b/modules/pdp_spiral.c @@ -0,0 +1,519 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is an adaptation of warp effect from effectv + * copyright (c) 2001 Sam Mertens. + * Pd-fication by Yves Degoyon + */ + + + +#include "pdp.h" +#include <math.h> + +#define PLANE_POWER (4) // 2 exp 4 = 16 +#define WAVE_COUNT_POWER (3) // 2 exp 3 = 8 +#define WAVE_LENGTH_POWER (9) // 2 exp 9 = 512 + +#define PLANES (1 << PLANE_POWER) // 16 +#define PLANE_MASK (PLANES - 1) +#define PLANE_MAX (PLANES - 1) + +#define WAVE_COUNT (1 << WAVE_COUNT_POWER) // 8 +#define WAVE_MASK (WAVE_COUNT - 1) +#define WAVE_MAX (WAVE_COUNT - 1) + +#define WAVE_LENGTH (1 << WAVE_LENGTH_POWER) // 512 +#define WAVE_LENGTH_MASK (WAVE_LENGTH - 1) + + +#define WAVE_CONCENTRIC_A 0 +#define WAVE_SAWTOOTH_UP 1 +#define WAVE_SAWTOOTH_DOWN 2 +#define WAVE_TRIANGLE 3 + +#define WAVE_SINUS 4 +#define WAVE_CONCENTRIC_B 5 +#define WAVE_LENS 6 +#define WAVE_FLAT 7 + +/* The *_OFFSET predefines are just precalculations. There shouldn't normally +** be any need to change them. +*/ + +#define WAVE_CONCENTRIC_A_OFFSET (WAVE_CONCENTRIC_A * WAVE_LENGTH) +#define WAVE_SAW_UP_OFFSET (WAVE_SAWTOOTH_UP * WAVE_LENGTH) +#define WAVE_SAW_DOWN_OFFSET (WAVE_SAWTOOTH_DOWN * WAVE_LENGTH) +#define WAVE_TRIANGLE_OFFSET (WAVE_TRIANGLE * WAVE_LENGTH) + +#define WAVE_CONCENTRIC_B_OFFSET (WAVE_CONCENTRIC_B * WAVE_LENGTH) +#define WAVE_LENS_OFFSET (WAVE_LENS * WAVE_LENGTH) +#define WAVE_SINUS_OFFSET (WAVE_SINUS * WAVE_LENGTH) +#define WAVE_FLAT_OFFSET (WAVE_FLAT * WAVE_LENGTH) + +#define WAVE_ELEMENT_SIZE (sizeof(char)) +#define WAVE_TABLE_SIZE (WAVE_COUNT * WAVE_LENGTH * WAVE_ELEMENT_SIZE) + +#define FOCUS_INCREMENT_PRESET (M_PI/2.0) + +static char *pdp_spiral_version = "pdp_spiral: version 0.1, port of spiral from effectv( Fukuchi Kentaro ) adapted by Yves Degoyon (ydegoyon@free.fr)"; + +static char* the_wave_table = NULL; + +typedef struct pdp_spiral_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + short int *x_buffer; + short int *x_planetable[PLANES]; + t_int x_plane; + t_int *x_depthmap; + t_int x_mode; + t_int x_focus_x; + t_int x_focus_y; + t_int x_cursor_state; + t_int x_cursor_local; + t_int x_toggle_xor; + t_int x_animate_focus; + t_int x_focus_interval; + t_int x_focus_counter; + unsigned int x_depth_shift; // Cheesy way to adjust intensity + t_int x_focus_radius; + double x_focus_degree; + double x_focus_increment; + +} t_pdp_spiral; + +static void pdp_spiral_define_waves(t_pdp_spiral *x) +{ + t_int i, w, iw; + double sinus_val = M_PI/2.0; + + if (NULL == the_wave_table) return; + + w = ((int)sqrt(x->x_vheight * x->x_vheight + x->x_vwidth * x->x_vwidth)); + for (i=0; i<WAVE_LENGTH; i++) + { + the_wave_table[WAVE_FLAT_OFFSET + i] = 0; + + the_wave_table[WAVE_SAW_UP_OFFSET + i] = i & PLANE_MASK; + the_wave_table[WAVE_SAW_DOWN_OFFSET + i] = PLANE_MAX - (i & PLANE_MASK); + if (i & PLANES) + { + the_wave_table[WAVE_TRIANGLE_OFFSET + i] = (~i) & PLANE_MASK; + } + else + { + the_wave_table[WAVE_TRIANGLE_OFFSET + i] = i & PLANE_MASK; + } + + iw = i / (w/(PLANES*2)); + + if (iw & PLANES) + { + the_wave_table[WAVE_CONCENTRIC_A_OFFSET + i] = (~iw) & PLANE_MASK; + } + else + { + the_wave_table[WAVE_CONCENTRIC_A_OFFSET + i] = iw & PLANE_MASK; + } + + the_wave_table[WAVE_CONCENTRIC_B_OFFSET + i] = (i*PLANES)/w; + the_wave_table[WAVE_LENS_OFFSET + i] = i >> 3; + the_wave_table[WAVE_SINUS_OFFSET + i] = ((PLANES/2) + + (int)((PLANES/2 - 1) * sin(sinus_val))) & PLANE_MASK; + sinus_val += M_PI/PLANES; + } + +} + +void pdp_spiral_create_map(t_pdp_spiral *x) +{ + t_int px, py, rel_x, rel_y, yy; + float x_ratio; + float y_ratio; + t_int v, i, wave_offset; + + if ( x->x_vsize == -1 ) + { + post( "pdp_spiral : create_map : no video data" ); + return; + } + + /* + ** The following code generates the default depth map. + */ + i = 0; + wave_offset = x->x_mode * WAVE_LENGTH; + + x_ratio = 320.0 / x->x_vwidth; + y_ratio = 240.0 / x->x_vheight; + + for (py=0; py<x->x_vheight; py++) + { + rel_y = (x->x_focus_y - py) * y_ratio; + yy = rel_y * rel_y; + + for(px=0; px<x->x_vwidth; px++) + { + rel_x = (x->x_focus_x - px) * x_ratio; + v = ((int)sqrt(yy + rel_x*rel_x)) & WAVE_LENGTH_MASK; + x->x_depthmap[i++] = the_wave_table[wave_offset + v] >> x->x_depth_shift; + } + } + + return; +} + +static void pdp_spiral_mode(t_pdp_spiral *x, t_floatarg fmode ) +{ + if ( ( fmode > 0 ) || ( fmode < WAVE_COUNT ) ) + { + x->x_mode = (int)fmode; + pdp_spiral_create_map(x); + } +} + +static void pdp_spiral_focus_x(t_pdp_spiral *x, t_floatarg ffocusx ) +{ + if ( ( ffocusx > 0 ) || ( ffocusx < x->x_vwidth ) ) + { + x->x_focus_x = (int)ffocusx; + pdp_spiral_create_map(x); + } +} + +static void pdp_spiral_focus_y(t_pdp_spiral *x, t_floatarg ffocusy ) +{ + if ( ( ffocusy > 0 ) || ( ffocusy < x->x_vwidth ) ) + { + x->x_focus_y = (int)ffocusy; + pdp_spiral_create_map(x); + } +} + +static void pdp_spiral_depth_shift(t_pdp_spiral *x, t_floatarg fdepthshift ) +{ + if ( ( fdepthshift > 0 ) || ( fdepthshift < 5 ) ) + { + x->x_depth_shift = (int)fdepthshift; + pdp_spiral_create_map(x); + } +} + +static void pdp_spiral_focus_interval(t_pdp_spiral *x, t_floatarg finterval ) +{ + if ( ( finterval > 0 ) || ( finterval < 60 ) ) + { + x->x_focus_interval = (int)finterval; + } +} + +static void pdp_spiral_focus_increment(t_pdp_spiral *x, t_floatarg fincrement ) +{ + if ( fincrement > 0 ) + { + x->x_focus_increment = (int)fincrement; + } +} + +static void pdp_spiral_toggle_xor(t_pdp_spiral *x, t_floatarg fxor ) +{ + if ( ( fxor ==0 ) || ( fxor == 1 ) ) + { + x->x_toggle_xor = (int)fxor; + } +} + +static void pdp_spiral_animate_focus(t_pdp_spiral *x, t_floatarg fafocus ) +{ + if ( ( fafocus ==0 ) || ( fafocus == 1 ) ) + { + x->x_animate_focus = (int)fafocus; + } +} + +static void pdp_spiral_free_ressources(t_pdp_spiral *x) +{ + if ( the_wave_table ) free ( the_wave_table ); + if ( x->x_buffer ) free ( x->x_buffer ); + if ( x->x_depthmap ) free ( x->x_depthmap ); +} + +static void pdp_spiral_allocate(t_pdp_spiral *x) +{ + int i; + + the_wave_table = (char*) malloc (WAVE_TABLE_SIZE); + x->x_focus_radius = x->x_vwidth / 2; + + // allocate space for the frame buffers. A lot of memory is required - + // with the default settings, it totals nearly 5 megs. + x->x_buffer = (short int *) malloc ( ( ( x->x_vsize + x->x_vsize>>1 ) << 1 ) * 2 * PLANES); + + // set up the array of pointers to the frame buffers + for(i=0;i<PLANES;i++) + { + x->x_planetable[i] = &x->x_buffer[ ( ( x->x_vsize + x->x_vsize>>1 ) << 1 ) * i]; + } + + x->x_depthmap = (t_int*) malloc ( x->x_vsize * sizeof ( t_int ) ); + + if ( !the_wave_table || !x->x_buffer || !x->x_depthmap ) + { + post( "pdp_spiral : severe error : cannot allocate buffers !!! "); + return; + } +} + +static void pdp_spiral_move_focus(t_pdp_spiral *x) +{ + x->x_focus_counter++; + // We'll only switch maps every X frames. + if (x->x_focus_interval <= x->x_focus_counter) + { + x->x_focus_counter = 0; + x->x_focus_x = (x->x_focus_radius * cos(x->x_focus_degree)) + (x->x_vwidth/2); + x->x_focus_y = (x->x_focus_radius * sin(x->x_focus_degree*2.0)) + (x->x_vheight/2); + pdp_spiral_create_map(x); + x->x_focus_degree += x->x_focus_increment; + if ((2.0*M_PI) <= x->x_focus_degree) + { + x->x_focus_degree -= (2.0*M_PI); + } + } +} + +static void pdp_spiral_process_yv12(t_pdp_spiral *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + int i, iu; + + unsigned int totalnbpixels; + unsigned int u_offset; + unsigned int v_offset; + unsigned int totnbpixels; + + int px, py; + int cf; + + /* allocate all ressources */ + if ( (int)(header->info.image.width*header->info.image.height) != x->x_vsize ) + { + pdp_spiral_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + x->x_focus_x = (x->x_vwidth/2); + x->x_focus_y = (x->x_vheight/2); + x->x_plane = PLANE_MAX; + pdp_spiral_allocate(x); + post( "pdp_spiral : reallocated buffers" ); + pdp_spiral_define_waves( x ); + pdp_spiral_create_map( x ); + post( "pdp_spiral : set wave table" ); + } + + totalnbpixels = x->x_vsize; + u_offset = x->x_vsize; + v_offset = x->x_vsize + (x->x_vsize>>2); + totnbpixels = x->x_vsize + (x->x_vsize>>1); + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + // post( "pdp_spiral : buffer=%x limit=%x dest=%x size=%d data=%x plane=%d", + // x->x_buffer, x->x_buffer + ( ( x->x_vsize + x->x_vsize>>1 ) << 1 ) * PLANES - 1, + // x->x_planetable[x->x_plane], ( ( x->x_vsize + x->x_vsize>>1) << 1 ), data, x->x_plane ); + memcpy( x->x_planetable[x->x_plane], data, ( ( x->x_vsize + x->x_vsize>>1 ) << 1 ) ); + + if (x->x_animate_focus) + { + pdp_spiral_move_focus(x); + } + + i = 0; + iu = 0; + for(py = 0; py < x->x_vheight; py++) + { + for(px = 0; px < x->x_vwidth; px++) + { + cf = (x->x_plane + x->x_depthmap[i]) & PLANE_MASK; + newdata[i] = (x->x_planetable[cf])[i]; + // u & v are untouched + newdata[x->x_vsize+iu] = data[x->x_vsize+iu]; + newdata[x->x_vsize+(x->x_vsize>>2)+iu] = data[x->x_vsize+(x->x_vsize>>2)+iu]; + i++; + if ( (px%2==0) && (py%2==0) ) + { + iu++; + } + } + } + + x->x_plane--; + x->x_plane &= PLANE_MASK; + + return; +} + +static void pdp_spiral_sendpacket(t_pdp_spiral *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_spiral_process(t_pdp_spiral *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_spiral_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_spiral_process_yv12, pdp_spiral_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + break; + + default: + /* don't know the type, so dont pdp_spiral_process */ + break; + + } + } +} + +static void pdp_spiral_input_0(t_pdp_spiral *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)) + { + /* add the process method and callback to the process queue */ + pdp_spiral_process(x); + } +} + +static void pdp_spiral_free(t_pdp_spiral *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); + pdp_spiral_free_ressources(x); +} + +t_class *pdp_spiral_class; + +void *pdp_spiral_new(void) +{ + int i; + + t_pdp_spiral *x = (t_pdp_spiral *)pd_new(pdp_spiral_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("mode")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("focus_x")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("focus_y")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("depth_shift")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("focus_interval")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("focus_increment")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("toggle_xor")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("animate_focus")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_mode = 0; + x->x_cursor_state = 0; + x->x_cursor_local = 0; + x->x_toggle_xor = 0; + x->x_animate_focus = 0; + x->x_focus_interval = 6; + x->x_focus_counter = 0; + x->x_depth_shift = 0; // Cheesy way to adjust intensity + x->x_focus_radius = 100; + x->x_focus_degree = 1.0; + x->x_focus_increment = FOCUS_INCREMENT_PRESET; + x->x_buffer = NULL; + x->x_depthmap = NULL; + the_wave_table = NULL; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_spiral_setup(void) +{ +// post( pdp_spiral_version ); + pdp_spiral_class = class_new(gensym("pdp_spiral"), (t_newmethod)pdp_spiral_new, + (t_method)pdp_spiral_free, sizeof(t_pdp_spiral), 0, A_NULL); + + class_addmethod(pdp_spiral_class, (t_method)pdp_spiral_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_spiral_class, (t_method)pdp_spiral_mode, gensym("mode"), A_FLOAT, A_NULL); + class_addmethod(pdp_spiral_class, (t_method)pdp_spiral_focus_x, gensym("focus_x"), A_FLOAT, A_NULL); + class_addmethod(pdp_spiral_class, (t_method)pdp_spiral_focus_y, gensym("focus_y"), A_FLOAT, A_NULL); + class_addmethod(pdp_spiral_class, (t_method)pdp_spiral_depth_shift, gensym("depth_shift"), A_FLOAT, A_NULL); + class_addmethod(pdp_spiral_class, (t_method)pdp_spiral_depth_shift, gensym("focus_interval"), A_FLOAT, A_NULL); + class_addmethod(pdp_spiral_class, (t_method)pdp_spiral_depth_shift, gensym("focus_increment"), A_FLOAT, A_NULL); + class_addmethod(pdp_spiral_class, (t_method)pdp_spiral_depth_shift, gensym("toggle_xor"), A_FLOAT, A_NULL); + class_addmethod(pdp_spiral_class, (t_method)pdp_spiral_depth_shift, gensym("animate_focus"), A_FLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_text.c b/modules/pdp_text.c new file mode 100644 index 0000000..81bd83f --- /dev/null +++ b/modules/pdp_text.c @@ -0,0 +1,630 @@ +/* + * PiDiP module + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is a text rendering object for PDP + * It uses imlib2 for all graphical operations + */ + +/* Listening to : + * Deviants - Nothing Man + * Monte Cazzaza - Kick That Habit Man + */ + +#include "pdp.h" +#include "yuv.h" +#include <math.h> +#include <ctype.h> +#include <Imlib2.h> // imlib2 is required + +#define DEFAULT_CAPACITY 10 +#define DEFAULT_FONT "helmetr/16" + +static char *pdp_text_version = "pdp_text: version 0.2 : text rendering object written by ydegoyon@free.fr"; + +typedef struct pdp_text_struct +{ + t_object x_obj; + t_float x_f; + + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_outlet *x_outlet0; + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + char **x_text_array; + t_int *x_xoffsets; + t_int *x_yoffsets; + t_int *x_r; + t_int *x_g; + t_int *x_b; + t_float *x_angle; + t_int *x_scroll; + + t_int x_nbtexts; + t_int x_current; + t_int x_capacity; + + /* imlib data */ + Imlib_Image x_image; + Imlib_Font x_font; + +} t_pdp_text; + + /* add a new text : syntax : text <my%20text> x y */ +static void pdp_text_add(t_pdp_text *x, t_symbol *s, int argc, t_atom *argv) +{ + char *pname; + char *pdname; + + if ( x->x_nbtexts >= x->x_capacity ) + { + post( "pdp_text : sorry, maximum capacity has been reached... try resize" ); + return; + } + + if ( argc < 3 ) + { + post( "pdp_text : error in the number of arguments ( minimum is 3 )", argc ); + return; + } + if ( argv[0].a_type != A_SYMBOL || argv[1].a_type != A_FLOAT || argv[2].a_type != A_FLOAT ) { + post( "pdp_text : add : wrong arguments" ); + return; + } + + // allocate new text area + pdname = x->x_text_array[x->x_nbtexts] = (char *) malloc( strlen( argv[0].a_w.w_symbol->s_name ) ); + pname=argv[0].a_w.w_symbol->s_name; + while (*(pname)) + { + if ( (*pname=='%') && ( isdigit(*(pname+1)) || (*(pname+1)=='%') ) ) + { + t_int ivalue; + t_int ndigits; + char *piname; + + ndigits=0; + piname=pname+1; + while ( isdigit( *(piname++) ) ) ndigits++; + + ivalue=atoi(pname+1); + + // special case %% + if ( ( pname != argv[0].a_w.w_symbol->s_name ) && ( *(pname+1) == '%' ) ) + { + *(pdname++)=*(pname++); + pname++; + continue; + } + *(pdname++)=(char)ivalue; + pname+=ndigits+1; + } + else if ( !strncmp( pname, "\"", 1 ) ) // quotes are ignored unless %34 + { + pname++; + } + else + { + *(pdname++)=*(pname++); + } + } + *(pdname)='\0'; + x->x_xoffsets[x->x_nbtexts] = (int)argv[1].a_w.w_float; + x->x_yoffsets[x->x_nbtexts] = (int)argv[2].a_w.w_float; + + if ( (argc>=4) && (argv[3].a_type == A_FLOAT) ) + { + x->x_r[x->x_nbtexts] = (int)argv[3].a_w.w_float; + } + if ( (argc>=5) && (argv[4].a_type == A_FLOAT) ) + { + x->x_g[x->x_nbtexts] = (int)argv[4].a_w.w_float; + } + if ( (argc>=6) && (argv[5].a_type == A_FLOAT) ) + { + x->x_b[x->x_nbtexts] = (int)argv[5].a_w.w_float; + } + if ( (argc>=7) && (argv[6].a_type == A_FLOAT) ) + { + x->x_angle[x->x_nbtexts] = argv[6].a_w.w_float; + } + if ( (argc>=8) && (argv[7].a_type == A_FLOAT) ) + { + x->x_scroll[x->x_nbtexts] = (int)argv[7].a_w.w_float; + } + + + post( "pdp_text : added text >%s< @ %d (r=%d g=%d b=%d)", + x->x_text_array[x->x_nbtexts], x->x_nbtexts, + x->x_r[x->x_nbtexts], x->x_g[x->x_nbtexts], x->x_b[x->x_nbtexts] ); + + if ( x->x_current == -1 ) x->x_current = x->x_nbtexts; + x->x_nbtexts++; + +} + +static void pdp_text_current(t_pdp_text *x, t_floatarg fcurrent ) +{ + if ( ( fcurrent >= 0 ) && ( fcurrent < x->x_nbtexts ) ) + { + x->x_current = fcurrent; + } +} + +static void pdp_text_textx(t_pdp_text *x, t_floatarg fx ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_nbtexts ) ) + { + x->x_xoffsets[ x->x_current ] = fx; + } +} + +static void pdp_text_texty(t_pdp_text *x, t_floatarg fy ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_nbtexts ) ) + { + x->x_yoffsets[ x->x_current ] = fy; + } +} + +static void pdp_text_textr(t_pdp_text *x, t_floatarg fr ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_nbtexts ) ) + { + x->x_r[ x->x_current ] = fr; + } +} + +static void pdp_text_textg(t_pdp_text *x, t_floatarg fg ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_nbtexts ) ) + { + x->x_g[ x->x_current ] = fg; + } +} + +static void pdp_text_textb(t_pdp_text *x, t_floatarg fb ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_nbtexts ) ) + { + x->x_b[ x->x_current ] = fb; + } +} + +static void pdp_text_angle(t_pdp_text *x, t_floatarg fangle ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_nbtexts ) ) + { + x->x_angle[ x->x_current ] = fangle; + } +} + +static void pdp_text_scroll(t_pdp_text *x, t_floatarg fscroll ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_nbtexts ) ) + { + x->x_scroll[ x->x_current ] = fscroll; + } +} + +static void pdp_text_dither(t_pdp_text *x, t_floatarg fdither ) +{ + imlib_context_set_dither( (char)fdither ); +} + +static void pdp_text_blend(t_pdp_text *x, t_floatarg fblend ) +{ + imlib_context_set_blend( (char)fblend ); +} + +static void pdp_text_antialias(t_pdp_text *x, t_floatarg fantialias ) +{ + imlib_context_set_anti_alias( (char)fantialias ); +} + +static void pdp_text_clear(t_pdp_text *x ) +{ + x->x_nbtexts = 0; +} + +static void pdp_text_delete(t_pdp_text *x, t_floatarg fnum ) +{ + t_int i; + char *lostword; + + if ( ( fnum>0 ) && ( fnum<=x->x_nbtexts ) ) + { + lostword = x->x_text_array[ (int)fnum-1 ]; + for ( i=(int)fnum; i<x->x_nbtexts; i++ ) + { + x->x_text_array[ i-1 ] = x->x_text_array[ i ]; + x->x_xoffsets[ i-1 ] = x->x_xoffsets[ i ]; + x->x_yoffsets[ i-1 ] = x->x_yoffsets[ i ]; + x->x_r[ i-1 ] = x->x_r[ i ]; + x->x_g[ i-1 ] = x->x_g[ i ]; + x->x_b[ i-1 ] = x->x_b[ i ]; + x->x_angle[ i-1 ] = x->x_angle[ i ]; + x->x_scroll[ i-1 ] = x->x_scroll[ i ]; + } + x->x_nbtexts--, + free( lostword ); + } +} + +static void pdp_text_resize(t_pdp_text *x, t_floatarg fnewsize ) +{ + char **text_array; + t_int *xoffsets; + t_int *yoffsets; + t_int *r; + t_int *g; + t_int *b; + t_float *angle; + t_int *scroll; + + t_int i, csize; + + if ( (int) fnewsize<=0 ) return; + + // allocate new structures + text_array = (char**) getbytes( fnewsize*sizeof(char*) ); + xoffsets = (t_int*) getbytes( fnewsize*sizeof(t_int) ); + yoffsets = (t_int*) getbytes( fnewsize*sizeof(t_int) ); + r = (t_int*) getbytes( fnewsize*sizeof(t_int) ); + g = (t_int*) getbytes( fnewsize*sizeof(t_int) ); + b = (t_int*) getbytes( fnewsize*sizeof(t_int) ); + angle = (t_float*) getbytes( fnewsize*sizeof(t_float) ); + scroll = (t_int*) getbytes( fnewsize*sizeof(t_int) ); + + + for ( i=0; i<fnewsize; i++ ) + { + r[i] = g[i] = b[i] = 255; + } + + if ( fnewsize < x->x_nbtexts ) + { + post( "pdp_text : new size is too small : texts lost !!" ); + csize = fnewsize; + } + else + { + csize = x->x_nbtexts; + } + + // copy all values + for ( i=0; i<csize; i++ ) + { + text_array[i] = (char*) malloc( strlen( x->x_text_array[i] ) + 1 ); + strcpy( text_array[i], x->x_text_array[i] ); + free( x->x_text_array[i] ); + xoffsets[i] = x->x_xoffsets[i]; + yoffsets[i] = x->x_yoffsets[i]; + r[i] = x->x_r[i]; + g[i] = x->x_g[i]; + b[i] = x->x_b[i]; + angle[i] = x->x_angle[i]; + scroll[i] = x->x_scroll[i]; + } + + // free old structures + if ( x->x_text_array ) freebytes( x->x_text_array, x->x_capacity*sizeof(char*) ); + if ( x->x_xoffsets ) freebytes( x->x_xoffsets, x->x_capacity*sizeof(t_int) ); + if ( x->x_yoffsets ) freebytes( x->x_yoffsets, x->x_capacity*sizeof(t_int) ); + if ( x->x_r ) freebytes( x->x_r, x->x_capacity*sizeof(t_int) ); + if ( x->x_g ) freebytes( x->x_g, x->x_capacity*sizeof(t_int) ); + if ( x->x_b ) freebytes( x->x_b, x->x_capacity*sizeof(t_int) ); + if ( x->x_angle) freebytes( x->x_angle, x->x_capacity*sizeof(t_float) ); + if ( x->x_scroll) freebytes( x->x_scroll, x->x_capacity*sizeof(t_int) ); + + // set new structures + x->x_text_array = text_array; + x->x_xoffsets = xoffsets; + x->x_yoffsets = yoffsets; + x->x_r = r; + x->x_g = g; + x->x_b = b; + x->x_angle = angle; + x->x_scroll = scroll; + x->x_nbtexts = csize; + x->x_capacity = csize; + if ( x->x_nbtexts > 0 ) + { + x->x_current = 0; + } + else + { + x->x_current = -1; + } +} + +static void pdp_text_font(t_pdp_text *x, t_symbol *sfont ) +{ + Imlib_Font font; + + font = imlib_load_font(sfont->s_name); + if ( !font ) + { + post( "pdp_text : could not load font : >%s<", sfont->s_name ); + return; + } + imlib_context_set_font( font ); + x->x_font = font; +} + +static void pdp_text_allocate(t_pdp_text *x) +{ + x->x_image = imlib_create_image( x->x_vwidth, x->x_vheight ); + if ( x->x_image == NULL ) + { + post( "pdp_text : severe error : could not allocate image !!" ); + return; + } + imlib_context_set_image(x->x_image); +} + +static void pdp_text_free_ressources(t_pdp_text *x) +{ + if ( x->x_image != NULL ) imlib_free_image(); +} + +static void pdp_text_process_yv12(t_pdp_text *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + t_int ti; + t_int px, py; + unsigned char y, u, v; + DATA32 *imdata; + DATA32 bgcolor; + short int *pY, *pU, *pV; + int text_width, text_height; + + if ( ( (int)(header->info.image.width) != x->x_vwidth ) || + ( (int)(header->info.image.height) != x->x_vheight ) ) + { + pdp_text_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_text_allocate(x); + } + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + memcpy( newdata, data, (x->x_vsize+(x->x_vsize>>1))<<1 ); + + // draw all texts + imlib_image_clear(); + imlib_context_set_direction(IMLIB_TEXT_TO_ANGLE); + imdata = imlib_image_get_data(); + bgcolor = imdata[0]; + + for (ti=0; ti<x->x_nbtexts; ti++) + { + imlib_context_set_angle( x->x_angle[ti] ); + imlib_context_set_color( x->x_r[ti], x->x_g[ti], x->x_b[ti], 255 ); + + imlib_get_text_size( x->x_text_array[ti], &text_width, &text_height); + + imlib_text_draw( x->x_xoffsets[ti] - (0.5*text_width) + (cos(x->x_angle[ti]) * x->x_scroll[ti]), x->x_yoffsets[ti] - (0.5*text_height) + (sin(x->x_angle[ti]) * x->x_scroll[ti]), x->x_text_array[ti] ); + } + + pY = newdata; + pV = newdata+x->x_vsize; + pU = newdata+x->x_vsize+(x->x_vsize>>2); + for ( py=0; py<x->x_vheight; py++ ) + { + for ( px=0; px<x->x_vwidth; px++ ) + { + if ( imdata[py*x->x_vwidth+px] != bgcolor ) + { + y = yuv_RGBtoY(imdata[py*x->x_vwidth+px]); + u = yuv_RGBtoU(imdata[py*x->x_vwidth+px]); + v = yuv_RGBtoV(imdata[py*x->x_vwidth+px]); + + *(pY) = y<<7; + if ( (px%2==0) && (py%2==0) ) + { + *(pV) = (v-128)<<8; + *(pU) = (u-128)<<8; + } + } + pY++; + if ( (px%2==0) && (py%2==0) ) + { + pV++;pU++; + } + } + } + + return; +} + +static void pdp_text_sendpacket(t_pdp_text *x) +{ + /* delete source packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_text_process(t_pdp_text *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_text_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding) + { + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_text_process_yv12, pdp_text_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_text_process */ + break; + + } + } + +} + +static void pdp_text_input_0(t_pdp_text *x, t_symbol *s, t_floatarg f) +{ + + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_text_process(x); + + } + +} + +static void pdp_text_free(t_pdp_text *x) +{ + int i; + + pdp_text_free_ressources(x); + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); +} + +t_class *pdp_text_class; + +void *pdp_text_new(void) +{ + int i; + + t_pdp_text *x = (t_pdp_text *)pd_new(pdp_text_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("current")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("textx")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("texty")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("textr")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("textg")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("textb")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("angle")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("scroll")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + x->x_image = NULL; + + x->x_font = imlib_context_get_font(); + + x->x_capacity = DEFAULT_CAPACITY; + + + x->x_text_array = (char**) getbytes( x->x_capacity*sizeof(char*) ); + x->x_xoffsets = (t_int*) getbytes( x->x_capacity*sizeof(t_int) ); + x->x_yoffsets = (t_int*) getbytes( x->x_capacity*sizeof(t_int) ); + x->x_r = (t_int*) getbytes( x->x_capacity*sizeof(t_int) ); + x->x_g = (t_int*) getbytes( x->x_capacity*sizeof(t_int) ); + x->x_b = (t_int*) getbytes( x->x_capacity*sizeof(t_int) ); + x->x_angle = (t_float*) getbytes( x->x_capacity*sizeof(t_float) ); + x->x_scroll = (t_int*) getbytes( x->x_capacity*sizeof(t_int) ); + + for ( i=0; i<x->x_capacity; i++ ) + { + x->x_r[i] = x->x_g[i] = x->x_b[i] = 255; + } + + x->x_nbtexts = 0; + x->x_current = -1; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_text_setup(void) +{ + Imlib_Font font; + + post( pdp_text_version ); + pdp_text_class = class_new(gensym("pdp_text"), (t_newmethod)pdp_text_new, + (t_method)pdp_text_free, sizeof(t_pdp_text), 0, A_NULL); + + class_addmethod(pdp_text_class, (t_method)pdp_text_input_0, gensym("pdp"), + A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_text_class, (t_method)pdp_text_add, gensym("text"), A_GIMME, A_NULL); + class_addmethod(pdp_text_class, (t_method)pdp_text_current, gensym("current"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_text_class, (t_method)pdp_text_textx, gensym("textx"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_text_class, (t_method)pdp_text_texty, gensym("texty"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_text_class, (t_method)pdp_text_textr, gensym("textr"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_text_class, (t_method)pdp_text_textg, gensym("textg"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_text_class, (t_method)pdp_text_textb, gensym("textb"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_text_class, (t_method)pdp_text_clear, gensym("clear"), A_NULL); + class_addmethod(pdp_text_class, (t_method)pdp_text_delete, gensym("delete"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_text_class, (t_method)pdp_text_resize, gensym("resize"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_text_class, (t_method)pdp_text_font, gensym("font"), A_SYMBOL, A_NULL); + class_addmethod(pdp_text_class, (t_method)pdp_text_angle, gensym("angle"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_text_class, (t_method)pdp_text_scroll, gensym("scroll"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_text_class, (t_method)pdp_text_dither, gensym("dither"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_text_class, (t_method)pdp_text_blend, gensym("blend"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_text_class, (t_method)pdp_text_antialias, gensym("antialias"), A_DEFFLOAT, A_NULL); + + imlib_add_path_to_font_path("/usr/X11R6/lib/X11/fonts/TTF"); + font = imlib_load_font(DEFAULT_FONT); + if ( !font ) + { + post( "pdp_text : severe error : could not load default font : no rendering !!!" ); + } + imlib_context_set_font( font ); +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_transform.c b/modules/pdp_transform.c new file mode 100644 index 0000000..b69f778 --- /dev/null +++ b/modules/pdp_transform.c @@ -0,0 +1,357 @@ +/* + * PiDiP module + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is a port of transform effect from EffecTV + * Originally written by clifford smith <nullset@dookie.net> + * Pd-fication by Yves Degoyon ( ydegoyon@free.fr ) + */ + + +#include "pdp.h" +#include <math.h> + +#define MAX_TABLES 6 +static unsigned int fastrand_val; +#define inline_fastrand() (fastrand_val=fastrand_val*1103515245+12345) + +static char *pdp_transform_version = "pdp_transform: version 0.1, port of transform from EffecTV by clifford smith, adapted by ydegoyon@free.fr "; + +typedef struct pdp_transform_struct +{ + t_object x_obj; + t_float x_f; + + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_outlet *x_outlet0; + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + t_int **x_table_list; // mapping tables + t_int **x_table_list_u; // mapping tables + t_int x_table; // current table + t_int x_t; + + +} t_pdp_transform; + +static void pdp_transform_table(t_pdp_transform *x, t_floatarg ftable ) +{ + if ( ( ftable >= 0 ) && ( ftable < MAX_TABLES ) ) + { + x->x_table = ftable; + } +} + +static int pdp_transform_map_from_table(t_pdp_transform *x, t_int px, t_int py, t_int t) +{ + int xd,yd; + + yd = py + (inline_fastrand() >> 30)-2; + xd = px + (inline_fastrand() >> 30)-2; + if (xd > x->x_vwidth) { + xd-=1; + } + return (xd+yd*x->x_vwidth); +} + +static int pdp_transform_map_from_table_u(t_pdp_transform *x, t_int px, t_int py, t_int t) +{ + int xd,yd; + + yd = py + (inline_fastrand() >> 30)-2; + xd = px + (inline_fastrand() >> 30)-2; + if (xd > x->x_vwidth) { + xd-=1; + } + return ((xd>>1)+(yd>>1)*(x->x_vwidth>>1)); +} + +static void pdp_transform_square_table_init(t_pdp_transform *x) +{ + const int size = 16; + t_int px, py, tx, ty; + + for(py=0; py<x->x_vheight; py++) + { + ty = py % size - size / 2; + if((py/size)%2) + { + ty = py - ty; + } + else + { + ty = py + ty; + } + if(ty<0) ty = 0; + if(ty>=x->x_vheight) + { + ty = x->x_vheight - 1; + } + for(px=0; px<x->x_vwidth; px++) + { + tx = px % size - size / 2; + if((px/size)%2) + { + tx = px - tx; + } + else + { + tx = px + tx; + } + if(tx<0) tx = 0; + if(tx>=x->x_vwidth) tx = x->x_vwidth - 1; + x->x_table_list[5][px+py*x->x_vwidth] = ty*x->x_vwidth+tx; + x->x_table_list_u[5][px+py*x->x_vwidth] = (ty>>1)*(x->x_vwidth>>1)+(tx>>1); + } + } +} + +static void pdp_transform_init_tables(t_pdp_transform *x) +{ + t_int px, py; + + for (py=0;py<x->x_vheight;py++) + { + for (px=0;px<x->x_vwidth;px++) + { + x->x_table_list[0][px+py*x->x_vwidth] = px+py*x->x_vwidth; + x->x_table_list[1][px+py*x->x_vwidth] = (x->x_vwidth-1-px)+py*x->x_vwidth; + x->x_table_list[2][px+py*x->x_vwidth] = px+(x->x_vheight-1-py)*x->x_vwidth; + x->x_table_list[3][px+py*x->x_vwidth] = (x->x_vwidth-1-px)+(x->x_vheight-1-py)*x->x_vwidth; + x->x_table_list_u[0][px+py*x->x_vwidth]= (px>>1)+((py*x->x_vwidth)>>2); + x->x_table_list_u[1][px+py*x->x_vwidth] = (x->x_vwidth>>1)-1-(px>>1)+(py>>1)*(x->x_vwidth>>1); + x->x_table_list_u[2][px+py*x->x_vwidth] = (px>>1)+((x->x_vheight>>1)-1-(py>>1))*(x->x_vwidth>>1); + x->x_table_list_u[3][px+py*x->x_vwidth] = ((x->x_vwidth-1-px)>>1)+((x->x_vheight-1-py)>>1)*(x->x_vwidth>>1); + x->x_table_list[4][px+py*x->x_vwidth] = -2; /* Function */ + x->x_table_list_u[4][px+py*x->x_vwidth] = -2; /* Function */ + } + } + pdp_transform_square_table_init(x); +} + +static void pdp_transform_free_ressources(t_pdp_transform *x) +{ + int i; + + // free tables + for(i=0;i<MAX_TABLES;i++) + { + if ( x->x_table_list[i] ) freebytes( x->x_table_list[i], x->x_vsize*sizeof(int) ); + if ( x->x_table_list_u[i] ) freebytes( x->x_table_list_u[i], x->x_vsize*sizeof(int) ); + } +} + +static void pdp_transform_allocate(t_pdp_transform *x) +{ + int i; + + // allocate tables + for(i=0;i<MAX_TABLES;i++) + { + x->x_table_list[i] = (t_int *) getbytes( x->x_vsize*sizeof(int) ); + x->x_table_list_u[i] = (t_int *) getbytes( x->x_vsize*sizeof(int) ); + } +} + +static void pdp_transform_process_yv12(t_pdp_transform *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + t_int i, iu; + t_int px, py; + t_int d, o, du=0, ou; + short int *pY, *pU, *pV, *pnY, *pnU, *pnV; + + /* allocate all ressources */ + if ( ((int)header->info.image.width != x->x_vwidth) || + ((int)header->info.image.height != x->x_vheight) ) + { + pdp_transform_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_transform_allocate(x); + post( "pdp_transform : reallocated buffers" ); + pdp_transform_init_tables(x); + post( "pdp_transform : initialized tables" ); + } + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + x->x_t++; + + pnY = newdata; + pnV = newdata+x->x_vsize; + pnU = newdata+x->x_vsize+(x->x_vsize>>2); + iu = 0; + for(py=0; py<x->x_vheight; py++) + { + for(px=0; px<x->x_vwidth; px++) + { + d = x->x_table_list[x->x_table][py*x->x_vwidth+px]; + if ( (px%2==0) && (py%2==0) ) + { + du = x->x_table_list_u[x->x_table][py*x->x_vwidth+px]; + iu++; + } + if ( d==-2 ) + { + d = pdp_transform_map_from_table( x, px, py, x->x_t ); + du = pdp_transform_map_from_table_u( x, px, py, x->x_t ); + } + if ( d < 0) { + o = 0; + ou = 0; + } else { + o = d; + ou = du; + } + *pnY++ = *(data+o); + if ( (px%2==0) && (py%2==0) ) + { + *pnV++ = *(data+x->x_vsize+ou); + *pnU++ = *(data+x->x_vsize+(x->x_vsize>>2)+ou); + } + } + } + + return; +} + +static void pdp_transform_sendpacket(t_pdp_transform *x) +{ + /* delete source packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_transform_process(t_pdp_transform *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_transform_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding) + { + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_transform_process_yv12, pdp_transform_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + + default: + /* don't know the type, so dont pdp_transform_process */ + break; + + } + } + +} + +static void pdp_transform_input_0(t_pdp_transform *x, t_symbol *s, t_floatarg f) +{ + + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_transform_process(x); + + } + +} + +static void pdp_transform_free(t_pdp_transform *x) +{ + int i; + + pdp_transform_free_ressources(x); + if ( x->x_table_list ) freebytes(x->x_table_list, MAX_TABLES * sizeof(int *)); + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); +} + +t_class *pdp_transform_class; + +void *pdp_transform_new(void) +{ + int i; + + t_pdp_transform *x = (t_pdp_transform *)pd_new(pdp_transform_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("table")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_table_list = (t_int **) getbytes(MAX_TABLES * sizeof(int *)); + x->x_table_list_u = (t_int **) getbytes(MAX_TABLES * sizeof(int *)); + x->x_t = 0; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_transform_setup(void) +{ +// post( pdp_transform_version ); + pdp_transform_class = class_new(gensym("pdp_transform"), (t_newmethod)pdp_transform_new, + (t_method)pdp_transform_free, sizeof(t_pdp_transform), 0, A_NULL); + + class_addmethod(pdp_transform_class, (t_method)pdp_transform_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_transform_class, (t_method)pdp_transform_table, gensym("table"), A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_transition.c b/modules/pdp_transition.c new file mode 100644 index 0000000..d186aa0 --- /dev/null +++ b/modules/pdp_transition.c @@ -0,0 +1,787 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is an object allowing transitions between two video sources + * "circle", "wipe", "random", "melt" and "blend" + * Written by Yves Degoyon + */ + +#include "pdp.h" +#include <math.h> + +#define BLEND_MAX 200 + +static char *pdp_transition_version = "pdp_transition: version 0.1, two sources transition, written by Yves Degoyon (ydegoyon@free.fr)"; + +typedef struct pdp_transition_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_packet; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth0; + t_int x_vheight0; + t_int x_vsize0; + + t_int x_vwidth1; + t_int x_vheight1; + t_int x_vsize1; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + t_int x_transition_mode; // 1 : "circle" + t_int x_transition_pending; + + t_int x_current_source; + t_int x_target_source; + + t_int x_pos; // current position for transition + t_int x_inc; // increment for various mode + t_int x_rand;// randomizing argument + +} t_pdp_transition; + +static t_int pdp_transition_min( t_int a, t_int b ) +{ + if ( a == 0 ) return b; + if ( b == 0 ) return a; + if ( a < b ) return a; + else return b; +} + +static void pdp_transition_circle(t_pdp_transition *x, t_floatarg finc ) +{ + if ( x->x_transition_pending ) + { + post ( "pdp_transition : a transition is already pending, retry later...." ); + return; + } + if ( (int) finc > 0 ) + { + x->x_inc = (int)finc; + } + x->x_transition_mode = 1; + x->x_transition_pending = 1; +} + +static void pdp_transition_wipelr(t_pdp_transition *x, t_floatarg finc, t_floatarg frand ) +{ + if ( x->x_transition_pending ) + { + post ( "pdp_transition : a transition is already pending, retry later...." ); + return; + } + if ( (int) finc > 0 ) + { + x->x_inc = (int)finc; + } + if ( (int) frand >= 0 ) + { + x->x_rand = (int)frand; + } + x->x_transition_mode = 2; + x->x_transition_pending = 1; +} + +static void pdp_transition_wiperl(t_pdp_transition *x, t_floatarg finc, t_floatarg frand ) +{ + if ( x->x_transition_pending ) + { + post ( "pdp_transition : a transition is already pending, retry later...." ); + return; + } + if ( (int) finc > 0 ) + { + x->x_inc = (int)finc; + } + if ( (int) frand >= 0 ) + { + x->x_rand = (int)frand; + } + x->x_transition_mode = 3; + x->x_transition_pending = 1; + x->x_pos = x->x_vwidth; +} + +static void pdp_transition_mwipe(t_pdp_transition *x, t_floatarg finc, t_floatarg frand ) +{ + if ( x->x_transition_pending ) + { + post ( "pdp_transition : a transition is already pending, retry later...." ); + return; + } + if ( (int) finc > 0 ) + { + x->x_inc = (int)finc; + } + if ( (int) frand >= 0 ) + { + x->x_rand = (int)frand; + } + x->x_transition_mode = 4; + x->x_transition_pending = 1; + x->x_pos = 0; +} + +static void pdp_transition_wipetd(t_pdp_transition *x, t_floatarg finc, t_floatarg frand ) +{ + if ( x->x_transition_pending ) + { + post ( "pdp_transition : a transition is already pending, retry later...." ); + return; + } + if ( (int) finc > 0 ) + { + x->x_inc = (int)finc; + } + if ( (int) frand >= 0 ) + { + x->x_rand = (int)frand; + } + x->x_transition_mode = 5; + x->x_transition_pending = 1; + x->x_pos = 0; +} + +static void pdp_transition_wipebu(t_pdp_transition *x, t_floatarg finc, t_floatarg frand ) +{ + if ( x->x_transition_pending ) + { + post ( "pdp_transition : a transition is already pending, retry later...." ); + return; + } + if ( (int) finc > 0 ) + { + x->x_inc = (int)finc; + } + if ( (int) frand >= 0 ) + { + x->x_rand = (int)frand; + } + x->x_transition_mode = 6; + x->x_transition_pending = 1; + x->x_pos = x->x_vheight; +} + +static void pdp_transition_random(t_pdp_transition *x, t_floatarg finc ) +{ + if ( x->x_transition_pending ) + { + post ( "pdp_transition : a transition is already pending, retry later...." ); + return; + } + if ( (int) finc > 0 ) + { + x->x_inc = (int)finc; + } + x->x_transition_mode = 7; + x->x_transition_pending = 1; + x->x_rand = x->x_vsize/(x->x_inc*(pdp_transition_min( x->x_vwidth, 100 ))); +} + +static void pdp_transition_melt(t_pdp_transition *x, t_floatarg finc ) +{ + if ( x->x_transition_pending ) + { + post ( "pdp_transition : a transition is already pending, retry later...." ); + return; + } + if ( (int) finc > 0 ) + { + x->x_inc = (int)finc; + } + x->x_transition_mode = 8; + x->x_transition_pending = 1; + x->x_rand = 20; +} + +static void pdp_transition_blend(t_pdp_transition *x, t_floatarg finc, t_floatarg frand ) +{ + if ( x->x_transition_pending ) + { + post ( "pdp_transition : a transition is already pending, retry later...." ); + return; + } + if ( (int) finc > 0 ) + { + x->x_inc = (int)finc; + } + if ( (int) frand >= 0 ) + { + x->x_rand = (int)frand; + } + x->x_transition_mode = 9; + x->x_transition_pending = 1; + x->x_pos = 0; +} + +static void pdp_transition_process_yv12(t_pdp_transition *x) +{ + t_pdp *header0 = pdp_packet_header(x->x_packet0); + short int *data0 = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *header1 = pdp_packet_header(x->x_packet1); + short int *data1 = (short int *)pdp_packet_data(x->x_packet1); + t_pdp *header; + short int *data; + t_int tsource, cx=0, cy=0; + t_int px, py, rvalue=0; + t_float factor; + int i; + short int *poY, *poV, *poU, *p0Y, *p0V, *p0U, *p1Y, *p1V, *p1U; + + if ( header0 ) + { + x->x_vwidth0 = header0->info.image.width; + x->x_vheight0 = header0->info.image.height; + x->x_vsize0 = x->x_vwidth0*x->x_vheight0; + } + else + { + x->x_vwidth0 = x->x_vheight0 = x->x_vsize0 = 0; + } + + if ( header1 ) + { + x->x_vwidth1 = header1->info.image.width; + x->x_vheight1 = header1->info.image.height; + x->x_vsize1 = x->x_vwidth1*x->x_vheight1; + } + else + { + x->x_vwidth1 = x->x_vheight1 = x->x_vsize1 = 0; + } + + x->x_vwidth = pdp_transition_min( x->x_vwidth0 , x->x_vwidth1); + x->x_vheight = pdp_transition_min( x->x_vheight0 , x->x_vheight1); + x->x_vsize = x->x_vwidth*x->x_vheight; + // post( "pdp_transition : resulting frame : %dx%d", x->x_vwidth, x->x_vheight ); + + x->x_packet = pdp_packet_new_image_YCrCb( x->x_vwidth, x->x_vheight ); + + header = pdp_packet_header(x->x_packet); + data = (short int *)pdp_packet_data(x->x_packet); + + header->info.image.encoding = PDP_IMAGE_YV12; + header->info.image.width = x->x_vwidth; + header->info.image.height = x->x_vheight; + + poY = data; + poV = data+x->x_vsize; + poU = data+x->x_vsize+(x->x_vsize>>2); + if ( x->x_current_source == 0 ) + { + if ( x->x_vsize0 > 0 ) memcpy( data, data0, (x->x_vsize+(x->x_vsize>>1))<<1 ); + p0Y = data0; + p0V = data0+x->x_vsize0; + p0U = data0+x->x_vsize0+(x->x_vsize0>>2); + p1Y = data1; + p1V = data1+x->x_vsize1; + p1U = data1+x->x_vsize1+(x->x_vsize1>>2); + } + else + { + if ( x->x_vsize1 > 0 ) memcpy( data, data1, (x->x_vsize+(x->x_vsize>>1))<<1 ); + p0Y = data1; + p0V = data1+x->x_vsize0; + p0U = data1+x->x_vsize0+(x->x_vsize0>>2); + p1Y = data0; + p1V = data0+x->x_vsize1; + p1U = data0+x->x_vsize1+(x->x_vsize1>>2); + } + if ( ( x->x_transition_pending ) && ( x->x_vsize0 > 0 ) && ( x->x_vsize1 > 0 ) ) + { + switch ( x->x_transition_mode ) + { + case 1: // circle + for ( py=0; py<x->x_vheight; py++ ) + { + for ( px=0; px<x->x_vwidth; px++ ) + { + cx = px-(x->x_vwidth/2); + cy = py-(x->x_vheight/2); + if ( cx*cx + cy*cy < x->x_pos*x->x_pos ) + { + *(poY) = *(p1Y); + *(poU) = *(p1U); + *(poV) = *(p1V); + } + poY++; p1Y++; + if ( (px%2==0) && (py%2==0) ) + { + poU++; poV++; + p1U++; p1V++; + } + } + } + if ( ( x->x_pos > (x->x_vwidth/2) ) && ( x->x_pos > (x->x_vheight/2) ) ) + { + post( "pdp_transition : circle transition finished" ); + x->x_transition_pending = 0; + x->x_transition_mode = 0; + tsource = x->x_current_source; + x->x_current_source = x->x_target_source; + x->x_target_source = tsource; + x->x_pos = 0; + } + x->x_pos += x->x_inc; + break; + + case 2: // wipelr + for ( py=0; py<x->x_vheight; py++ ) + { + rvalue = (int)(((float) x->x_rand )*( (float)random() ) / RAND_MAX); + for ( px=0; px<x->x_vwidth; px++ ) + { + if ( px <= x->x_pos + rvalue ) + { + *(poY) = *(p1Y); + *(poU) = *(p1U); + *(poV) = *(p1V); + } + poY++; p1Y++; + if ( (px%2==0) && (py%2==0) ) + { + poU++; poV++; + p1U++; p1V++; + } + } + } + if ( x->x_pos > x->x_vwidth ) + { + post( "pdp_transition : wipelr transition finished" ); + x->x_transition_pending = 0; + x->x_transition_mode = 0; + tsource = x->x_current_source; + x->x_current_source = x->x_target_source; + x->x_target_source = tsource; + x->x_pos = 0; + } + x->x_pos += x->x_inc; + break; + + case 3: // wiperl + for ( py=0; py<x->x_vheight; py++ ) + { + rvalue = (int)(((float) x->x_rand )*( (float)random() ) / RAND_MAX); + for ( px=0; px<x->x_vwidth; px++ ) + { + if ( px >= x->x_pos + rvalue ) + { + *(poY) = *(p1Y); + *(poU) = *(p1U); + *(poV) = *(p1V); + } + poY++; p1Y++; + if ( (px%2==0) && (py%2==0) ) + { + poU++; poV++; + p1U++; p1V++; + } + } + } + if ( x->x_pos <= 0 ) + { + post( "pdp_transition : wiperl transition finished" ); + x->x_transition_pending = 0; + x->x_transition_mode = 0; + tsource = x->x_current_source; + x->x_current_source = x->x_target_source; + x->x_target_source = tsource; + x->x_pos = 0; + } + x->x_pos -= x->x_inc; + break; + + case 4: // mwipe + for ( px=0; px<x->x_vwidth; px++ ) + { + rvalue = (int)(((float) x->x_rand )*( (float)random() ) / RAND_MAX); + for ( py=0; py<x->x_vheight; py++ ) + { + if ( py <= x->x_pos + rvalue ) + { + *(poY) = *(p1Y); + *(poU) = *(p1U); + *(poV) = *(p1V); + } + poY++; p1Y++; + if ( (px%2==0) && (py%2==0) ) + { + poU++; poV++; + p1U++; p1V++; + } + } + } + if ( x->x_pos >= x->x_vheight ) + { + post( "pdp_transition : mwipe transition finished" ); + x->x_transition_pending = 0; + x->x_transition_mode = 0; + tsource = x->x_current_source; + x->x_current_source = x->x_target_source; + x->x_target_source = tsource; + x->x_pos = 0; + } + x->x_pos += x->x_inc; + break; + + case 5: // wipetd + for ( px=0; px<x->x_vwidth; px++ ) + { + rvalue = (int)(((float) x->x_rand )*( (float)random() ) / RAND_MAX); + for ( py=0; py<x->x_vheight; py++ ) + { + if ( py <= x->x_pos + rvalue ) + { + *(poY+py*x->x_vwidth+px) = *(p1Y+py*x->x_vwidth1+px); + *(poU+(py>>1)*(x->x_vwidth>>1)+(px>>1)) = + *(p1U+(py>>1)*(x->x_vwidth1>>1)+(px>>1)); + *(poV+(py>>1)*(x->x_vwidth>>1)+(px>>1)) = + *(p1V+(py>>1)*(x->x_vwidth1>>1)+(px>>1)); + } + } + } + if ( x->x_pos >= x->x_vheight ) + { + post( "pdp_transition : wipetd transition finished" ); + x->x_transition_pending = 0; + x->x_transition_mode = 0; + tsource = x->x_current_source; + x->x_current_source = x->x_target_source; + x->x_target_source = tsource; + x->x_pos = 0; + } + x->x_pos += x->x_inc; + break; + + case 6: // wipebu + for ( px=0; px<x->x_vwidth; px++ ) + { + rvalue = (int)(((float) x->x_rand )*( (float)random() ) / RAND_MAX); + for ( py=0; py<x->x_vheight; py++ ) + { + if ( py >= x->x_pos + rvalue ) + { + *(poY+py*x->x_vwidth+px) = *(p1Y+py*x->x_vwidth1+px); + *(poU+(py>>1)*(x->x_vwidth>>1)+(px>>1)) = + *(p1U+(py>>1)*(x->x_vwidth1>>1)+(px>>1)); + *(poV+(py>>1)*(x->x_vwidth>>1)+(px>>1)) = + *(p1V+(py>>1)*(x->x_vwidth1>>1)+(px>>1)); + } + } + } + if ( x->x_pos <= 0 ) + { + post( "pdp_transition : wipebu transition finished" ); + x->x_transition_pending = 0; + x->x_transition_mode = 0; + tsource = x->x_current_source; + x->x_current_source = x->x_target_source; + x->x_target_source = tsource; + x->x_pos = 0; + } + x->x_pos -= x->x_inc; + break; + + case 7: // random + for ( px=0; px<x->x_vwidth; px++ ) + { + for ( py=0; py<x->x_vheight; py++ ) + { + rvalue = (int)(((float) x->x_rand )*( (float)random() ) / RAND_MAX); + if ( rvalue <= x->x_pos ) + { + *(poY+py*x->x_vwidth+px) = *(p1Y+py*x->x_vwidth1+px); + *(poU+(py>>1)*(x->x_vwidth>>1)+(px>>1)) = + *(p1U+(py>>1)*(x->x_vwidth1>>1)+(px>>1)); + *(poV+(py>>1)*(x->x_vwidth>>1)+(px>>1)) = + *(p1V+(py>>1)*(x->x_vwidth1>>1)+(px>>1)); + } + } + } + if ( x->x_pos >= x->x_rand ) + { + post( "pdp_transition : wipebu transition finished" ); + x->x_transition_pending = 0; + x->x_transition_mode = 0; + tsource = x->x_current_source; + x->x_current_source = x->x_target_source; + x->x_target_source = tsource; + x->x_pos = 0; + } + x->x_pos += x->x_inc; + break; + + case 8: // melt + for ( px=0; px<x->x_vwidth; px++ ) + { + rvalue = (int)(((float) x->x_rand )*( (float)random() ) / RAND_MAX)+(abs(px-x->x_vwidth/2)/5); + for ( py=0; py<x->x_vheight; py++ ) + { + if ( py <= x->x_pos + rvalue ) + { + *(poY+py*x->x_vwidth+px) = 0; + *(poU+(py>>1)*(x->x_vwidth>>1)+(px>>1)) = 0; + *(poV+(py>>1)*(x->x_vwidth>>1)+(px>>1)) = 0; + } + } + } + if ( x->x_pos >= x->x_vheight ) + { + post( "pdp_transition : melt transition finished" ); + x->x_transition_pending = 0; + x->x_transition_mode = 0; + tsource = x->x_current_source; + x->x_current_source = x->x_target_source; + x->x_target_source = tsource; + x->x_pos = 0; + } + x->x_pos += x->x_inc; + break; + + case 9: // blend + for ( px=0; px<x->x_vwidth; px++ ) + { + for ( py=0; py<x->x_vheight; py++ ) + { + rvalue = (((float) x->x_rand )*( (float)random() ) / RAND_MAX); + factor = ( (float) x->x_pos + rvalue ) / BLEND_MAX; + *(poY+py*x->x_vwidth+px) = + (int)((1.0-factor)*(*(poY+py*x->x_vwidth+px)) + + factor*(*(p1Y+py*x->x_vwidth1+px))); + *(poU+(py>>1)*(x->x_vwidth>>1)+(px>>1)) = + (int)((1.0-factor)*(*(poU+(py>>1)*(x->x_vwidth>>1)+(px>>1))) + + factor*(*(p1U+(py>>1)*(x->x_vwidth1>>1)+(px>>1)))); + *(poV+(py>>1)*(x->x_vwidth>>1)+(px>>1)) = + (int)((1.0-factor)*(*(poV+(py>>1)*(x->x_vwidth>>1)+(px>>1))) + + factor*(*(p1V+(py>>1)*(x->x_vwidth1>>1)+(px>>1)))); + } + } + if ( x->x_pos >= BLEND_MAX ) + { + post( "pdp_transition : blend transition finished" ); + x->x_transition_pending = 0; + x->x_transition_mode = 0; + tsource = x->x_current_source; + x->x_current_source = x->x_target_source; + x->x_target_source = tsource; + x->x_pos = 0; + } + x->x_pos += x->x_inc; + break; + + default: + break; + } + } + + return; +} + +static void pdp_transition_sendpacket0(t_pdp_transition *x) +{ + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet); +} + +static void pdp_transition_sendpacket1(t_pdp_transition *x) +{ + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet); +} + +static void pdp_transition_process0(t_pdp_transition *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_transition_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + pdp_queue_add(x, pdp_transition_process_yv12, pdp_transition_sendpacket0, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + break; + + default: + /* don't know the type, so dont pdp_transition_process */ + break; + + } + } +} + +static void pdp_transition_process1(t_pdp_transition *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet1)) + && (PDP_IMAGE == header->type)){ + + /* pdp_transition_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet1)->info.image.encoding){ + + case PDP_IMAGE_YV12: + pdp_queue_add(x, pdp_transition_process_yv12, pdp_transition_sendpacket1, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + break; + + default: + /* don't know the type, so dont pdp_transition_process */ + break; + + } + } +} + +static void pdp_transition_input_0(t_pdp_transition *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + { + /* release the packet */ + if ( x->x_packet0 != -1 ) + { + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + } + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + } + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_transition_process0(x); + + } +} + +static void pdp_transition_input_1(t_pdp_transition *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + { + /* release the packet */ + if ( x->x_packet1 != -1 ) + { + pdp_packet_mark_unused(x->x_packet1); + x->x_packet1 = -1; + } + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet1, (int)f, pdp_gensym("image/YCrCb/*") ); + } + + if ((s == gensym("process")) && (-1 != x->x_packet1) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_transition_process1(x); + + } +} + +static void pdp_transition_free(t_pdp_transition *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); + pdp_packet_mark_unused(x->x_packet1); +} + +t_class *pdp_transition_class; + +void *pdp_transition_new(void) +{ + int i; + + t_pdp_transition *x = (t_pdp_transition *)pd_new(pdp_transition_class); + + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("pdp"), gensym("pdp1")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("pdp"), gensym("pdp2")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_packet = -1; + x->x_queue_id = -1; + + x->x_transition_mode = 0; + x->x_transition_pending = 0; + + x->x_current_source = 0; + x->x_target_source = 1; + + x->x_pos = 0; + x->x_inc = 1; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_transition_setup(void) +{ + post( pdp_transition_version ); + pdp_transition_class = class_new(gensym("pdp_transition"), (t_newmethod)pdp_transition_new, + (t_method)pdp_transition_free, sizeof(t_pdp_transition), 0, A_NULL); + + class_addmethod(pdp_transition_class, (t_method)pdp_transition_input_0, gensym("pdp1"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_transition_class, (t_method)pdp_transition_input_1, gensym("pdp2"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_transition_class, (t_method)pdp_transition_circle, gensym("circle"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_transition_class, (t_method)pdp_transition_wipelr, gensym("wipelr"), A_DEFFLOAT, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_transition_class, (t_method)pdp_transition_wiperl, gensym("wiperl"), A_DEFFLOAT, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_transition_class, (t_method)pdp_transition_mwipe, gensym("mwipe"), A_DEFFLOAT, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_transition_class, (t_method)pdp_transition_wipetd, gensym("wipetd"), A_DEFFLOAT, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_transition_class, (t_method)pdp_transition_wipebu, gensym("wipebu"), A_DEFFLOAT, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_transition_class, (t_method)pdp_transition_random, gensym("random"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_transition_class, (t_method)pdp_transition_melt, gensym("melt"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_transition_class, (t_method)pdp_transition_blend, gensym("blend"), A_DEFFLOAT, A_DEFFLOAT, A_NULL); + + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_underwatch.c b/modules/pdp_underwatch.c new file mode 100644 index 0000000..887be29 --- /dev/null +++ b/modules/pdp_underwatch.c @@ -0,0 +1,244 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is an adaptation of 1d effect from effectv + * but i found it funnier to rename it as underwatch + * Originally written by Fukuchi Kentaro & others + * Pd-fication by Yves Degoyon + */ + + + +#include "pdp.h" +#include <math.h> + +static char *pdp_underwatch_version = "pdp_underwatch: version 0.1, inspired by 1d from effectv( Fukuchi Kentaro ) adapted by Yves Degoyon (ydegoyon@free.fr)"; + +typedef struct pdp_underwatch_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + t_int x_line; + t_int x_sline; + t_int x_sheight; + t_int x_prevline; + t_int x_prevsline; + t_int x_prevsheight; + t_int x_stripsize; + +} t_pdp_underwatch; + +static void pdp_underwatch_setparams(t_pdp_underwatch *x) +{ + int snext; + + x->x_sline = x->x_line; + snext = (x->x_line + 1); + x->x_sheight = snext - x->x_sline; +} + +static void pdp_underwatch_process_yv12(t_pdp_underwatch *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + short int *p=0, *po=0, *pu=0, *pv=0, *pou=0, *pov=0; + int i; + + unsigned int u_offset; + unsigned int v_offset; + unsigned int totnbpixels; + int px, py, pd, t; + + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + + u_offset = x->x_vsize; + v_offset = x->x_vsize + (x->x_vsize>>2); + totnbpixels = x->x_vsize + (x->x_vsize>>1); + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + /* copy region */ + for (pd=0; pd<x->x_stripsize; pd++ ) + { + p = newdata+x->x_vwidth*x->x_sline; + pu = newdata+((x->x_vwidth*x->x_sline)>>2)+x->x_vsize; + pv = newdata+((x->x_vwidth*x->x_sline)>>2)+x->x_vsize+(x->x_vsize>>2); + po = data+x->x_vwidth*x->x_line; + pou = data+((x->x_vwidth*x->x_line)>>2)+x->x_vsize; + pov = data+((x->x_vwidth*x->x_line)>>2)+x->x_vsize+(x->x_vsize>>2); + // post("INIT : pov=%x limit=%x", pov, data+x->x_vsize+(x->x_vsize>>1) ); + for(py=0; py<=x->x_sheight; py++) + { + for(px=0; px<x->x_vwidth; px++) + { + if( po < data+x->x_vsize+(x->x_vsize>>1) ) *p = *po; + if( pou < data+x->x_vsize+(x->x_vsize>>1) ) *(pu) = *(pou); + if( pov < data+x->x_vsize+(x->x_vsize>>1) ) *(pv) = *(pov); + p++; + po++; + if ( ((px+1)%2==0) && ((py+1)%2==0) ) { pu++; pv++; pou++; pov++; }; + } + } + x->x_prevline = x->x_line; + x->x_prevsline = x->x_sline; + x->x_prevsheight = x->x_sheight; + x->x_line=(x->x_line+1)%(x->x_vheight); + pdp_underwatch_setparams(x); + //p = newdata + x->x_vwidth * x->x_sline+1; + //for(px=0; px<x->x_vwidth; px++) + //{ + // p[px] = 0xff00; + //} + } + + return; +} + +static void pdp_underwatch_sendpacket(t_pdp_underwatch *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_underwatch_process(t_pdp_underwatch *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_underwatch_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_underwatch_process_yv12, pdp_underwatch_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // pdp_underwatch_process_packet(x); + break; + + default: + /* don't know the type, so dont pdp_underwatch_process */ + break; + + } + } +} + +static void pdp_underwatch_stripsize(t_pdp_underwatch *x, t_floatarg fstripsize ) +{ + if ( fstripsize>0 && fstripsize<x->x_vheight ) + { + x->x_stripsize = (int)fstripsize; + } +} + +static void pdp_underwatch_input_0(t_pdp_underwatch *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)) + { + /* add the process method and callback to the process queue */ + pdp_underwatch_process(x); + } +} + +static void pdp_underwatch_free(t_pdp_underwatch *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); +} + +t_class *pdp_underwatch_class; + +void *pdp_underwatch_new(void) +{ + int i; + + t_pdp_underwatch *x = (t_pdp_underwatch *)pd_new(pdp_underwatch_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("stripsize")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_line = 0; + pdp_underwatch_setparams(x); + x->x_prevline = 0; + x->x_prevsline = 0; + x->x_prevsheight = 0; + x->x_stripsize = 10; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_underwatch_setup(void) +{ +// post( pdp_underwatch_version ); + pdp_underwatch_class = class_new(gensym("pdp_underwatch"), (t_newmethod)pdp_underwatch_new, + (t_method)pdp_underwatch_free, sizeof(t_pdp_underwatch), 0, A_NULL); + + class_addmethod(pdp_underwatch_class, (t_method)pdp_underwatch_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_underwatch_class, (t_method)pdp_underwatch_stripsize, gensym("stripsize"), A_FLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_vertigo.c b/modules/pdp_vertigo.c new file mode 100644 index 0000000..b6f4e37 --- /dev/null +++ b/modules/pdp_vertigo.c @@ -0,0 +1,349 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is an adaptation of lens effect from effectv + * Originally written by Fukuchi Kentaro & others + * Pd-fication by Yves Degoyon + */ + + + +#include "pdp.h" +#include <math.h> + +static char *pdp_vertigo_version = "pdp_vertigo: version 0.1, port of vertigo from effectv( Fukuchi Kentaro ) adapted by Yves Degoyon (ydegoyon@free.fr)"; + +typedef struct pdp_vertigo_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + short int *x_buffer; + short int *x_current_buffer; + short int *x_alt_buffer; + t_int x_dx; + t_int x_dy; + t_int x_sx; + t_int x_sy; + double x_phase; + double x_phase_increment; + double x_zoomrate; + + +} t_pdp_vertigo; + +static void pdp_vertigo_increment(t_pdp_vertigo *x, t_floatarg fincrement ) +{ + x->x_phase_increment = fincrement; +} + +static void pdp_vertigo_zoomrate(t_pdp_vertigo *x, t_floatarg fzoomrate ) +{ + x->x_zoomrate = (int)fzoomrate; +} + +static void pdp_vertigo_allocate(t_pdp_vertigo *x, t_floatarg fnewsize ) +{ + t_int nsize = (int) fnewsize; + + if ( x->x_buffer ) freebytes( x->x_buffer, 2*((x->x_vsize + (x->x_vsize>>1))<<1) ); + x->x_buffer = (short int *) getbytes( 2*(( nsize + (nsize>>1))<<1) ); + if ( x->x_buffer ) + { + bzero( x->x_buffer, 2*((nsize + (nsize>>1))<<1) ); + x->x_current_buffer = x->x_buffer; + x->x_alt_buffer = x->x_buffer + (nsize + (nsize>>1)); + } + x->x_phase = 0; +} + +static void pdp_vertigo_set_params(t_pdp_vertigo *x) +{ + double vx, vy; + double t; + double X, Y; + double dizz; + + dizz = sin(x->x_phase) * 10 + sin(x->x_phase*1.9+5) * 5; + + X = x->x_vwidth / 2; + Y = x->x_vheight / 2; + t = (X*X + Y*Y) * x->x_zoomrate; + if( x->x_vwidth > x->x_vheight ) + { + if(dizz >= 0) + { + if(dizz > X) dizz = X; + vx = (X*(X-dizz) + Y*Y) / t; + } + else + { + if(dizz < -X) dizz = -X; + vx = (X*(X+dizz) + Y*Y) / t; + } + vy = (dizz*Y) / t; + } + else + { + if(dizz >= 0) + { + if(dizz > Y) dizz = Y; + vx = (X*X + Y*(Y-dizz)) / t; + } + else + { + if(dizz < -Y) dizz = -Y; + vx = (X*X + Y*(Y+dizz)) / t; + } + vy = (dizz*X) / t; + } + x->x_dx = vx * 65536; + x->x_dy = vy * 65536; + x->x_sx = (-vx * X + vy * Y + X + cos(x->x_phase*5) * 2) * 65536; + x->x_sy = (-vx * Y - vy * X + Y + sin(x->x_phase*6) * 2) * 65536; + + x->x_phase += x->x_phase_increment; + if(x->x_phase > 5700000) x->x_phase = 0; +} + + +static void pdp_vertigo_process_yv12(t_pdp_vertigo *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + + unsigned int totalnbpixels; + unsigned int u_offset; + unsigned int v_offset; + unsigned int totnbpixels; + short int *poy, *pou, *pov, *pny, *pnu, *pnv, *pcy, *pcu, *pcv; + int px, py; + short int v; + int ox, oy; + int i, ninc; + + /* allocate all ressources */ + if ( (int)(header->info.image.width*header->info.image.height) != x->x_vsize ) + { + pdp_vertigo_allocate(x, header->info.image.width*header->info.image.height ); + post( "pdp_vertigo : reallocated buffers" ); + } + + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + + totalnbpixels = x->x_vsize; + u_offset = x->x_vsize; + v_offset = x->x_vsize + (x->x_vsize>>2); + totnbpixels = x->x_vsize + (x->x_vsize>>1); + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + pdp_vertigo_set_params(x); + + poy = data; + pou = data + x->x_vsize; + pov = data + x->x_vsize + (x->x_vsize>>2); + pcy = x->x_current_buffer; + pcu = x->x_current_buffer + x->x_vsize; + pcv = x->x_current_buffer + x->x_vsize + (x->x_vsize>>2); + pny = x->x_alt_buffer; + pnu = x->x_alt_buffer + x->x_vsize; + pnv = x->x_alt_buffer + x->x_vsize + (x->x_vsize>>2); + ninc=0; + for(py=x->x_vheight; py>0; py--) + { + ox = x->x_sx; + oy = x->x_sy; + for(px=x->x_vwidth; px>0; px--) + { + if ( pny >= ( x->x_alt_buffer + x->x_vsize ) ) + { + post( "pdp_vertigo : abnormal pointer position : pny=%x, start=%x, size=%x ninc=%d px=%d py=%d", + pny, x->x_alt_buffer , x->x_vsize-1, ninc, px, py ); + break; + } + if ( pnu >= ( x->x_alt_buffer + x->x_vsize + (x->x_vsize>>2) ) ) + { + post( "pdp_vertigo : abnormal pointer position : pnu=%x, start=%x, size=%x ninc=%d px=%d py=%d", + pnu, x->x_alt_buffer + x->x_vsize, (x->x_vsize>>2)-1, ninc, px, py ); + break; + } + if ( pnv >= ( x->x_alt_buffer + x->x_vsize + (x->x_vsize>>1) ) ) + { + post( "pdp_vertigo : abnormal pointer position : pnv=%x, start=%x, size=%x ninc=%d px=%d py=%d", + pnv, x->x_alt_buffer + x->x_vsize + (x->x_vsize>>2), (x->x_vsize>>2)-1, ninc, px, py ); + break; + } + i = (oy>>16)*x->x_vwidth + (ox>>16); + if (i<0) i = 0; + if ( i >= (x->x_vsize + (x->x_vsize>>1)) ) i = (x->x_vsize + (x->x_vsize>>1))-1; + v = pcy[i] & 0xffff; + v = (v * 3) + ((*poy++) & 0xffff); + *pny++ = (v>>2); + if ( (((px+1)%2)==0) && (((py+1)%2)==0) ) + { + ninc++; + v = pcu[(i/4)] & 0xffff; + v = (v * 3) + ((*pou++) & 0xffff); + *pnu++ = (v>>2); + v = pcv[(i/4)] & 0xffff; + v = (v * 3) + ((*pov++) & 0xffff); + *pnv++ = (v>>2); + } + ox += x->x_dx; + oy += x->x_dy; + } + x->x_sx -= x->x_dy; + x->x_sy += x->x_dx; + } + + memcpy(newdata, x->x_alt_buffer, (x->x_vsize + (x->x_vsize>>1))<<1); + + poy = x->x_current_buffer; + x->x_current_buffer = x->x_alt_buffer; + x->x_alt_buffer = poy; + + return; +} + +static void pdp_vertigo_sendpacket(t_pdp_vertigo *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_vertigo_process(t_pdp_vertigo *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_vertigo_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_vertigo_process_yv12, pdp_vertigo_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // pdp_vertigo_process_packet(x); + break; + + default: + /* don't know the type, so dont pdp_vertigo_process */ + break; + + } + } +} + +static void pdp_vertigo_input_0(t_pdp_vertigo *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)) + { + /* add the process method and callback to the process queue */ + pdp_vertigo_process(x); + } +} + +static void pdp_vertigo_free(t_pdp_vertigo *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); + + if ( x->x_buffer ) freebytes( x->x_buffer, 2*((x->x_vsize + (x->x_vsize>>1))<<1) ); +} + +t_class *pdp_vertigo_class; + +void *pdp_vertigo_new(void) +{ + int i; + + t_pdp_vertigo *x = (t_pdp_vertigo *)pd_new(pdp_vertigo_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("increment")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("zoomrate")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_phase = 0; + x->x_buffer = NULL; + x->x_phase_increment = 0.02; + x->x_zoomrate = 1.01; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_vertigo_setup(void) +{ +// post( pdp_vertigo_version ); + pdp_vertigo_class = class_new(gensym("pdp_vertigo"), (t_newmethod)pdp_vertigo_new, + (t_method)pdp_vertigo_free, sizeof(t_pdp_vertigo), 0, A_NULL); + + class_addmethod(pdp_vertigo_class, (t_method)pdp_vertigo_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_vertigo_class, (t_method)pdp_vertigo_increment, gensym("increment"), A_FLOAT, A_NULL); + class_addmethod(pdp_vertigo_class, (t_method)pdp_vertigo_zoomrate, gensym("zoomrate"), A_FLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_warhol.c b/modules/pdp_warhol.c new file mode 100644 index 0000000..8d12f2b --- /dev/null +++ b/modules/pdp_warhol.c @@ -0,0 +1,285 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is an adaptation of warhol effect from effectv + * Copyright (C) 2002 Jun IIO + * Pd-fication by Yves Degoyon + */ + + + +#include "pdp.h" +#include <math.h> + +#define NBCOLORS 9 +static t_int colortable[NBCOLORS] = { + 0x000080, 0x008045, 0x07f0e7, + 0x0000f0, 0x00f07f, 0x037a10, + 0x0023d9, 0x0080f0, 0x083df0 +}; + +static char *pdp_warhol_version = "pdp_warhol: version 0.1, port of warhol from effectv( Fukuchi Kentaro ) adapted by Yves Degoyon (ydegoyon@free.fr)"; + +typedef struct pdp_warhol_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + t_int x_dividerx; + t_int x_dividery; + t_int x_colorindex; + +} t_pdp_warhol; + +static void pdp_warhol_dividerx(t_pdp_warhol *x, t_floatarg fdivider ) +{ + if ( ( fdivider > 1 ) && ( fdivider < x->x_vwidth ) ) + { + x->x_dividerx = (t_int) fdivider; + } +} + +static void pdp_warhol_dividery(t_pdp_warhol *x, t_floatarg fdivider ) +{ + if ( ( fdivider > 1 ) && ( fdivider < x->x_vwidth ) ) + { + x->x_dividery = (t_int) fdivider; + } +} + +static void pdp_warhol_colorindex(t_pdp_warhol *x, t_floatarg findex ) +{ + if ( ( findex >= 0 ) && ( findex < NBCOLORS ) ) + { + x->x_colorindex = (t_int) findex; + } +} + +static void pdp_warhol_v(t_pdp_warhol *x, t_floatarg fv ) +{ + t_int tc; + + if ( ( fv >= 0 ) && ( fv < 255 ) ) + { + tc = colortable[x->x_colorindex] & 0xffff00; + tc = tc | (int) fv; + colortable[x->x_colorindex] = tc; + } +} + +static void pdp_warhol_u(t_pdp_warhol *x, t_floatarg fu ) +{ + t_int tc; + + if ( ( fu >= 0 ) && ( fu < 255 ) ) + { + tc = colortable[x->x_colorindex] & 0xff00ff; + tc = tc | (((int)fu)<<8); + colortable[x->x_colorindex] = tc; + } +} + +static void pdp_warhol_y(t_pdp_warhol *x, t_floatarg fy ) +{ + t_int tc; + + if ( ( fy >= 0 ) && ( fy < 255 ) ) + { + tc = colortable[x->x_colorindex] & 0x00ffff; + tc = tc | (((int)fy)<<16); + colortable[x->x_colorindex] = tc; + } +} + +static void pdp_warhol_process_yv12(t_pdp_warhol *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + short int *pny, *pnu, *pnv; + short int *poy, *pou, *pov; + + short int Y, U, V; + int p, q, px, py, i; + + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + poy = data; + pou = data + x->x_vsize; + pov = data + x->x_vsize + (x->x_vsize>>2); + pny = newdata; + pnu = newdata + x->x_vsize; + pnv = newdata + x->x_vsize + (x->x_vsize>>2); + for (py = 0; py < x->x_vheight; py++) + { + for (px = 0; px < x->x_vwidth; px++) + { + p = (px * x->x_dividerx) % x->x_vwidth; + q = (py * x->x_dividery) % x->x_vheight; + i = ( ((py * x->x_dividery) / x->x_vheight) * x->x_dividery + + ((px * x->x_dividerx) / x->x_vwidth) ) % NBCOLORS; + Y = (colortable[i] >> 16); + U = ( (colortable[i] >> 8) & 0xff ); + V = ( colortable[i] & 0xff); + *pny = ( *(poy + (q*x->x_vwidth+p) ) ) ^ ( Y<<8 ); + pny++; + if ( ( px%2==0 ) && ( py%2==0 ) ) + { + *pnu = ( ( U - 128 << 7 ) ); + *pnv = ( ( V - 128 << 7 ) ); + // *pnu = ( *(pou + ((q>>1)*(x->x_vwidth>>1)+(p>>1)) ) ) ^ ( ( U - 128 << 7 ) ); + // *pnv = ( *(pov + ((q>>1)*(x->x_vwidth>>1)+(p>>1)) ) ) ^ ( ( V - 128 << 7 ) ); + pnu++; pnv++; + } + } + } + + return; +} + +static void pdp_warhol_sendpacket(t_pdp_warhol *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_warhol_process(t_pdp_warhol *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_warhol_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_warhol_process_yv12, pdp_warhol_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + break; + + default: + /* don't know the type, so dont pdp_warhol_process */ + break; + + } + } +} + +static void pdp_warhol_input_0(t_pdp_warhol *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)) + { + /* add the process method and callback to the process queue */ + pdp_warhol_process(x); + } +} + +static void pdp_warhol_free(t_pdp_warhol *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); +} + +t_class *pdp_warhol_class; + +void *pdp_warhol_new(void) +{ + int i; + + t_pdp_warhol *x = (t_pdp_warhol *)pd_new(pdp_warhol_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("dividerx")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("dividery")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("colorindex")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("Y")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("U")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("V")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_dividerx = 3; + x->x_dividery = 3; + x->x_colorindex = 0; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_warhol_setup(void) +{ +// post( pdp_warhol_version ); + pdp_warhol_class = class_new(gensym("pdp_warhol"), (t_newmethod)pdp_warhol_new, + (t_method)pdp_warhol_free, sizeof(t_pdp_warhol), 0, A_NULL); + + class_addmethod(pdp_warhol_class, (t_method)pdp_warhol_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_warhol_class, (t_method)pdp_warhol_dividerx, gensym("dividerx"), A_FLOAT, A_NULL); + class_addmethod(pdp_warhol_class, (t_method)pdp_warhol_dividery, gensym("dividery"), A_FLOAT, A_NULL); + class_addmethod(pdp_warhol_class, (t_method)pdp_warhol_colorindex, gensym("colorindex"), A_FLOAT, A_NULL); + class_addmethod(pdp_warhol_class, (t_method)pdp_warhol_y, gensym("Y"), A_FLOAT, A_NULL); + class_addmethod(pdp_warhol_class, (t_method)pdp_warhol_u, gensym("U"), A_FLOAT, A_NULL); + class_addmethod(pdp_warhol_class, (t_method)pdp_warhol_v, gensym("V"), A_FLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_warp.c b/modules/pdp_warp.c new file mode 100644 index 0000000..e3b4311 --- /dev/null +++ b/modules/pdp_warp.c @@ -0,0 +1,352 @@ +/* + * PiDiP module. + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * + * 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. + * + */ + +/* This object is an adaptation of warp effect from effectv + * Originally written by Fukuchi Kentaro & others + * Pd-fication by Yves Degoyon + */ + + + +#include "pdp.h" +#include <math.h> + +#define CTABLE_SIZE 1024 + +static t_int sintable[CTABLE_SIZE+256]; + +static char *pdp_warp_version = "pdp_warp: version 0.1, port of warp from effectv( Fukuchi Kentaro ) adapted by Yves Degoyon (ydegoyon@free.fr)"; + +typedef struct pdp_warp_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + t_int x_tval; + t_int x_mode; + t_int x_ctable[CTABLE_SIZE]; + t_int *x_disttable; + t_int *x_offstable; + +} t_pdp_warp; + +static void pdp_warp_mode(t_pdp_warp *x, t_floatarg fmode ) +{ + if ( ( fmode == 0 ) || ( fmode == 1 ) ) + { + x->x_mode = (int)fmode; + } +} + +static void pdp_warp_tval(t_pdp_warp *x, t_floatarg ftval ) +{ + x->x_tval = (int)ftval; +} + +static void pdp_warp_init_sin_table(void) +{ + t_int *tptr, *tsinptr; + double i; + + tsinptr = tptr = sintable; + + for (i = 0; i < 1024; i++) + { + *tptr++ = (int) (sin (i*M_PI/512) * 32767); + } + + for (i = 0; i < 256; i++) + { + *tptr++ = *tsinptr++; + } +} + +static void pdp_warp_init_offs_table(t_pdp_warp* x) +{ + int y; + + for (y = 0; y < x->x_vheight; y++) { + x->x_offstable[y] = y * x->x_vwidth; + } +} + +static void pdp_warp_init_dist_table(t_pdp_warp *x) +{ + t_int halfw, halfh, *distptr; + double px,py,m; + + halfw = x->x_vwidth>> 1; + halfh = x->x_vheight >> 1; + + distptr = x->x_disttable; + + m = sqrt ((double)(halfw*halfw + halfh*halfh)); + + for (py = -halfh; py < halfh; py++) + { + for (px= -halfw; px < halfw; px++) + { + *distptr++ = ((int) ( (sqrt (px*px+py*py) * 511.9999) / m)) << 1; + } + } +} + + +static void pdp_warp_free_ressources(t_pdp_warp *x) +{ + if ( x->x_offstable ) freebytes( x->x_offstable, x->x_vheight * sizeof (t_int) ); + if ( x->x_disttable ) freebytes( x->x_disttable, x->x_vwidth * x->x_vheight * sizeof (t_int) ); +} + +static void pdp_warp_allocate(t_pdp_warp *x) +{ + int i; + + x->x_offstable = (t_int*) getbytes ( x->x_vheight * sizeof (t_int) ); + x->x_disttable = (t_int*) getbytes ( x->x_vwidth * x->x_vheight * sizeof (t_int) ); + pdp_warp_init_offs_table(x); + pdp_warp_init_dist_table(x); + +} + +void pdp_warp_do_warp(t_pdp_warp *x, short int* src, short int *dest, int xw, int yw, int cw) +{ + t_int c, i, px, py, dx, dy, dxu, dyu, maxx, maxy; + t_int width, height, skip, *ctptr, *distptr; + short int *destptr, *destptru, *destptrv; + + ctptr = x->x_ctable; + distptr = x->x_disttable; + width = x->x_vwidth; + height = x->x_vheight; + destptr = dest; + destptrv = dest+x->x_vsize; + destptru = dest+x->x_vsize+(x->x_vsize>>2); + skip = 0 ; /* x->x_vwidth*sizeof(short int)/4 - x->x_vwidth; */ + c = 0; + for (px = 0; px < 512; px++) + { + i = (c >> 3) & 0x3FE; + *ctptr++ = ((sintable[i] * yw) >> 15); + *ctptr++ = ((sintable[i+256] * xw) >> 15); + c += cw; + } + maxx = width - 2; maxy = height - 2; + for (py = 0; py < height-1; py++) + { + for (px = 0; px < width; px++) + { + i = *distptr++; + dx = x->x_ctable [i+1] + px; + dxu = x->x_ctable [i+1] + (px>>1); + dy = x->x_ctable [i] + py; + dyu = x->x_ctable [i] + (py>>1); + + if (dx < 0) dx = 0; + else if (dx > maxx) dx = maxx; + if (dy < 0) dy = 0; + else if (dy > maxy) dy = maxy; + if (dxu < 0) dxu = 0; + else if (dxu > (maxx>>1)) dxu = (maxx>>1); + if (dyu < 0) dyu = 0; + else if (dyu > (maxy>>1)) dyu = (maxy>>1); + + *destptr++ = src[dy*x->x_vwidth+dx]; + if ( (py%2==0) && (px%2==0) ) + { + *destptrv++ = src[x->x_vsize+((dyu*x->x_vwidth)>>1)+dxu]; + *destptru++ = src[x->x_vsize+(x->x_vsize>>2)+((dyu*x->x_vwidth)>>1)+dxu]; + } + } + } + +} + +static void pdp_warp_process_yv12(t_pdp_warp *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + int i; + + unsigned int totalnbpixels; + unsigned int u_offset; + unsigned int v_offset; + unsigned int totnbpixels; + + int px, py; + int dx, dy; + int h, v; + int width, height; + int *p, *q, *r; + signed char *vp; + t_int xw, yw, cw; + + /* allocate all ressources */ + if ( (int)(header->info.image.width*header->info.image.height) != x->x_vsize ) + { + pdp_warp_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_warp_allocate(x); + post( "pdp_warp : reallocated buffers" ); + } + + totalnbpixels = x->x_vsize; + u_offset = x->x_vsize; + v_offset = x->x_vsize + (x->x_vsize>>2); + totnbpixels = x->x_vsize + (x->x_vsize>>1); + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + memcpy( newdata, data, (x->x_vsize + (x->x_vsize>>1))<<1 ); + + xw = (int) (sin((x->x_tval+100)*M_PI/128) * 30); + yw = (int) (sin((x->x_tval)*M_PI/256) * -35); + cw = (int) (sin((x->x_tval-70)*M_PI/64) * 50); + xw += (int) (sin((x->x_tval-10)*M_PI/512) * 40); + yw += (int) (sin((x->x_tval+30)*M_PI/512) * 40); + + pdp_warp_do_warp( x, data, newdata, xw, yw, cw); + if ( x->x_mode ) x->x_tval = (x->x_tval+1) &511; + + return; +} + +static void pdp_warp_sendpacket(t_pdp_warp *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_warp_process(t_pdp_warp *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_warp_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_warp_process_yv12, pdp_warp_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + break; + + default: + /* don't know the type, so dont pdp_warp_process */ + break; + + } + } +} + +static void pdp_warp_input_0(t_pdp_warp *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)) + { + /* add the process method and callback to the process queue */ + pdp_warp_process(x); + } +} + +static void pdp_warp_free(t_pdp_warp *x) +{ + int i; + + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); + pdp_warp_free_ressources(x); +} + +t_class *pdp_warp_class; + +void *pdp_warp_new(void) +{ + int i; + + t_pdp_warp *x = (t_pdp_warp *)pd_new(pdp_warp_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("mode")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("tval")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + x->x_mode = 0; + x->x_tval = 0; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_warp_setup(void) +{ +// post( pdp_warp_version ); + pdp_warp_class = class_new(gensym("pdp_warp"), (t_newmethod)pdp_warp_new, + (t_method)pdp_warp_free, sizeof(t_pdp_warp), 0, A_NULL); + + pdp_warp_init_sin_table(); + + class_addmethod(pdp_warp_class, (t_method)pdp_warp_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_warp_class, (t_method)pdp_warp_mode, gensym("mode"), A_FLOAT, A_NULL); + class_addmethod(pdp_warp_class, (t_method)pdp_warp_tval, gensym("tval"), A_FLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_yqt.c b/modules/pdp_yqt.c new file mode 100644 index 0000000..5f0ebbe --- /dev/null +++ b/modules/pdp_yqt.c @@ -0,0 +1,444 @@ +/* + * Pure Data Packet module. + * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org> + * + * 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 "pdp.h" +#include "pdp_llconv.h" +#include <quicktime/lqt.h> +#include <quicktime/colormodels.h> + +#define MIN_AUDIO_INPUT 1024 /* we must have at least n chunks to play a steady sound */ +#define OUTPUT_BUFFER_SIZE 128*1024 /* audio output buffer : 128k */ +#define DECODE_PACKET_SIZE 16*1024 /* size of audio data decoded in one call */ + +typedef struct pdp_yqt_data +{ + short int gain[4]; +} t_pdp_yqt_data; + +typedef struct pdp_yqt_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_outlet *x_outlet1; + t_outlet *x_outlet2; + t_outlet *x_outlet3; /* audio left channel */ + t_outlet *x_outlet4; /* audio right channel */ + + int packet0; + bool initialized; + + unsigned int x_vwidth; + unsigned int x_vheight; + + bool loop; + + unsigned char * qt_rows[3]; + + unsigned char * qt_frame; + quicktime_t *qt; + int qt_cmodel; + + t_int x_audio; /* indicates the existence of an audio track */ + t_int x_audio_channels; /* number of audio channels of first track */ + t_int x_mono; /* indicates a mono audio track */ + t_int x_audio_rate; /* audio rate */ + t_int x_resampling_factor; /* resampling factor */ + + t_float *x_outbuffer; /* buffer to store audio decoded data */ + t_int x_outwriteposition; + t_int x_outreadposition; + t_int x_outunread; + t_int x_outbuffersize; + t_float *x_outl; + t_float *x_outr; + + t_pdp_yqt_data *state_data; + +} t_pdp_yqt; + + + +static void pdp_yqt_close(t_pdp_yqt *x) +{ + if (x->initialized){ + quicktime_close(x->qt); + free(x->qt_frame); + x->initialized = false; + } + +} + +static void pdp_yqt_open(t_pdp_yqt *x, t_symbol *name) +{ + unsigned int size; + + post("pdp_yqt: opening %s", name->s_name); + + pdp_yqt_close(x); + + x->qt = quicktime_open(name->s_name, 1, 0); + + if (!(x->qt)){ + post("pdp_yqt: error opening qt file"); + x->initialized = false; + return; + } + + if (!quicktime_has_video(x->qt)) { + post("pdp_yqt: no video stream"); + quicktime_close(x->qt); + x->initialized = false; + return; + + } + else if (!quicktime_supported_video(x->qt,0)) { + post("pdp_yqt: unsupported video codec\n"); + quicktime_close(x->qt); + x->initialized = false; + return; + } + else + { + x->qt_cmodel = BC_YUV420P; + x->x_vwidth = quicktime_video_width(x->qt,0); + x->x_vheight = quicktime_video_height(x->qt,0); + x->qt_frame = (unsigned char*)malloc(x->x_vwidth*x->x_vheight*4); + size = x->x_vwidth * x->x_vheight; + x->qt_rows[0] = &x->qt_frame[0]; + x->qt_rows[2] = &x->qt_frame[size]; + x->qt_rows[1] = &x->qt_frame[size + (size>>2)]; + + quicktime_set_cmodel(x->qt, x->qt_cmodel); + x->initialized = true; + outlet_float(x->x_outlet2, (float)quicktime_video_length(x->qt,0)); + + } + + if (!quicktime_has_audio(x->qt)) { + post("pdp_yqt: warning : no audio stream"); + x->x_audio = 0; + return; + } + + if ( quicktime_audio_tracks(x->qt) > 1 ) + { + post("pdp_yqt: warning : more that one audio track, using first one"); + } + + if ( ( x->x_audio_channels = quicktime_track_channels(x->qt, 0) ) != 2 ) { + x->x_mono=0; + post("pdp_yqt: track 0 has %d channels", x->x_audio_channels ); + post("pdp_yqt: warning : not a stereo audio track ( audio channels : %d )", x->x_audio_channels ); + if ( x->x_audio_channels == 1 ) x->x_mono = 1; + else x->x_audio_channels = 2; + } else { + post("pdp_yqt: track 0 has %d channels", x->x_audio_channels ); + } + + if (!quicktime_supported_audio(x->qt,0)) { + post("pdp_yqt: warning : audio not supported" ); + x->x_audio = 0; + } else { + x->x_audio = 1; + } + + if ( x->x_audio ) + { + post("pdp_yqt: using audio track 0 with %d channels", x->x_audio_channels ); + post("pdp_yqt: audio data is %d bytes, %d kHz compressed with %s", + quicktime_audio_bits(x->qt, 0), + x->x_audio_rate = quicktime_sample_rate(x->qt, 0), + quicktime_audio_compressor(x->qt, 0) ); + x->x_resampling_factor = ( sys_getsr() / x->x_audio_rate ); + } + +} + + +static void pdp_yqt_bang(t_pdp_yqt *x) +{ + unsigned int w, h, nbpixels, packet_size; + int object, length, pos, i, j; + short int* data; + t_pdp* header; + + static short int gain[4] = {0x7fff, 0x7fff, 0x7fff, 0x7fff}; + + if (!(x->initialized)){ + //post("pdp_yqt: no qt file opened"); + return; + } + + w = x->x_vwidth; + h = x->x_vheight; + nbpixels = w * h; + packet_size = (nbpixels + (nbpixels >> 1)) << 1; + + object = pdp_packet_new_image_YCrCb( x->x_vwidth, x->x_vheight ); + header = pdp_packet_header(object); + data = (short int *) pdp_packet_data(object); + + header->info.image.encoding = PDP_IMAGE_YV12; + header->info.image.width = w; + header->info.image.height = h; + + length = quicktime_video_length(x->qt,0); + pos = quicktime_video_position(x->qt,0); + // post("pdp_yqt : video position : %d length =%d", pos, length ); + + if (pos >= length){ + pos = (x->loop) ? 0 : length - 1; + // post("pdp_yqt : setting video position to %d", pos); + quicktime_set_video_position(x->qt, pos, 0); + if (x->loop) + { + // post("pdp_yqt : resetting audio position"); + if ( x->x_audio ) quicktime_set_audio_position(x->qt, 0, 0); + } + } + + lqt_decode_video(x->qt, x->qt_rows, 0); + + switch(x->qt_cmodel){ + case BC_YUV420P: + pdp_llconv(x->qt_frame, RIF_YVU__P411_U8, data, RIF_YVU__P411_S16, x->x_vwidth, x->x_vheight); + break; + + case BC_YUV422: + pdp_llconv(x->qt_frame, RIF_YUYV_P____U8, data, RIF_YVU__P411_S16, x->x_vwidth, x->x_vheight); + break; + + case BC_RGB888: + pdp_llconv(x->qt_frame, RIF_RGB__P____U8, data, RIF_YVU__P411_S16, x->x_vwidth, x->x_vheight); + break; + + default: + post("pdp_yqt : error on decode: unkown colour model"); + break; + } + + outlet_float(x->x_outlet1, (float)pos); + pdp_packet_pass_if_valid(x->x_outlet0, &object); + + // fills in the audio buffer with a chunk if necessary + if ( x->x_audio && x->x_outunread < MIN_AUDIO_INPUT ) + { + int csize, rsize; + + // watch remaining size + rsize = (int ) ( quicktime_audio_length(x->qt, 0) - quicktime_audio_position(x->qt, 0) ); + csize = ( rsize < DECODE_PACKET_SIZE ) ? rsize : DECODE_PACKET_SIZE; + + // post("pdp_yqt : decode one chunk (size=%d)", csize ); + if ( ( quicktime_decode_audio(x->qt, NULL, x->x_outl, csize, 1) <0 ) || + ( !x->x_mono && ( quicktime_decode_audio(x->qt, NULL, x->x_outl, csize, 2) <0 ) ) ) + { + post("pdp_yqt : could not decode audio data" ); + } else { + for ( i=0; i<csize; i++ ) + { + if ( x->x_outunread >= x->x_outbuffersize-2 ) + { + post( "pdp_yqt: decode audio : too much input ... ignored" ); + continue; + } + for ( j=0; j<x->x_resampling_factor; j++ ) + { + *(x->x_outbuffer+x->x_outwriteposition) = x->x_outl[i]; + x->x_outwriteposition = (x->x_outwriteposition + 1)%x->x_outbuffersize; + *(x->x_outbuffer+x->x_outwriteposition) = + ((x->x_mono)? x->x_outl[i] : x->x_outr[i] ); + x->x_outwriteposition = (x->x_outwriteposition + 1)%x->x_outbuffersize; + x->x_outunread+=2; + } + } + } + } + +} + +static void pdp_yqt_loop(t_pdp_yqt *x, t_floatarg loop) +{ + int loopi = (int)loop; + x->loop = !(loopi == 0); +} + +static void pdp_yqt_frame_cold(t_pdp_yqt *x, t_floatarg frameindex) +{ + int frame = (int)frameindex; + int length; + + + if (!(x->initialized)) return; + + length = quicktime_video_length(x->qt,0); + + frame = (frame >= length) ? length-1 : frame; + frame = (frame < 0) ? 0 : frame; + + // post("pdp_yqt : frame cold : setting video position to : %d", frame ); + quicktime_set_video_position(x->qt, frame, 0); +} + +static void pdp_yqt_frame(t_pdp_yqt *x, t_floatarg frameindex) +{ + // pdp_yqt_frame_cold(x, frameindex); + pdp_yqt_bang(x); +} + +static void pdp_yqt_gain(t_pdp_yqt *x, t_floatarg f) +{ + int i; + short int g; + float bound = (float)0x7fff; + + f *= (float)0x7fff; + + f = (f>bound) ? bound : f; + f = (f<-bound) ? -bound : f; + + g = (short int)f; + + for (i=0; i<4; i++) x->state_data->gain[i] = g; +} + +static void pdp_yqt_free(t_pdp_yqt *x) +{ + + free (x->state_data); + pdp_yqt_close(x); + + freebytes(x->x_outbuffer, OUTPUT_BUFFER_SIZE*sizeof(t_float)); + freebytes(x->x_outl, DECODE_PACKET_SIZE*sizeof(t_float)); + freebytes(x->x_outr, DECODE_PACKET_SIZE*sizeof(t_float)); +} + +t_class *pdp_yqt_class; + +void *pdp_yqt_new(void) +{ + t_pdp_yqt *x = (t_pdp_yqt *)pd_new(pdp_yqt_class); + + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("frame_cold")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("gain")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + x->x_outlet1 = outlet_new(&x->x_obj, &s_float); + x->x_outlet2 = outlet_new(&x->x_obj, &s_float); + + x->x_outlet3 = outlet_new(&x->x_obj, &s_signal); /* audio left channel */ + x->x_outlet4 = outlet_new(&x->x_obj, &s_signal); /* audio right channel */ + + x->packet0 = -1; + + x->initialized = false; + + x->loop = false; + + x->state_data = (t_pdp_yqt_data *)malloc(sizeof(t_pdp_yqt_data)); + pdp_yqt_gain(x, 1.0f); + + // allocate audio buffers + x->x_outbuffersize = OUTPUT_BUFFER_SIZE; + x->x_outl = (t_float*) getbytes(DECODE_PACKET_SIZE*sizeof(t_float)); + x->x_outr = (t_float*) getbytes(DECODE_PACKET_SIZE*sizeof(t_float)); + x->x_outbuffer = (t_float*) getbytes(OUTPUT_BUFFER_SIZE*sizeof(t_float)); + + if ( !x->x_outl || !x->x_outr || !x->x_outbuffer ) + { + post( "mp3amp~: could not allocate buffers" ); + return NULL; + } + memset( x->x_outl, 0x0, DECODE_PACKET_SIZE*sizeof(t_float) ); + memset( x->x_outr, 0x0, DECODE_PACKET_SIZE*sizeof(t_float) ); + memset( x->x_outbuffer, 0x0, OUTPUT_BUFFER_SIZE*sizeof(t_float) ); + + x->x_outreadposition = 0; + x->x_outwriteposition = 0; + x->x_outunread = 0; + + return (void *)x; +} + +static t_int *pdp_yqt_perform(t_int *w) +{ + t_pdp_yqt *x = (t_pdp_yqt*) (w[1]); + t_float *out1 = (t_float *)(w[2]); + t_float *out2 = (t_float *)(w[3]); + int n = (int)(w[4]); + int ret; + int i = 0; + + while( n-- ) + { + if ( x->x_audio && x->x_outunread > 0 ) + { + *out1++=*(x->x_outbuffer+x->x_outreadposition); + x->x_outreadposition = (x->x_outreadposition + 1)%x->x_outbuffersize; + *out2++=*(x->x_outbuffer+x->x_outreadposition); + x->x_outreadposition = (x->x_outreadposition + 1)%x->x_outbuffersize; + x->x_outunread-=2; + } + else + { + *out1++=0.; + *out2++=0.; + } + } + + return (w+5); +} + +static void pdp_yqt_dsp(t_pdp_yqt *x, t_signal **sp) +{ + dsp_add(pdp_yqt_perform, 4, x, sp[1]->s_vec, sp[2]->s_vec, sp[1]->s_n); +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_yqt_setup(void) +{ + pdp_yqt_class = class_new(gensym("pdp_yqt"), (t_newmethod)pdp_yqt_new, + (t_method)pdp_yqt_free, sizeof(t_pdp_yqt), 0, A_NULL); + + class_addmethod(pdp_yqt_class, (t_method)pdp_yqt_bang, gensym("bang"), A_NULL); + class_addmethod(pdp_yqt_class, (t_method)pdp_yqt_close, gensym("close"), A_NULL); + class_addmethod(pdp_yqt_class, (t_method)pdp_yqt_open, gensym("open"), A_SYMBOL, A_NULL); + class_addmethod(pdp_yqt_class, (t_method)pdp_yqt_loop, gensym("loop"), A_DEFFLOAT, A_NULL); + class_addfloat (pdp_yqt_class, (t_method)pdp_yqt_frame); + class_addmethod(pdp_yqt_class, (t_method)pdp_yqt_frame_cold, gensym("frame_cold"), A_FLOAT, A_NULL); + class_addmethod(pdp_yqt_class, (t_method)pdp_yqt_gain, gensym("gain"), A_FLOAT, A_NULL); + class_addmethod(pdp_yqt_class, nullfn, gensym("signal"), 0); + class_addmethod(pdp_yqt_class, (t_method)pdp_yqt_dsp, gensym("dsp"), 0); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_yvu2rgb.c b/modules/pdp_yvu2rgb.c new file mode 100644 index 0000000..ba22d8b --- /dev/null +++ b/modules/pdp_yvu2rgb.c @@ -0,0 +1,185 @@ +/* + * Pure Data Packet module. + * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org> + * + * 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 "pdp.h" +#include "yuv.h" +#include <math.h> + + +typedef struct pdp_yvu2rgb_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + unsigned int *x_RGBFrame; + t_int x_RGBFrameSize; + + +} t_pdp_yvu2rgb; + +static void pdp_yvu2rgb_process_yv12(t_pdp_yvu2rgb *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + int i; + + unsigned int w = header->info.image.width; + unsigned int h = header->info.image.height; + + unsigned int size = w*h; + unsigned int totalnbpixels = size; + unsigned int u_offset = size; + unsigned int v_offset = size + (size>>2); + unsigned int totnbpixels = size + (size>>1); + + unsigned int row, col; + + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = w; + newheader->info.image.height = h; + + if ( !x->x_RGBFrame ) + { + x->x_RGBFrame = ( unsigned int* ) getbytes( size*sizeof( unsigned int ) ); + x->x_RGBFrameSize = size*sizeof( unsigned int ); + post( "pdp_yvu2rgb : allocated frame size=%d", x->x_RGBFrameSize ); + } + if ( !x->x_RGBFrame ) + { + post( "pdp_yvu2rgb : cannot allocate frame" ); + return; + } + + yuv_Y122RGB( data, x->x_RGBFrame, w, h ); + // post( "pdp_yvu2rgb : converted to RGB" ); + yuv_RGB2Y12( x->x_RGBFrame, newdata, w, h ); + // post( "pdp_yvu2rgb : converted to Y12" ); + + return; +} + +static void pdp_yvu2rgb_sendpacket(t_pdp_yvu2rgb *x) +{ + /* release the packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_yvu2rgb_process(t_pdp_yvu2rgb *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_yvu2rgb_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_yvu2rgb_process_yv12, pdp_yvu2rgb_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // pdp_yvu2rgb_process_packet(x); + break; + + default: + /* don't know the type, so dont pdp_yvu2rgb_process */ + break; + + } + } +} + +static void pdp_yvu2rgb_input_0(t_pdp_yvu2rgb *x, t_symbol *s, t_floatarg f) +{ + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)) + { + /* add the process method and callback to the process queue */ + pdp_yvu2rgb_process(x); + } +} + +static void pdp_yvu2rgb_free(t_pdp_yvu2rgb *x) +{ + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); + if (x->x_RGBFrame ) freebytes( x->x_RGBFrame, x->x_RGBFrameSize ); +} + +t_class *pdp_yvu2rgb_class; + +void *pdp_yvu2rgb_new(void) +{ + int i; + + t_pdp_yvu2rgb *x = (t_pdp_yvu2rgb *)pd_new(pdp_yvu2rgb_class); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_yvu2rgb_setup(void) +{ + + + pdp_yvu2rgb_class = class_new(gensym("pdp_yvu2rgb"), (t_newmethod)pdp_yvu2rgb_new, + (t_method)pdp_yvu2rgb_free, sizeof(t_pdp_yvu2rgb), 0, A_NULL); + + class_addmethod(pdp_yvu2rgb_class, (t_method)pdp_yvu2rgb_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/system/Makefile b/system/Makefile new file mode 100644 index 0000000..fc2c9ac --- /dev/null +++ b/system/Makefile @@ -0,0 +1,7 @@ +current: all_modules + +include ../Makefile + +OBJECTS = pidip.o yuv.o + +all_modules: $(OBJECTS) diff --git a/system/Makefile.in b/system/Makefile.in new file mode 100644 index 0000000..fc2c9ac --- /dev/null +++ b/system/Makefile.in @@ -0,0 +1,7 @@ +current: all_modules + +include ../Makefile + +OBJECTS = pidip.o yuv.o + +all_modules: $(OBJECTS) diff --git a/system/pidip.c b/system/pidip.c new file mode 100644 index 0000000..152313d --- /dev/null +++ b/system/pidip.c @@ -0,0 +1,116 @@ +#include <stdio.h> +#include "pdp.h" + + +/* all symbols are C style */ +#ifdef __cplusplus +extern "C" +{ +#endif + + void pdp_intrusion_setup(void); + void pdp_simura_setup(void); + void pdp_underwatch_setup(void); + void pdp_vertigo_setup(void); + void pdp_yvu2rgb_setup(void); + void pdp_yqt_setup(void); + void pdp_lens_setup(void); + void pdp_baltan_setup(void); + void pdp_aging_setup(void); + void pdp_ripple_setup(void); + void pdp_warp_setup(void); + void pdp_rev_setup(void); + void pdp_mosaic_setup(void); + void pdp_edge_setup(void); + void pdp_spiral_setup(void); + void pdp_radioactiv_setup(void); + void pdp_warhol_setup(void); + void pdp_nervous_setup(void); + void pdp_quark_setup(void); + void pdp_spigot_setup(void); + void pdp_rec_tilde_setup(void); + void pdp_o_setup(void); + void pdp_i_setup(void); + void pdp_mgrid_setup(void); + void pdp_ctrack_setup(void); + void pdp_cycle_setup(void); + void pdp_transform_setup(void); + void pdp_shagadelic_setup(void); + void pdp_dice_setup(void); + void pdp_puzzle_setup(void); + void pdp_text_setup(void); + void pdp_form_setup(void); + void pdp_compose_setup(void); + void pdp_cmap_setup(void); + void pdp_aa_setup(void); + void pdp_ascii_setup(void); + void pdp_ffmpeg_tilde_setup(void); + void pdp_live_tilde_setup(void); + void pdp_segsnd_tilde_setup(void); + void pdp_noquark_setup(void); + void pdp_juxta_setup(void); + void pdp_capture_setup(void); + void pdp_smuck_setup(void); + void pdp_lumafilt_setup(void); + void pdp_transition_setup(void); + void pdp_imgloader_setup(void); + void pdp_imgsaver_setup(void); + + +/* library setup routine */ +void pidip_setup(void){ + + post ("PiDiP : additional video processing objects for PDP : version " PDP_PIDIP_VERSION " ( ydegoyon@free.fr )\n"); + + pdp_intrusion_setup(); + pdp_yqt_setup(); + pdp_simura_setup(); + pdp_underwatch_setup(); + pdp_vertigo_setup(); + pdp_yvu2rgb_setup(); + pdp_lens_setup(); + pdp_baltan_setup(); + pdp_aging_setup(); + pdp_ripple_setup(); + pdp_warp_setup(); + pdp_rev_setup(); + pdp_mosaic_setup(); + pdp_edge_setup(); + pdp_spiral_setup(); + pdp_radioactiv_setup(); + pdp_warhol_setup(); + pdp_nervous_setup(); + pdp_quark_setup(); + pdp_spigot_setup(); + pdp_rec_tilde_setup(); + pdp_o_setup(); + pdp_i_setup(); + pdp_mgrid_setup(); + pdp_ctrack_setup(); + pdp_cycle_setup(); + pdp_transform_setup(); + pdp_shagadelic_setup(); + pdp_dice_setup(); + pdp_puzzle_setup(); + pdp_text_setup(); + pdp_form_setup(); + pdp_compose_setup(); + pdp_cmap_setup(); + pdp_aa_setup(); + pdp_ascii_setup(); + pdp_ffmpeg_tilde_setup(); + pdp_live_tilde_setup(); + pdp_segsnd_tilde_setup(); + pdp_noquark_setup(); + pdp_juxta_setup(); + pdp_capture_setup(); + pdp_lumafilt_setup(); + pdp_transition_setup(); + pdp_imgloader_setup(); + pdp_imgsaver_setup(); + +} + +#ifdef __cplusplus +} +#endif diff --git a/system/yuv.c b/system/yuv.c new file mode 100644 index 0000000..4e6cd69 --- /dev/null +++ b/system/yuv.c @@ -0,0 +1,201 @@ +/* + * EffecTV - Realtime Digital Video Effector + * Copyright (C) 2001-2002 FUKUCHI Kentaro + * + * yuv.c: YUV(YCbCr) color system utilities + * + */ + +#include <math.h> +#include "m_pd.h" + +/* + * conversion from YUV to RGB + * r = 1.164*(y-16) + 1.596*(v-128); + * g = 1.164*(y-16) - 0.813*(v-128) - 0.391*(u-128); + * b = 1.164*(y-16) + 2.018*(u-128); + * conversion from RGB to YUV + * y = 0.257*r + 0.504*g + 0.098*b + 16 + * u = -0.148*r - 0.291*g + 0.439*b + 128 + * v = 0.439*r - 0.368*g - 0.071*b + 128 + */ + +float YtoRGB[256]; +float VtoR[256], VtoG[256]; +float UtoG[256], UtoB[256]; +float RtoY[256], RtoU[256], RtoV[256]; +float GtoY[256], GtoU[256], GtoV[256]; +float BtoY[256], BtoV[256]; + +static int yuvinit=-1; + +int yuv_init(void) +{ + int i; + + if(yuvinit==-1) { + for(i=0; i<256; i++) { + YtoRGB[i] = 1.164*(i-16); + VtoR[i] = 1.596*(i-128); + VtoG[i] = -0.813*(i-128); + UtoG[i] = -0.391*(i-128); + UtoB[i] = 2.018*(i-128); + RtoY[i] = 0.257*i; + RtoU[i] = -0.148*i; + RtoV[i] = 0.439*i; + GtoY[i] = 0.504*i; + GtoU[i] = -0.291*i; + GtoV[i] = -0.368*i; + BtoY[i] = 0.098*i; + BtoV[i] = -0.071*i; + } + yuvinit=1; + } + + return 0; +} + +unsigned char yuv_RGBtoY(int rgb) +{ + int i; + + if ( yuvinit == -1 ) { yuv_init(); } + i = RtoY[(rgb>>16)&0xff]; + i += GtoY[(rgb>>8)&0xff]; + i += BtoY[rgb&0xff]; + i += 16; + + return i; +} + +unsigned char yuv_RGBtoU(int rgb) +{ + int i; + + if ( yuvinit == -1 ) { yuv_init(); } + i = RtoU[(rgb>>16)&0xff]; + i += GtoU[(rgb>>8)&0xff]; + i += RtoV[rgb&0xff];/* BtoU == RtoV */ + i += 128; + + return i; +} + +unsigned char yuv_RGBtoV(int rgb) +{ + int i; + + if ( yuvinit == -1 ) { yuv_init(); } + i = RtoV[(rgb>>16)&0xff]; + i += GtoV[(rgb>>8)&0xff]; + i += BtoV[rgb&0xff]; + i += 128; + + return i; +} + +unsigned char yuv_YUVtoR(unsigned char y, unsigned char u, unsigned char v) +{ + int r; + + if ( yuvinit == -1 ) { yuv_init(); } + r = YtoRGB[(int)y] + VtoR[(int)v]; + if ( r>255 ) r=255; + if ( r<0 ) r=0; + return r; +} + +unsigned char yuv_YUVtoG(unsigned char y, unsigned char u, unsigned char v) +{ + int g; + + if ( yuvinit == -1 ) { yuv_init(); } + g = YtoRGB[(int)y] + UtoG[(int)u] + VtoG[(int)v]; + if ( g>255 ) g=255; + if ( g<0 ) g=0; + return g; +} + +unsigned char yuv_YUVtoB(unsigned char y, unsigned char u, unsigned char v) +{ + int b; + + if ( yuvinit == -1 ) { yuv_init(); } + b = YtoRGB[(int)y] + UtoB[(int)u]; + if ( b>255 ) b=255; + if ( b<0 ) b=0; + return b; +} + +int yuv_YUVtoRGB(unsigned char y, unsigned char u, unsigned char v) +{ + if ( yuvinit == -1 ) { yuv_init(); } + return ( (yuv_YUVtoR(y,u,v)<<16) + (yuv_YUVtoG(y,u,v)<<8) + (yuv_YUVtoB(y,u,v)) ); +} + +void yuv_Y122RGB( short int* packet, unsigned int *rgb, int width, int height ) +{ + unsigned char y=0,u=0,v=0; + int X,Y; + int uoffset = width*height; + int maxoffset = width*height+((width*height)>>1); + int voffset = width*height+((width*height)>>2); + + if ( !packet || !rgb ) + { + post( "yuv_Y122RGB : pointers are NULL !!!" ); + return; + } + if ( yuvinit == -1 ) { yuv_init(); } + for(Y=0; Y < height; Y++){ + for(X=0; X < width; X++){ + // post( "yuv_Y122RGB : X=%d Y=%d", X, Y ); + if ( (Y*width+X) < maxoffset ) + y=(packet[Y*width+X]>>7); + if( (uoffset+((Y>>1)*width+(X>>1))) < maxoffset ) + u=(packet[uoffset+((Y>>1)*width+(X>>1))]>>8)+128; + if( (voffset+((Y>>1)*width+(X>>1))) < maxoffset ) + v=(packet[voffset+((Y>>1)*width+(X>>1))]>>8)+128; + + rgb[Y*width+X] = yuv_YUVtoRGB( y, u, v ); + } + } + +} + +void yuv_RGB2Y12( unsigned int *rgb, short int* packet, int width, int height ) +{ + short int y,u,v,iu=0,iv=0; + int X,Y; + int uoffset = width*height; + int maxoffset = width*height+((width*height)>>1); + int voffset = width*height+((width*height)>>2); + + if ( !packet || !rgb ) + { + post( "yuv_RGB2Y12 : pointers are NULL !!!" ); + return; + } + if ( yuvinit == -1 ) { yuv_init(); }; + for(Y=0; Y < height; Y++) + for(X=0; X < width; X++){ + { + // post( "yuv_RGB2Y12 : X=%d Y=%d", X, Y ); + y=yuv_RGBtoY( rgb[Y*width+X] ); + u=yuv_RGBtoU( rgb[Y*width+X] ); + v=yuv_RGBtoV( rgb[Y*width+X] ); + + if ( (Y*width+X) < maxoffset ) + packet[Y*width+X]=(y<<7); + if( (uoffset+iu) < maxoffset ) + packet[uoffset+iu]=(u-128<<8); + if( (voffset+iv) < maxoffset ) + packet[voffset+iv]=(v-128<<8); + if ( ( X%2 == 0) && ( Y%2 == 0) ) + { + iu++; iv++; + } + } + } + +} |