diff options
-rw-r--r-- | CHANGES.LOG | 16 | ||||
-rw-r--r-- | Makefile | 66 | ||||
-rw-r--r-- | Makefile.config | 49 | ||||
-rw-r--r-- | Makefile.config.in | 38 | ||||
-rw-r--r-- | Makefile.linux | 4 | ||||
-rw-r--r-- | Makefile.linux_mmx | 4 | ||||
-rw-r--r-- | README | 99 | ||||
-rw-r--r-- | TODO | 29 | ||||
-rw-r--r-- | configure.ac | 125 | ||||
-rw-r--r-- | debug/gdb_pdp_load | 8 | ||||
-rw-r--r-- | include/pdp.h | 40 | ||||
-rw-r--r-- | include/pdp_imageproc.h | 11 | ||||
-rw-r--r-- | include/pdp_resample.h | 6 | ||||
-rw-r--r-- | modules/Makefile | 10 | ||||
-rw-r--r-- | modules/pdp_del.c | 56 | ||||
-rw-r--r-- | modules/pdp_gradient.c | 7 | ||||
-rw-r--r-- | modules/pdp_noise.c | 10 | ||||
-rw-r--r-- | modules/pdp_qt.c | 18 | ||||
-rw-r--r-- | modules/pdp_sdl.c | 245 | ||||
-rw-r--r-- | modules/pdp_v4l.c | 61 | ||||
-rw-r--r-- | modules/pdp_xv.c | 132 | ||||
-rw-r--r-- | scaf/Makefile | 30 | ||||
-rw-r--r-- | scaf/README | 18 | ||||
-rw-r--r-- | scaf/pdp/Makefile | 2 | ||||
-rw-r--r-- | scaf/pdp/pdp_ca.c | 66 | ||||
-rw-r--r-- | system/Makefile | 22 | ||||
-rw-r--r-- | system/pdp.c | 37 | ||||
-rw-r--r-- | system/pdp_imageproc_mmx.c | 30 | ||||
-rw-r--r-- | system/pdp_imageproc_portable.c | 18 | ||||
-rw-r--r-- | system/pdp_packet.c | 10 | ||||
-rw-r--r-- | system/pdp_resample.c | 31 |
31 files changed, 929 insertions, 369 deletions
diff --git a/CHANGES.LOG b/CHANGES.LOG index e7562bc..eeb0931 100644 --- a/CHANGES.LOG +++ b/CHANGES.LOG @@ -1,4 +1,4 @@ -last modified: 2003/02/03 +last modified: 2003/02/27 ChangeLog: @@ -61,3 +61,17 @@ v0.8: 2003/02/02 (0.8.1) fixed scaf + gcc<3 compilation problem (0.8.2) fixed compile prob + added documentation (0.8.3) completed documentation + +v0.9: 2003/02/27 + added pdp_scanxy~, pdp_invert + now uses autoconf for configuration + standard "make install" target + optional compililation for external dependencies (xv,qt,v4l,sdl) + experimental OSX port (without i/o) + fixed crash when closing xv window manually + added mouse event output to pdp_xv + pdp_ca now automaticly compiles rule files + fixed image dimension crashes + fixed pdp_xv bang crash + added pdp_grey2mask + added pdp_slice_cut/pdp_slice_glue (experimental/nondoc) @@ -1,18 +1,24 @@ include Makefile.config -PDP_DISTRO = $(PDP_DIR)/../pdp-$(PDP_VERSION) -PDP_TARBALL = $(PDP_DISTRO).tar.gz -PDP_WWWDIR = /net/zwizwa/www/zwizwa.fartit.com/pd/pdp -PDP_WWWTESTDIR = /net/zwizwa/www/zwizwa.fartit.com/pd/pdp/test -all: pdp.pd_linux - -include Makefile.$(PDP_TARGET) +all: $(PDP_TARGET) pdp_all: make -C system make -C modules +darwin: pdp_all + rm -f pdp.pd_darwin + $(CC) -bundle -bundle_loader $(PD_EXECUTABLE) -o pdp.pd_darwin modules/*.o system/*.o $(PDP_LIBS) + +linux: pdp_all + rm -f pdp.pd_linux + $(CC) -export_dynamic -shared -o pdp.pd_linux modules/*.o system/*.o $(PDP_LIBS) + +linux_mmx: pdp_all + rm -f pdp.pd_linux + $(CC) -export_dynamic -shared -o pdp.pd_linux modules/*.o system/*.o system/mmx/*.o $(PDP_LIBS) + buildclean: make -C include clean make -C system clean @@ -25,6 +31,14 @@ clean: buildclean distroclean: buildclean make -C scaf clean +mrproper: clean + make -C scaf mrproper + rm -rf configure + rm -rf config.log + rm -rf config.status + rm -rf autom4te.cache + rm -rf Makefile.config + tags: etags --language=auto include/*.h system/mmx/*.s system/*.c modules/*.c @@ -32,26 +46,18 @@ tagsclean: rm -f TAGS - -distro: distroclean - rm -rf $(PDP_DISTRO) - mkdir $(PDP_DISTRO) - cp -av $(PDP_DIR)/* $(PDP_DISTRO) - #strip --strip-unneeded $(PDP_DISTRO)/pdp.pd_linux - rm -rf $(PDP_DISTRO)/CVS - rm -rf $(PDP_DISTRO)/*/CVS - rm -rf $(PDP_DISTRO)/*/*/CVS - rm -rf $(PDP_DISTRO)/*/*.o - rm -rf $(PDP_DISTRO)/*/TAGS - cd $(PDP_DISTRO)/.. && tar vczf pdp-$(PDP_VERSION).tar.gz pdp-$(PDP_VERSION) - rm -rf $(PDP_DISTRO) - -www: $(PDP_TARBALL) - cp -av $(PDP_TARBALL) $(PDP_WWWDIR) - cp -av $(PDP_DIR)/README $(PDP_WWWDIR)/README.txt - cp -av $(PDP_DIR)/doc/reference.txt $(PDP_WWWDIR)/REFERENCE.txt - cp -av $(PDP_DIR)/CHANGES.LOG $(PDP_WWWDIR)/CHANGELOG.txt - - -www-test:$(PDP_TARBALL) - cp -av $(PDP_TARBALL) $(PDP_WWWTESTDIR) +install: all + #check if pd is installed. if this fails make install will stop here. + test -d $(prefix)/lib/pd + install -m 755 $(PDP_LIBRARY_NAME) $(prefix)/lib/pd/externs + install -m 755 -d $(prefix)/include/pdp + install -m 644 include/*.h $(prefix)/include/pdp + install -m 644 abstractions/*.pd $(prefix)/lib/pd/externs + install -m 644 doc/objects/*.pd $(prefix)/lib/pd/doc/5.reference + install -m 755 -d $(prefix)/lib/pd/doc/pdp + install -m 755 -d $(prefix)/lib/pd/doc/pdp/introduction + install -m 755 -d $(prefix)/lib/pd/doc/pdp/examples + install -m 644 doc/reference.txt $(prefix)/lib/pd/doc/pdp + install -m 644 doc/introduction/*.pd $(prefix)/lib/pd/doc/pdp/introduction + install -m 644 doc/examples/*.pd $(prefix)/lib/pd/doc/pdp/examples + install -m 755 bin/pdp-config $(prefix)/bin diff --git a/Makefile.config b/Makefile.config deleted file mode 100644 index 694b79e..0000000 --- a/Makefile.config +++ /dev/null @@ -1,49 +0,0 @@ -# pd's directory -PD_DIR = /home/tom/pd/distro/pd -PDP_DIR = /home/tom/pd/packet - -#PD_DIR = /usr/local/pd -#PDP_DIR = /usr/local/pdp - -# uncomment for philips webcam support -# PDP_PWC = -DHAVE_V4LPWC - -# specify target -#PDP_TARGET = linux -PDP_TARGET = linux_mmx - - -################################################# - - -PDP_VERSION = 0.8.3 -PDP_DEFINES = $(PDP_PWC) - -# build flags -#SDL_CFLAGS := $(shell sdl-config --cflags) -#SDL_LDFLAGS := $(shell sdl-config --libs) -SDL_FLAGS = -D_REENTRANT -SDL_LDFLAGS = -lSDL - -PDP_INCLUDE = -I$(PD_DIR)/src -I. -I/usr/X11R6/include -I../include -PDP_LIBS = -L/usr/X11R6/lib -lX11 -lXv -lXext -lm -lquicktime -ldl $(SDL_LDFLAGS) -PDP_AFLAGS = -#--gstabs -PDP_CFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer -ffast-math \ - -Wall -W -Wstrict-prototypes -Werror \ - -Wno-unused -Wno-parentheses -Wno-switch $(PDP_DEFINES)\ - -DPDP_VERSION=\"$(PDP_VERSION)\" \ - -g $(SDL_CFLAGS) -# -Wshadow - -# compiler and assembler -#CC = gcc-3.2 -CC = gcc -AS = as - -# build rules - -.c.o: - $(CC) $(PDP_CFLAGS) $(PDP_INCLUDE) -o $*.o -c $*.c -.s.o: - $(AS) -o $*.o $*.s $(PDP_AFLAGS) diff --git a/Makefile.config.in b/Makefile.config.in new file mode 100644 index 0000000..2f163db --- /dev/null +++ b/Makefile.config.in @@ -0,0 +1,38 @@ +# if configure can't find the m_pd.h header +# specify pd's include path here and ignore the warning +# +#PD_CPPFLAGS=-I/path_to_pd_dir/src +#PD_EXECUTABLE=/path_to_pd_dir/bin/pd +PD_CPPFLAGS=@PD_CPPFLAGS@ +PD_EXECUTABLE=@PD_EXECUTABLE@ + + +prefix=@prefix@ +PDP_VERSION = @PDP_VERSION@ +PDP_TARGET = @PDP_TARGET@ +PDP_LIBRARY_NAME = @PDP_LIBRARY_NAME@ +PDP_OPTMOD = @PDP_OPTMOD@ +PDP_EXTRA_CPPFLAGS = @PDP_EXTRA_CPPFLAGS@ +SDL_FLAGS = -D_REENTRANT + +PDP_CPPFLAGS = -I. -I/usr/X11R6/include -I../include $(PD_CPPFLAGS) $(PDP_EXTRA_CPPFLAGS) +PDP_LIBS = @LIBS@ +PDP_AFLAGS = +#--gstabs +PDP_CFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer -ffast-math \ + -Wall -W -Wstrict-prototypes -Werror \ + -Wno-unused -Wno-parentheses -Wno-switch -DPDP_VERSION=\"$(PDP_VERSION)\" \ + -g $(SDL_CFLAGS) +# -Wshadow + +# compiler and assembler +#CC = gcc-3.2 +#CC = gcc +#AS = as + +# build rules + +.c.o: + $(CC) $(PDP_CFLAGS) $(PDP_CPPFLAGS) -o $*.o -c $*.c +.s.o: + $(AS) -o $*.o $*.s $(PDP_AFLAGS) diff --git a/Makefile.linux b/Makefile.linux deleted file mode 100644 index 0c4a748..0000000 --- a/Makefile.linux +++ /dev/null @@ -1,4 +0,0 @@ -pdp.pd_linux: pdp_all - rm -f pdp.pd_linux - $(CC) -export_dynamic -shared -o pdp.pd_linux modules/*.o system/*.o $(PDP_LIBS) - #strip --strip-unneeded pdp.pd_linux diff --git a/Makefile.linux_mmx b/Makefile.linux_mmx deleted file mode 100644 index 2adbb1c..0000000 --- a/Makefile.linux_mmx +++ /dev/null @@ -1,4 +0,0 @@ -pdp.pd_linux: pdp_all - rm -f pdp.pd_linux - $(CC) -export_dynamic -shared -o pdp.pd_linux modules/*.o system/*.o system/mmx/*.o $(PDP_LIBS) - #strip --strip-unneeded pdp.pd_linux @@ -1,4 +1,4 @@ -PDP - Pure Data Packet v0.8.3 +PDP - Pure Data Packet v0.9 a packet processing library for pure data Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org> @@ -26,18 +26,13 @@ This external pd library is a framework for image/video processing (and other raw data packets) that is fast, simple and flexible and as much as possible compatible with the pd messaging system. -Unfortunately, since the main idea is to "have something for myself to -play with", i haven't payed much attention to portability or even -compilablility yet. So if some of the requirements are missing on your -system, you'll have to tinker a bit to get it working until i move to -automatic configuration and building... Features: * packet formats: greyscale and YV12 encoded images, binary cellular automata (CA) * sources: noise, video4linux and quicktime (with audio), CA -* sink: xvideo display +* sinks: xvideo display, sdl * filters: convolution, biquad time, biquad space, CA * warping: rotate, zoom, stretch * transforms: colour translation/scaling, grey->palette @@ -47,12 +42,6 @@ Features: * minimal forth system for defining CA rules (only for mmx) -Implementation: - -* mmx/c 16bit internal integer processing -* sort of cache optimized (locality + minimal memory usage) - - Requirements: * pd @@ -60,49 +49,62 @@ Requirements: * a video4linux device for video input. special support for philips webcam included. * libquicktime (not quicktime4linux!) for quicktime playback. -* an X display with XVideo extension for video display -* libsdl +* an X display with XVideo extension or SDL for video display. Documentation: -Have a look in doc/ for documentation. The file doc/reference.txt -contains a list of all objects. doc/introduction has some basic -facts on using pdp. doc/objects is a reference doc for all the -objects and doc/examples contains some more example patches. - -The directory abstractions/ has some abstractions using the pdp -objects (some specific filters) that can serve as example. +When you use "make install" to install pd, all docs will be in +the pd doc directory. Right click on an object and select help +for a help patch. The pdp directory in pd's doc contains a +reference.txt file which lists all objects and abstractions and +an introduction and example section. -For developer docs see modules/README, scaf/README. +NOTE: all help patches use a pdp_help_input and pdp_help_output +abstraction. you can edit these to choose which input or output +object you want for the help patches. Building: -Edit Makefile.config to reflect your system settings. For now this -should be the pd dir, the pdp dir, a toggle for philips web cam -support and the compilation target (linux / linux_mmx). -type "make" in the top directory. Remember to type -"make clean all" after editing Makefile.config +./configure +make + +Options for configure: +--enable-mmx compile with mmx support +--enable-pwc compile with philips webcam support + +If pd is not installed in /usr/local you'll have to +specify the prefix on the configure command line with + +./configure --prefix=dir + +type +make install -Using: +To install pd in $prefix/lib/pd: the library in externs/ +the abstractions in extra/ and the documentation in doc/5.reference +and doc/pdp -launch pd with the options -lib $PDP_DIR/pdp -path $PDP_DIR/abstractions +NOTE: If you're not using the standard pd install location, and have +everything in a single tree, just untar pdp next to the pd source tree. Bugs: -see the TODO file +See the TODO file. Apart from the few items listed on top of this +file, pdp is fairly stable. If you encounter a crash please consider +sending a bug report. Additional Remarks: -* If some of the modules don't compile due to some missing libraries, -you can try to comment out the offending code in modules/Makefile and -system/pdp.c If compilation or linking fails due to other reasons, -please let me know. If you have both libquicktime and quicktime4linux -installed, make sure pdp.pd_linux loads the right library. +* The modules that depend on system libraries only get compiled when +the configure script can locate them. If compilation or linking fails +please let me know. NOTE: If you have libquicktime and quicktime4linux +installed, this can give problems with the configure script. Consider +removing quicktime4linux. (libquicktime is a drop-in replacement). * The reason i use YV12 and not RGB is simple: it's faster, and for linear operations it doesn't make much difference. Most camera's and @@ -130,13 +132,9 @@ thread. Note that when using the pdp thread, the control flow is no longer depth first. Additinal delays will be introduced. * There have been some requests for an osx port, but i wil probably not -do this myself (at least not right now). However, i've ported all -the mmx code to c, so it should work on other architectures as well. -This should ease porting a bit for anyone who wants to give it a try. -Also i've moved all the image conversion routines to pdp_llconv.c -This means porting is reduced to writing new objects for the os specific -stuff like movie playback&record and live video input. Thanks to Martin -Pi we now have sdl support for video output. +do this myself (at least not right now). However, the platform +independent part of pdp compiles on darwin, although it is not of much +use yet without input and output modules. * Have a look at Yves Degoyon's PiDiP library. It contains some extra effects (from EffecTV and FreeJ), a quicktime recording object, some @@ -150,8 +148,11 @@ suggested codec is jpeg (photo) and uncompressed audio with the same samplerate as the one pd is using. (hint: compile libquicktime with mmx jpeg support) -* The cellular automata object (pdp_ca) is now moved to a separate lib. -It requires mmx to be compiled. see the scaf/ dir. +* Writing new objects is not much different than normal pd externs. +Pdp just adds some functions to the pd kernel for package allocation, +manipulation and communication. The api is very raw to keep it as +simple as possible. In the future there will probably be a layer on +top of this that will make things a bit less spartan. * New versions of this package can be found at http://zwizwa.fartit.com/pd/pdp @@ -164,7 +165,6 @@ abstractions/ some abstractions that use the pdp objects doc/introduction/ getting started with pdp doc/examples/ some example patches doc/objects/ pd style reference documentation -debug/ debug scripts include/ header files modules/ pdp module code scaf/ CA extension lib (needs to be compiled separately) @@ -173,13 +173,12 @@ system/mmx/ mmx assembler files -Please let me know if you discover a bug or think something doesn't work -right. Code, documentation or example patches are more than welcome of -course. +Bugreports, feature suggestions, code, documentation, example patches +and general comments and questions are welcome. Have Fun, Tom -last modified: 2003/02/03 +last modified: 2003/02/24 @@ -1,38 +1,39 @@ -bugs: +fatal crash bugs: + +* none that i know of (if pdp dies on you, please let me know) -* some image dimensions cause crashes: solution: add checks in sources (pdp_v4l / pdp_qt / pdp_ca) -(workaround: use a multiple of 8x8 to prevent this. ca dims should be a multiple of 64x2) -* pdp_xv: catch sigpipe when window is closed (workaround: don't close the video windows manually ;) todo 0.9: -* improve scanned synthesis (method to specify scanning path) -* solve image dimension problenms for sources -* ascii art packet stuff (yves?) +* 2D affine transforms parametrized by vectors (center, x-axis, y-axis) +* some abstractions around pdp_cheby (colour shape, ...) * add real trigger object (problem with 3 phase protocol ?) -* add shear -> simplify code to use general affine 2d transformations +* absolute value object * displacement warp, substitution warp * efficient rescalers: pdp_double pdp_halve * move float color conversion and float<->fixed point conv code to system -* add mouse pointer code to pdp_xv * crop, shift (pad+scroll) -todo: +todo 0.10: +* solve biquad (blur) boundary init prob +* optimize blur effect (1 pole ? / dependency stalls) +* jpeg/png file and streaming support? * thresholding * find out why resampling code (warping) is so slow (reg->mem->reg->mem stalls?) +* mmx profiling * add audio resampling in pdp_qt~ -* add some more abstractions -* fix dimension problems on input (for now, make sure images have correct dim, else generate error) * use pd_error instead of post for errors -* move to autoconf/automake/libtool * interface with gem * think about the memory allocation strategy (there is no garbage collection right now) +* add automatic pwc detection +* frame rate limited delay line (burst delay?) wish list: +* ascii art packet stuff (yves?) +* 3D time space interpolation * colour keying * camera controller (motion tracking ?) * moebius transforms (integer inverse square root??) & other complex plane stuff - diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..50f9c1b --- /dev/null +++ b/configure.ac @@ -0,0 +1,125 @@ +AC_INIT(system/pdp.c) +AC_CONFIG_HEADER(include/pdp_config.h) +AC_PROG_CC +AC_HEADER_STDC + +dnl TAG CVS WHEN VERSION CHANGES !!! +PDP_VERSION=0.9 +AC_SUBST(PDP_VERSION) + +AC_ARG_ENABLE(pwc, + [ --enable-pwc enable additional Philips WebCam support], + AC_DEFINE(HAVE_PWCV4L, 1,enable pwc v4l support)) + +AC_ARG_ENABLE(mmx, + [ --enable-mmx enable MMX support], MMX=yes, MMX=no) + + +if test $prefix == NONE; +then + prefix=/usr/local +fi + + +dnl try to locate the pd header in case the setup is nonstandard +dnl check in $prefix/pd/src then ../pd/src +dnl if this fails we trust it is in the standard include path +PWD=`pwd` +if test -f $prefix/pd/src/m_pd.h; +then + PD_CPPFLAGS="-I$prefix/pd/src" + +elif test -f $prefix/src/pd/src/m_pd.h; +then + PD_CPPFLAGS="-I$prefix/src/pd/src" +elif test -f $PWD/../pd/src/m_pd.h; +then + PD_CPPFLAGS="-I$PWD/../pd/src" +elif test -f $PWD/../src/m_pd.h; +then + PD_CPPFLAGS="-I$PWD/../src" +fi + + +CPPFLAGS="$CPPFLAGS $PD_CPPFLAGS" +AC_CHECK_HEADER(m_pd.h,, + echo "WARNING: m_pd.h not found. Is PD installed?" + echo "WARNING: if you have changed PD_CPPFLAGS in Makefile.config.in you can ignore this warning." ) + + +AC_CHECK_LIB(m,sin) + + +ARCH=`uname -s` +if test $ARCH == Linux; +then + PDP_LIBRARY_NAME=pdp.pd_linux + if test $MMX == yes; + then + PDP_TARGET=linux_mmx + else + PDP_TARGET=linux + fi +elif test $ARCH == Darwin; +then + PDP_LIBRARY_NAME=pdp.pd_darwin + PDP_TARGET=darwin +else + echo WARNING: Architecture `uname -s` not supported. + exit +fi + + + +dnl Darwin specific stuff: this is still pretty experimental +dnl How to test if frameworks are present ???? +if test $ARCH == Darwin +then + PDP_OPTMOD="$PDP_OPTMOD pdp_sdl.o" + LIBS="$LIBS -framework SDL" + PDP_EXTRA_CPPFLAGS="$PDP_EXTRA_INCLUDE -I/Library/Frameworks/SDL.framework/Headers" + PD_EXECUTABLE=ihavenocluewherethepdbinaryislocated + AC_DEFINE(HAVE_PDP_SDL, 1, build pdp_sdl) + +dnl These are checks for libraries. +dnl Objects that depend on a lib only get included when the lib is found. +else + + AC_CHECK_LIB(quicktime, lqt_decode_video, + PDP_OPTMOD="$PDP_OPTMOD pdp_qt.o" + LIBS="$LIBS -lquicktime" + AC_DEFINE(HAVE_PDP_QT, 1, build pdp_qt), + echo " libquicktime not found: not building pdp_qt") + + AC_CHECK_LIB(SDL, SDL_Init, + PDP_OPTMOD="$PDP_OPTMOD pdp_sdl.o" + LIBS="$LIBS -lSDL" + AC_DEFINE(HAVE_PDP_SDL, 1, build pdp_sdl), + echo " libSDL not found: not building pdp_sdl") + + AC_CHECK_LIB(Xv, XvPutImage, + PDP_OPTMOD="$PDP_OPTMOD pdp_xv.o" + LIBS="$LIBS -L/usr/X11R6/lib -lX11 -lXv -lXext" + AC_DEFINE(HAVE_PDP_XV, 1, build pdp_xv), + echo " libXv not found: not building pdp_xv", + -L/usr/X11R6/lib -lX11 -lXext) + + AC_CHECK_HEADER(linux/videodev.h, + PDP_OPTMOD="$PDP_OPTMOD pdp_v4l.o" + AC_DEFINE(HAVE_PDP_V4L, 1, build pdp_v4l), + echo " linux/videodev.h not found: not building pdp_v4l") +fi + + +echo target is $PDP_TARGET + + +AC_SUBST(PD_CPPFLAGS) +AC_SUBST(PD_EXECUTABLE) +AC_SUBST(PDP_EXTRA_CPPFLAGS) +AC_SUBST(PDP_LIBRARY_NAME) +AC_SUBST(PDP_TARGET) +AC_SUBST(PDP_OPTMOD) +AC_CONFIG_FILES(Makefile.config) +AC_CONFIG_FILES(bin/pdp-config) +AC_OUTPUT diff --git a/debug/gdb_pdp_load b/debug/gdb_pdp_load index ec57816..3cf4da8 100644 --- a/debug/gdb_pdp_load +++ b/debug/gdb_pdp_load @@ -1,17 +1,17 @@ cd ~/pd/packet file ~/pd/distro/pd/bin/pd.debug # file ~/pd/distro/pd/bin/pd -set args -r 44100 -alsa -frags 64 -lib pdp -nodac -noadc -path abstractions test/test_pdp_zoom2.pd +set args -r 44100 -alsa -frags 64 -lib pdp -nodac -noadc -path abstractions doc/objects/pdp_grey2mask.pd # set args -lib pdp -nodac -noadc -path abstractions test/test_pdp_thread.pd # set args -lib pdp -nodac -noadc test/test_pdp_ca.pd # set args -r 44100 -alsa -frags 64 -lib pdp -nodac -noadc test/test_pdp_qt_read.pd # dir ~/pd/distro/pd/src +dir include dir modules dir system dir system/mmx -dir scaf -dir scaf/modules -dir scaf/system +dir scaf/include +dir scaf/pdp # until i figure out how to stop pd without hanging it # or set a breakpoint before a library is loaded diff --git a/include/pdp.h b/include/pdp.h index 2695402..b19e7dc 100644 --- a/include/pdp.h +++ b/include/pdp.h @@ -63,10 +63,17 @@ typedef int bool; /* image data packet */ typedef struct { - unsigned int encoding; /* image encoding (data format ) */ - unsigned int width; /* image width in pixels */ - unsigned int height; /* image height in pixels */ - unsigned int channels; /* number of colour planes if PDP_IMAGE_MCHP */ + /* standard images */ + unsigned int encoding; /* image encoding (data format ) */ + unsigned int width; /* image width in pixels */ + unsigned int height; /* image height in pixels */ + unsigned int channels; /* number of colour planes if PDP_IMAGE_MCHP */ + + /* sliced image extensions */ /* THIS IS EXPERIMENTAL, DON'T DEPEND ON IT STATYING HERE */ + unsigned int slice_sync; /* slice synchro information */ + unsigned int slice_yoff; /* y offset of the slice in original image */ + unsigned int orig_height; /* height of original image (this is zero for ordinary images) */ + } t_image; @@ -76,6 +83,12 @@ typedef struct #define PDP_IMAGE_RGBP 3 /* 48bpp: 16 bit planar RGB */ #define PDP_IMAGE_MCHP 4 /* generic 16bit multi channel planar */ +/* slice synchro information */ +#define PDP_IMAGE_SLICE_FIRST (1<<0) +#define PDP_IMAGE_SLICE_LAST (1<<1) +#define PDP_IMAGE_SLICE_BODY (1<<2) + + /* ascii data packet */ typedef struct { @@ -106,16 +119,17 @@ typedef unsigned int t_raw; /* general pdp header struct */ typedef struct { - unsigned int type; /* datatype of this object */ - unsigned int size; /* datasize including header */ - unsigned int users; /* nb users of this object, readonly if > 1 */ - unsigned int __pad__; /* pad to quad word size */ - union + unsigned int type; /* datatype of this object */ + unsigned int size; /* datasize including header */ + unsigned int users; /* nb users of this object, readonly if > 1 */ + unsigned int reserved[1]; /* reserved to provide binary compatibility for future extensions */ + + union /* each packet type has a unique subheader */ { - t_raw raw; /* raw subheader (for extensions unkown to pdp core system) */ - t_image image; /* bitmap image */ - //t_ca ca; /* cellular automaton state data */ - t_ascii ascii; /* ascii packet */ + t_raw raw; /* raw subheader (for extensions unkown to pdp core system) */ + t_image image; /* bitmap image */ + //t_ca ca; /* cellular automaton state data */ + t_ascii ascii; /* ascii packet */ } info; } t_pdp; diff --git a/include/pdp_imageproc.h b/include/pdp_imageproc.h index 09825dc..26bcdc6 100644 --- a/include/pdp_imageproc.h +++ b/include/pdp_imageproc.h @@ -21,6 +21,7 @@ /* this is a c wrapper around platform specific (mmx) code */ +#include "pdp_types.h" #ifndef PDP_IMAGEPROC_H #define PDP_IMAGEPROC_H @@ -32,6 +33,16 @@ extern "C" #endif */ +/* get legal image dimensions */ +/* this is a fix for the dimension problem */ +/* some imageproc implementations require the dims to be a multiple of some square */ +u32 pdp_imageproc_legalwidth(int i); +u32 pdp_imageproc_legalheight(int i); +u32 pdp_imageproc_legalwidth_round_down(int i); +u32 pdp_imageproc_legalheight_round_down(int i); + + + /****************************** 16 bit signed (pixel) routines ***************************************/ #include "pdp_types.h" diff --git a/include/pdp_resample.h b/include/pdp_resample.h index cc77d04..2865cac 100644 --- a/include/pdp_resample.h +++ b/include/pdp_resample.h @@ -37,6 +37,12 @@ void pdp_resample_zoom_tiled_bilin(s16 *src_image, s16 *dst_image, s32 w, s32 h, +/* power of 2 resamplers */ +void pdp_resample_halve(s16 *src_image, s16 *dst_image, s32 src_w, s32 src_h); + + + + /* core routines */ //s32 pdp_resample_bilin(s16 *image, s32 width, s32 height, s32 virt_x, s32 virt_y); diff --git a/modules/Makefile b/modules/Makefile index 8f743aa..09a9ce3 100644 --- a/modules/Makefile +++ b/modules/Makefile @@ -2,13 +2,15 @@ current: all_modules include ../Makefile.config -OBJECTS = pdp_xv.o pdp_qt.o pdp_add.o pdp_reg.o pdp_conv.o \ - pdp_mix.o pdp_v4l.o pdp_affine.o pdp_del.o pdp_mul.o pdp_randmix.o \ +PDP_MOD = pdp_add.o pdp_reg.o pdp_conv.o \ + pdp_mix.o pdp_affine.o pdp_del.o pdp_mul.o pdp_randmix.o \ pdp_snap.o pdp_trigger.o pdp_bq.o pdp_noise.o pdp_gradient.o \ pdp_route.o pdp_gain.o pdp_grey.o pdp_chrot.o pdp_scope.o \ - pdp_scale.o pdp_zoom.o pdp_scan.o pdp_sdl.o pdp_cheby.o + pdp_scale.o pdp_zoom.o pdp_scan.o pdp_cheby.o pdp_scanxy.o \ + pdp_grey2mask.o pdp_constant.o pdp_slice_cut.o pdp_slice_glue.o -all_modules: $(OBJECTS) +# build portable and optional modules +all_modules: $(PDP_MOD) $(PDP_OPTMOD) clean: rm -f *~ diff --git a/modules/pdp_del.c b/modules/pdp_del.c index 97e47fd..50813e3 100644 --- a/modules/pdp_del.c +++ b/modules/pdp_del.c @@ -23,29 +23,19 @@ #include "pdp.h" - - - - - - - - - - - - typedef struct pdp_del_struct { - t_object x_obj; - t_float x_f; + t_object x_obj; + t_float x_f; - t_outlet *x_outlet0; + t_outlet *x_outlet0; + + t_outlet **x_outlet; - int *x_packet; - int x_order; - int x_head; - int x_delay; + int *x_packet; + int x_order; + int x_head; + int x_delay; } t_pdp_del; @@ -63,7 +53,7 @@ static void pdp_del_input_0(t_pdp_del *x, t_symbol *s, t_floatarg f) /* if this is a process message, start the processing + propagate stuff to outputs */ if (s == gensym("register_ro")){ - in = (x->x_head & (x->x_order-1)); + in = (x->x_head % x->x_order); //post("pdp_del: marking unused packed id=%d on loc %d", x->x_packet[0], in); pdp_packet_mark_unused(x->x_packet[in]); packet = pdp_packet_copy_ro((int)f); @@ -71,7 +61,7 @@ static void pdp_del_input_0(t_pdp_del *x, t_symbol *s, t_floatarg f) //post("pdp_del: writing packed id=%d on loc %d", packet, in); } else if (s == gensym("process")){ - out = ((x->x_head + x->x_delay) & (x->x_order-1)); + out = (((x->x_head + x->x_delay)) % x->x_order); packet = x->x_packet[out]; if (-1 != packet){ @@ -83,7 +73,7 @@ static void pdp_del_input_0(t_pdp_del *x, t_symbol *s, t_floatarg f) else { //post("pdp_del: packet %d is empty", out); } - x->x_head--; + x->x_head = (x->x_head + x->x_order - 1) % x->x_order; } @@ -132,39 +122,19 @@ void *pdp_del_new(t_floatarg forder, t_floatarg fdel) int i; t_pdp_del *x = (t_pdp_del *)pd_new(pdp_del_class); - del = order; order++; if (del < 0) del = 0; - - if (order <= 2) order = 2; - else { - - order--; - logorder = 1; - - while ((order | 1) != 1) { - order >>= 1; - logorder++; - } - - order = 1 << logorder; - } - - post("pdp_del: order = %d", order); + //post("pdp_del: order = %d", order); x->x_order = order; x->x_packet = (int *)malloc(sizeof(int)*order); for(i=0; i<order; i++) x->x_packet[i] = -1; - x->x_delay = del; - - inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("delay")); - x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); diff --git a/modules/pdp_gradient.c b/modules/pdp_gradient.c index 5c92e12..3af2a84 100644 --- a/modules/pdp_gradient.c +++ b/modules/pdp_gradient.c @@ -265,8 +265,11 @@ static void pdp_gradient_input_0(t_pdp_gradient *x, t_symbol *s, t_floatarg f) /* add the process method and callback to the process queue */ - - pdp_queue_add(x, pdp_gradient_process, pdp_gradient_sendpacket, &x->x_queue_id); + // since the process method creates a packet, this is not processed in the thread + // $$$TODO: fix this + //pdp_queue_add(x, pdp_gradient_process, pdp_gradient_sendpacket, &x->x_queue_id); + pdp_gradient_process(x); + pdp_gradient_sendpacket(x); } } diff --git a/modules/pdp_noise.c b/modules/pdp_noise.c index f1a4661..84f4a72 100644 --- a/modules/pdp_noise.c +++ b/modules/pdp_noise.c @@ -149,16 +149,14 @@ static void pdp_noise_bang(t_pdp_noise *x) /* release the packet */ -} +} static void pdp_noise_dim(t_pdp_noise *x, t_floatarg w, t_floatarg h) { - if (w<32.0f) w = 32.0f; - if (h<32.0f) h = 32.0f; - - x->x_width = (unsigned int)w; - x->x_height = (unsigned int)h; + x->x_width = pdp_imageproc_legalwidth((int)w); + x->x_height = pdp_imageproc_legalheight((int)h); + //post("dims %d %d", x->x_width, x->x_height); } diff --git a/modules/pdp_qt.c b/modules/pdp_qt.c index 1c778d5..8ed633d 100644 --- a/modules/pdp_qt.c +++ b/modules/pdp_qt.c @@ -19,7 +19,6 @@ */ - #include "pdp.h" #include "pdp_llconv.h" #include <quicktime/lqt.h> @@ -169,8 +168,15 @@ static void pdp_qt_close(t_pdp_qt *x) void pdp_qt_create_pdp_packet(t_pdp_qt *x) { t_pdp *header; - int nbpixels = x->x_video_width * x->x_video_height; - //int packet_size = (x->x_qt_cmodel == BC_RGB888) ? (nbpixels << 1) : (nbpixels + (nbpixels >> 1)) << 1; + + + /* round to next legal size */ + /* if size is illegal, image distortion will occur */ + u32 w = pdp_imageproc_legalwidth(x->x_video_width); + u32 h = pdp_imageproc_legalheight(x->x_video_height); + + + int nbpixels = w * h; int packet_size = (nbpixels + (nbpixels >> 1)) << 1; @@ -180,8 +186,8 @@ void pdp_qt_create_pdp_packet(t_pdp_qt *x) //header->info.image.encoding = (x->x_qt_cmodel == BC_RGB888) ? PDP_IMAGE_GREY : PDP_IMAGE_YV12; header->info.image.encoding = PDP_IMAGE_YV12; - header->info.image.width = x->x_video_width; - header->info.image.height = x->x_video_height; + header->info.image.width = w; + header->info.image.height = h; } @@ -939,3 +945,5 @@ void pdp_qt_setup(void) #ifdef __cplusplus } #endif + + diff --git a/modules/pdp_sdl.c b/modules/pdp_sdl.c index 7bd8992..d30ef84 100644 --- a/modules/pdp_sdl.c +++ b/modules/pdp_sdl.c @@ -1,6 +1,6 @@ /* * Pure Data Packet module. - * Copyright (c) by martin pi <pi@attacksyour.net> + * Copyright (c) 2003 by martin pi <pi@attacksyour.net> * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org> * * This program is free software; you can redistribute it and/or modify @@ -33,16 +33,15 @@ TODO: */ - #include <stdio.h> -#include <unistd.h> -#include <sys/ipc.h> -#include <sys/shm.h> +//#include <unistd.h> +//#include <sys/ipc.h> +//#include <sys/shm.h> #include <SDL/SDL.h> -#include <quicktime/lqt.h> -#include <quicktime/colormodels.h> +//#include <quicktime/lqt.h> +//#include <quicktime/colormodels.h> #include "pdp.h" #include "pdp_llconv.h" @@ -52,8 +51,6 @@ TODO: #define PDP_SDL_W 320 #define PDP_SDL_H 240 -#define PDP_AUTOCREATE_RETRY 3 - typedef struct pdp_sdl_struct { t_object x_obj; @@ -65,6 +62,8 @@ typedef struct pdp_sdl_struct { SDL_Surface *x_sdl_surface; SDL_Overlay *x_sdl_overlay; SDL_Rect x_sdl_rect; + + int x_xid; Uint32 x_sdl_format; @@ -74,59 +73,69 @@ typedef struct pdp_sdl_struct { unsigned int x_width; unsigned int x_height; int x_last_encoding; + int x_cursor; int x_initialized; int x_backfromthread; - int x_autocreate; - int x_fullscreen; } t_pdp_sdl; -static SDL_Surface *pdp_sdl_getSurface(char* title, int width, int height, int bits, int fullscreenflag) { +static SDL_Surface *pdp_sdl_getSurface(int xid, char* title, int width, int height, int bits, int fullscreenflag, int cursorflag) { Uint32 flags; int size,i; SDL_Surface *screen; + char SDL_hack[32]; + + /* next lines from gstreamer plugin sdlvideosink */ + if (xid < 0) unsetenv("SDL_WINDOWID"); + else { + sprintf(SDL_hack, "%d", xid); + setenv("SDL_WINDOWID", SDL_hack, 1); + } /* Initialize SDL */ if (!SDL_WasInit(SDL_INIT_VIDEO)) { if (SDL_Init (SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE)) { - printf("SDL: Initializing of SDL failed: %s.\n", SDL_GetError()); - return (SDL_Surface *)-1; + post("SDL: Initializing of SDL failed: %s.\n", SDL_GetError()); + return NULL; } - } - + /* ignore events :: only keys and wm_quit */ + for ( i=SDL_NOEVENT; i<SDL_NUMEVENTS; ++i ) + if( !(i & (SDL_KEYDOWN|SDL_VIDEORESIZE)) ) + SDL_EventState(i, SDL_IGNORE); + + } /* gem : SDL_OPENGL|SDL_DOUBLEBUF|SDL_HWSURFACE|SDL_ANYFORMAT|SDL_OPENGLBLIT; working: SDL_ANYFORMAT|SDL_RESIZABLE|SDL_RLEACCEL; */ - - flags = SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL; + flags = SDL_SWSURFACE | SDL_RESIZABLE; +// flags = SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL|SDL_ANYFORMAT|SDL_RLEACCEL; if ( fullscreenflag>0 ) { flags |= SDL_FULLSCREEN|SDL_DOUBLEBUF; } - /* Have a preference for 8-bit, but accept any depth */ screen = SDL_SetVideoMode(width, height, bits, flags); if ( screen == NULL ) { - fprintf(stderr, "Couldn't set video mode: %s\n", - SDL_GetError()); + post("Couldn't set video mode: %s\n", SDL_GetError()); return NULL; } SDL_WM_SetCaption (title, title); - /* ignore events :: only keys and wm_quit */ - for ( i=SDL_NOEVENT; i<SDL_NUMEVENTS; ++i ) - if( !(i & (SDL_KEYDOWN|SDL_QUIT)) ) - SDL_EventState(i, SDL_IGNORE); + SDL_ShowCursor(cursorflag); - SDL_ShowCursor(1); + return screen; +} - return screen; // Success +static SDL_Surface *pdp_sdl_recreateSurface(SDL_Surface *old, int xid, char* title, int width, int height, int bits, int fullscreenflag, int cursorflag) { + SDL_Surface *new = pdp_sdl_getSurface(xid, title, width, height, bits, fullscreenflag, cursorflag); + if (new != NULL) SDL_FreeSurface(old); + return new; } static inline void pdp_sdl_getOverlay(t_pdp_sdl* x) { @@ -169,30 +178,26 @@ static int pdp_sdl_drawImage(t_pdp_sdl* x, t_image *image, short int *pixels) { return 1; } -static void pdp_sdl_resize(t_pdp_sdl* x, t_floatarg width, t_floatarg height) { +static void pdp_sdl_fullscreen(t_pdp_sdl *x, t_floatarg f); - if (x->x_initialized && (!x->x_fullscreen) && (width>0) && (height>0)){ -// disabled for now -// if media size is different to the one set, it will resize (yet never dither) - } +static inline void pdp_sdl_recreate(t_pdp_sdl *x) { + x->x_sdl_surface = pdp_sdl_recreateSurface(x->x_sdl_surface, x->x_xid,"pdp-sdl", x->x_winwidth, x->x_winheight, 16, x->x_fullscreen,x->x_cursor); } -static void pdp_sdl_fullscreen(t_pdp_sdl *x, t_floatarg f); - static int pdp_sdl_create(t_pdp_sdl *x) { if (x->x_initialized){ return 0; } x->x_initialized = 0; - x->x_sdl_surface = pdp_sdl_getSurface("pdp-sdl", x->x_winwidth, x->x_winheight, 16, x->x_fullscreen); + x->x_sdl_surface = pdp_sdl_getSurface(x->x_xid, "pdp-sdl", x->x_winwidth, x->x_winheight, 16, x->x_fullscreen,x->x_cursor); if (x->x_sdl_surface != NULL) { pdp_sdl_getOverlay(x); if (x->x_sdl_overlay != NULL) { x->x_sdl_rect.x = 0; x->x_sdl_rect.y = 0; - x->x_sdl_rect.w = x->x_width; - x->x_sdl_rect.h = x->x_height; + x->x_sdl_rect.w = x->x_winwidth; + x->x_sdl_rect.h = x->x_winheight; x->x_initialized = 1; post("created successfully"); } @@ -203,12 +208,13 @@ static int pdp_sdl_create(t_pdp_sdl *x) { } static void pdp_sdl_destroy(t_pdp_sdl *x); +static void pdp_sdl_resize(t_pdp_sdl *x,t_floatarg,t_floatarg); static void pdp_sdl_checkEvents(t_pdp_sdl *x) { Uint8 *keys; SDL_Event event; - if (!SDL_PollEvent(&event)) return; + if (SDL_PollEvent(&event)!=1) return; switch( event.type ){ case SDL_KEYDOWN: @@ -224,6 +230,9 @@ static void pdp_sdl_checkEvents(t_pdp_sdl *x) { case SDL_QUIT: pdp_sdl_destroy(x); break; + case SDL_VIDEORESIZE: + pdp_sdl_resize(x,(t_floatarg)event.resize.w,(t_floatarg)event.resize.h); + break; default: break; } @@ -231,26 +240,6 @@ static void pdp_sdl_checkEvents(t_pdp_sdl *x) { } -static int pdp_sdl_try_autocreate(t_pdp_sdl *x) -{ - - if (x->x_autocreate){ - post("pdp_sdl: autocreate window"); - pdp_sdl_create(x); - if (!(x->x_initialized)){ - x->x_autocreate--; - if (!x->x_autocreate){ - post ("pdp_sdl: autocreate failed %d times: disabled", PDP_AUTOCREATE_RETRY); - post ("pdp_sdl: send [autocreate 1] message to re-enable"); - return 0; - } - } - else return 1; - - } - return 0; -} - static void pdp_sdl_bang(t_pdp_sdl *x); static void pdp_sdl_process(t_pdp_sdl *x) @@ -263,8 +252,7 @@ static void pdp_sdl_process(t_pdp_sdl *x) /* check if window is initialized */ if (!(x->x_initialized)){ - post("trying to autocreate"); - if (!pdp_sdl_try_autocreate(x)) return; + if (!pdp_sdl_create(x)) return; } /* check for pending sdl events */ @@ -296,6 +284,7 @@ static void pdp_sdl_destroy(t_pdp_sdl *x) { pdp_sdl_freeOverlay(x); SDL_FreeSurface(x->x_sdl_surface); x->x_initialized = 0; + SDL_Quit(); } } @@ -309,10 +298,8 @@ static void pdp_sdl_random(t_pdp_sdl *x) { /* redisplays image */ static void pdp_sdl_bang_thread(t_pdp_sdl *x) { -// if (x->x_sdl_overlay->pixels) { - if (SDL_DisplayYUVOverlay(x->x_sdl_overlay, &(* x).x_sdl_rect) <0) - post("pdp_sdl: __LINE__ cannot display"); -// } + if (SDL_DisplayYUVOverlay(x->x_sdl_overlay, &(* x).x_sdl_rect) <0) + post("pdp_sdl: __LINE__ cannot display"); } static void pdp_sdl_bang_callback(t_pdp_sdl *x) @@ -340,34 +327,122 @@ static void pdp_sdl_input_0(t_pdp_sdl *x, t_symbol *s, t_floatarg f) { } -static void pdp_sdl_autocreate(t_pdp_sdl *x, t_floatarg f) { - if (f != 0.0f) x->x_autocreate = PDP_AUTOCREATE_RETRY; - else x->x_autocreate = 0; +static void pdp_sdl_resize(t_pdp_sdl* x, t_floatarg width, t_floatarg height) { + + if (x->x_initialized && (!x->x_fullscreen) && (width>0) && (height>0)) { + post("should get %d/%d",(int)width,(int) height); + x->x_winwidth=(int)width; + x->x_winheight=(int)height; + pdp_sdl_recreate(x); + } } + static void pdp_sdl_fullscreen(t_pdp_sdl *x, t_floatarg f) { if (f == x->x_fullscreen) return; - x->x_fullscreen = (f != 0.0f); + x->x_fullscreen = (f != 0.0f); + x->x_cursor=0; + + pdp_sdl_recreate(x); +} + +static void pdp_sdl_cursor(t_pdp_sdl *x, t_floatarg f) { + if (f == x->x_cursor) return; + + x->x_cursor = (f != 0.0f); + SDL_ShowCursor(x->x_cursor); +} + + +/* sets new target window */ + +static void pdp_sdl_win(t_pdp_sdl *x, t_floatarg *f) { + pdp_queue_finish(x->x_queue_id); + x->x_queue_id = -1; + x->x_xid = (int)f; + pdp_sdl_recreate(x); +} + +/* be very carefule not to set DGA fro here! */ +/* use export SDL_VIDEODRIVER=dga (or equivalent for your shell) instead */ + +static void pdp_sdl_renderer(t_pdp_sdl *x, t_symbol *s) { + char SDL_hack[32]; pdp_sdl_destroy(x); + + /* next lines from gstreamer plugin sdlvideosink */ + unsetenv("SDL_VIDEODRIVER"); + + sprintf(SDL_hack, "%s", s->s_name); + setenv("SDL_VIDEODRIVER", SDL_hack, 1); + pdp_sdl_create(x); - SDL_ShowCursor(0); } static void pdp_sdl_free(t_pdp_sdl *x) { - pdp_queue_finish(x->x_queue_id); - pdp_sdl_destroy(x); - pdp_packet_mark_unused(x->x_packet0); - SDL_Quit(); + pdp_queue_finish(x->x_queue_id); + pdp_sdl_destroy(x); + pdp_packet_mark_unused(x->x_packet0); +// SDL_Quit(); +} + +static void pdp_sdl_listmodes(const char* title, Uint32 flags) { + SDL_Rect ** modes; + int i; + + /* Get available modes */ + modes = SDL_ListModes(NULL, flags); + + /* Check is there are any modes available */ + if(modes == (SDL_Rect **)0){ + printf("%s : No modes available!", title); + return; + } + + /* Check if our resolution is restricted */ + if(modes == (SDL_Rect **)-1){ + post("%s : All resolutions available.", title); + } else { + /* Print valid modes */ + for(i=0;modes[i];++i) + post("%s : %d x %d", title, modes[i]->w, modes[i]->h); + } + +} + +static void pdp_sdl_modes(t_pdp_sdl *x) { + pdp_sdl_listmodes("FULL|HWSURF|||||||||||||||||||||||||", SDL_FULLSCREEN|SDL_HWSURFACE); + pdp_sdl_listmodes("HWSURF|RESIZ|ASYNC|HWACCEL||||||||||", SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL); + pdp_sdl_listmodes("HWSURF|RESIZ|ASYNC|HWACCEL|FULL|DBUF", SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL|SDL_FULLSCREEN|SDL_DOUBLEBUF); + pdp_sdl_listmodes("OPENGL|DBUF|HWSURF|ANYF|GLBLIT||||||", SDL_OPENGL|SDL_DOUBLEBUF|SDL_HWSURFACE|SDL_ANYFORMAT|SDL_OPENGLBLIT); + pdp_sdl_listmodes("ANYF|RESIZ|RLEA|||||||||||||||||||||", SDL_ANYFORMAT|SDL_RESIZABLE|SDL_RLEACCEL); } +static void pdp_sdl_info(t_pdp_sdl *x) { + const SDL_VideoInfo *narf; + post("\nSDL video info: note that this only works under dga mode\n"); + narf = SDL_GetVideoInfo(); + post("Is it possible to create hardware surfaces?\t\thw_available=%d",narf->hw_available); + post("Is there a window manager available?\t\t\twm_available=%d",narf->wm_available); + post("Are hardware to hardware blits accelerated?\t\tblit_hw=%d",narf->blit_hw); + post("Are hardware to hardware colorkey blits accelerated?\tblit_hw_CC=%d",narf->blit_hw_CC); + post("Are hardware to hardware alpha bits accelerated?\tblit_hw_A=%d",narf->blit_hw_A); + post("Are software to hardware blits accelerated?\t\tblit_sw=%d",narf->blit_sw); + post("Are software to hardware colorkey blits accelerated?\tblit_sw_CC=%d",narf->blit_sw_CC); + post("Are software to hardware alpha blits accelerated?\tblit_sw_A=%d",narf->blit_sw_A); + post("Are color fills accelerated?\t\t\t\tblit_fill=%d",narf->blit_fill); + post("Total amount of video_mem: %d",narf->video_mem); + +} t_class *pdp_sdl_class; -void *pdp_sdl_new(void) -{ +void *pdp_sdl_new(void) { + + t_pdp_sdl *x = (t_pdp_sdl *)pd_new(pdp_sdl_class); x->x_packet0 = -1; @@ -385,9 +460,13 @@ void *pdp_sdl_new(void) x->x_backfromthread = 1; x->x_initialized = 0; - pdp_sdl_autocreate(x,1); - x->x_fullscreen = 0; + x->x_fullscreen = 0; + x->x_cursor=1; + + x->x_xid = -1; + + pdp_sdl_create(x); return (void *)x; } @@ -411,13 +490,16 @@ void pdp_sdl_setup(void) class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_bang, gensym("bang"), A_NULL); class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_random, gensym("random"), A_NULL); class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_create, gensym("create"), A_NULL); - class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_autocreate, gensym("autocreate"), A_FLOAT, A_NULL); + class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_info, gensym("info"), A_NULL); + class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_modes, gensym("modes"), A_NULL); class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_destroy, gensym("destroy"), A_NULL); class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_destroy, gensym("close"), A_NULL); -// class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_resize, gensym("dim"), A_FLOAT, A_FLOAT, A_NULL); -// class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_resize, gensym("size"), A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_resize, gensym("dim"), A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_resize, gensym("size"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_fullscreen, gensym("fullscreen"), A_FLOAT, A_NULL); -// class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_display, gensym("display"), A_SYMBOL, A_NULL); + class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_cursor, gensym("cursor"), A_FLOAT, A_NULL); + class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_win, gensym("window"), A_FLOAT, A_NULL); + class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_renderer, gensym("renderer"), A_SYMBOL, A_NULL); class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); } @@ -425,3 +507,4 @@ void pdp_sdl_setup(void) #ifdef __cplusplus } #endif + diff --git a/modules/pdp_v4l.c b/modules/pdp_v4l.c index e4dbff9..f1195c3 100644 --- a/modules/pdp_v4l.c +++ b/modules/pdp_v4l.c @@ -19,9 +19,10 @@ */ - +#include "pdp_config.h" #include "pdp.h" #include "pdp_llconv.h" +#include "pdp_imageproc.h" #include <stdio.h> #include <stdlib.h> #include <stdarg.h> @@ -45,9 +46,7 @@ // is reset when manually opened or closed #define PDP_XV_RETRIES 10 -//uncomment this for additional philips webcam control -//#define HAVE_V4LPWC -#ifdef HAVE_V4LPWC +#ifdef HAVE_PWCV4L #include "pwc-ioctl.h" #endif @@ -107,6 +106,11 @@ typedef struct pdp_v4l_struct int x_open_retry; + u32 x_minwidth; + u32 x_maxwidth; + u32 x_minheight; + u32 x_maxheight; + } t_pdp_v4l; @@ -158,7 +162,7 @@ static void pdp_v4l_pwc_init(t_pdp_v4l *x) { /* todo add detection code for pwc */ -#ifdef HAVE_V4LPWC +#ifdef HAVE_PWCV4L if(ioctl(x->x_tvfd, VIDIOCPWCRUSER)){ perror("pdp_v4l: pwc: VIDIOCPWCRUSER"); @@ -259,6 +263,7 @@ static void *pdp_v4l_thread(void *voidx) return 0; } +static void pdp_v4l_setlegaldim(t_pdp_v4l *x, int xx, int yy); static void pdp_v4l_open(t_pdp_v4l *x, t_symbol *name) { @@ -302,6 +307,12 @@ static void pdp_v4l_open(t_pdp_v4l *x, t_symbol *name) post("pdp_v4l: cap: name %s type %d channels %d maxw %d maxh %d minw %d minh %d", x->x_vcap.name, x->x_vcap.type, x->x_vcap.channels, x->x_vcap.maxwidth, x->x_vcap.maxheight, x->x_vcap.minwidth, x->x_vcap.minheight); + + x->x_minwidth = pdp_imageproc_legalwidth(x->x_vcap.minwidth); + x->x_maxwidth = pdp_imageproc_legalwidth_round_down(x->x_vcap.maxwidth); + x->x_minheight = pdp_imageproc_legalheight(x->x_vcap.minheight); + x->x_maxheight = pdp_imageproc_legalheight_round_down(x->x_vcap.maxheight); + if (ioctl(x->x_tvfd, VIDIOCGPICT, &x->x_vpicture) < 0) { @@ -376,10 +387,9 @@ static void pdp_v4l_open(t_pdp_v4l *x, t_symbol *name) goto closit; } - width = (x->x_width > (unsigned int)x->x_vcap.minwidth) ? x->x_width : (unsigned int)x->x_vcap.minwidth; - width = (width > (unsigned int)x->x_vcap.maxwidth) ?(unsigned int) x->x_vcap.maxwidth : width; - height = (x->x_height > (unsigned int)x->x_vcap.minheight) ? x->x_height :(unsigned int) x->x_vcap.minheight; - height = (height > (unsigned int)x->x_vcap.maxheight) ? (unsigned int)x->x_vcap.maxheight : height; + pdp_v4l_setlegaldim(x, x->x_width, x->x_height); + width = x->x_width; + height = x->x_height; for (i = 0; i < NBUF; i++) { @@ -633,27 +643,34 @@ static void pdp_v4l_bang(t_pdp_v4l *x) } -static void pdp_v4l_dim(t_pdp_v4l *x, t_floatarg xx, t_floatarg yy) +static void pdp_v4l_setlegaldim(t_pdp_v4l *x, int xx, int yy) { - unsigned int w,h; - xx = (xx < 0.0f) ? 0.0f : xx; - yy = (yy < 0.0f) ? 0.0f : yy; + unsigned int w,h; - w = (unsigned int)xx; - h = (unsigned int)yy; + w = pdp_imageproc_legalwidth((int)xx); + h = pdp_imageproc_legalheight((int)yy); + + w = (w < x->x_maxwidth) ? w : x->x_maxwidth; + w = (w > x->x_minwidth) ? w : x->x_minwidth; + h = (h < x->x_maxheight) ? h : x->x_maxheight; + h = (h > x->x_minheight) ? h : x->x_minheight; - if (x->x_initialized){ - pdp_v4l_close(x); x->x_width = w; x->x_height = h; +} + +static void pdp_v4l_dim(t_pdp_v4l *x, t_floatarg xx, t_floatarg yy) +{ + if (x->x_initialized){ + pdp_v4l_close(x); + pdp_v4l_setlegaldim(x, (int)xx, (int)yy); pdp_v4l_open(x, x->x_device); } else{ - x->x_width = w; - x->x_height = h; + pdp_v4l_setlegaldim(x, (int)xx, (int)yy); } } @@ -699,6 +716,12 @@ void *pdp_v4l_new(void) x->x_channel = 0; x->x_freq = -1; //don't set freq by default + x->x_minwidth = pdp_imageproc_legalwidth(0); + x->x_maxwidth = pdp_imageproc_legalwidth_round_down(0x7fffffff); + x->x_minheight = pdp_imageproc_legalheight(0); + x->x_maxheight = pdp_imageproc_legalheight_round_down(0x7fffffff); + + return (void *)x; } diff --git a/modules/pdp_xv.c b/modules/pdp_xv.c index c859a40..fde5409 100644 --- a/modules/pdp_xv.c +++ b/modules/pdp_xv.c @@ -24,9 +24,9 @@ pdp xvideo output */ - // x stuff #include <X11/Xlib.h> +#include <X11/Xatom.h> #include <X11/extensions/Xv.h> #include <X11/extensions/Xvlib.h> @@ -51,6 +51,7 @@ typedef struct pdp_xv_struct { t_object x_obj; t_float x_f; + t_outlet *x_outlet; int x_packet0; int x_queue_id; @@ -60,6 +61,7 @@ typedef struct pdp_xv_struct int x_screen; Window x_win; GC x_gc; + Atom x_WM_DELETE_WINDOW; int x_xv_format; int x_xv_port; @@ -77,6 +79,7 @@ typedef struct pdp_xv_struct int x_autocreate; float x_cursor; + t_symbol *x_dragbutton; } t_pdp_xv; @@ -122,10 +125,12 @@ void pdp_xv_create_xvimage(t_pdp_xv *x) { long size = (x->x_width * x->x_height + (((x->x_width>>1)*(x->x_height>>1))<<1)); + //post("create xvimage %d %d", x->x_width, x->x_height); x->x_data = (unsigned char *)malloc(size); x->x_xvi = XvCreateImage(x->x_dpy, x->x_xv_port, x->x_xv_format, (char *)x->x_data, x->x_width, x->x_height); x->x_last_encoding = -1; - if (!(x->x_xvi) || (!x->x_data)) post ("ERROR CREATING XVIMAGE"); + if ((!x->x_xvi) || (!x->x_data)) post ("ERROR CREATING XVIMAGE"); + //post("created xvimag data:%x xvi:%x",x->x_data,x->x_xvi); } @@ -193,6 +198,7 @@ static void pdp_xv_create(t_pdp_xv* x) XEvent e; unsigned int i; + if( x->x_initialized ){ //post("pdp_xv: window already created"); return; @@ -230,6 +236,11 @@ static void pdp_xv_create(t_pdp_xv* x) BlackPixel(x->x_dpy, x->x_screen), BlackPixel(x->x_dpy, x->x_screen)); + + /* enable handling of close window event */ + x->x_WM_DELETE_WINDOW = XInternAtom(x->x_dpy, "WM_DELETE_WINDOW", True); + (void)XSetWMProtocols(x->x_dpy, x->x_win, &x->x_WM_DELETE_WINDOW, 1); + if(!(x->x_win)){ /* clean up mess */ post("pdp_xv: could not create window\n"); @@ -243,7 +254,10 @@ static void pdp_xv_create(t_pdp_xv* x) return; } - XSelectInput(x->x_dpy, x->x_win, StructureNotifyMask); + /* select input events */ + XSelectInput(x->x_dpy, x->x_win, StructureNotifyMask + | ButtonPressMask | ButtonReleaseMask | MotionNotify | ButtonMotionMask); + XMapWindow(x->x_dpy, x->x_win); @@ -255,7 +269,10 @@ static void pdp_xv_create(t_pdp_xv* x) } + /* we're done initializing */ x->x_initialized = true; + + /* disable/enable cursor */ pdp_xv_cursor(x, x->x_cursor); } @@ -380,31 +397,104 @@ static void pdp_xv_random(t_pdp_xv *x) for(i=0; i<x->x_width*x->x_height/4; i++) intdata[i]=random(); } + /* redisplays image */ static void pdp_xv_bang_thread(t_pdp_xv *x) { - XEvent e; unsigned int i; + XEvent e; + XConfigureEvent *ce = (XConfigureEvent *)&e; + XButtonEvent *be = (XButtonEvent *)&e; + XMotionEvent *me = (XMotionEvent *)&e; + float inv_x, inv_y; + t_symbol *s; + t_atom atom[2]; + char nextdrag[]="drag0"; + char b='0'; + + inv_x = 1.0f / (float)(x->x_winwidth); + inv_y = 1.0f / (float)(x->x_winheight); - //while (XEventsQueued(x->x_dpy, QueuedAlready)){ while (XPending(x->x_dpy)){ - //post("pdp_xv: waiting for event"); + XNextEvent(x->x_dpy, &e); - //post("pdp_xv: XEvent %d", e.type); - if(e.type == ConfigureNotify){ - XConfigureEvent *ce = (XConfigureEvent *)&e; + + switch(e.type){ + case ConfigureNotify: x->x_winwidth = ce->width; x->x_winheight = ce->height; + inv_x = 1.0f / (float)(x->x_winwidth); + inv_y = 1.0f / (float)(x->x_winheight); + break; + + case ClientMessage: + if ((Atom)e.xclient.data.l[0] == x->x_WM_DELETE_WINDOW) { + post("pdp_xv: button disabled, please send a \"close\" message to close the window"); + //destroy = 1; + } + break; + + case ButtonPress: + //post("pdp_xv: press %f %f", inv_x * (float)be->x, inv_y * (float)be->y); + SETFLOAT(atom+0,inv_x * (float)be->x); + SETFLOAT(atom+1,inv_y * (float)be->y); + outlet_anything(x->x_outlet, gensym("press"), 2, atom); + switch(be->button){ + case Button1: outlet_anything(x->x_outlet, gensym("press1"), 2, atom); b='1'; break; + case Button2: outlet_anything(x->x_outlet, gensym("press2"), 2, atom); b='2'; break; + case Button3: outlet_anything(x->x_outlet, gensym("press3"), 2, atom); b='3'; break; + case Button4: outlet_anything(x->x_outlet, gensym("press4"), 2, atom); b='4'; break; + case Button5: outlet_anything(x->x_outlet, gensym("press5"), 2, atom); b='5'; break; + default: break; + } + nextdrag[4]=b; + x->x_dragbutton = gensym(nextdrag); + break; + + case ButtonRelease: + //post("pdp_xv: release %f %f", inv_x * (float)be->x, inv_y * (float)be->y); + SETFLOAT(atom+0,inv_x * (float)be->x); + SETFLOAT(atom+1,inv_y * (float)be->y); + outlet_anything(x->x_outlet, gensym("release"), 2, atom); + switch(be->button){ + case Button1: outlet_anything(x->x_outlet, gensym("release1"), 2, atom); break; + case Button2: outlet_anything(x->x_outlet, gensym("release2"), 2, atom); break; + case Button3: outlet_anything(x->x_outlet, gensym("release3"), 2, atom); break; + case Button4: outlet_anything(x->x_outlet, gensym("release4"), 2, atom); break; + case Button5: outlet_anything(x->x_outlet, gensym("release5"), 2, atom); break; + default: break; + } + break; + case MotionNotify: + //post("pdp_xv: drag %f %f", inv_x * (float)be->x, inv_y * (float)be->y); + SETFLOAT(atom+0,inv_x * (float)be->x); + SETFLOAT(atom+1,inv_y * (float)be->y); + outlet_anything(x->x_outlet, gensym("drag"), 2, atom); + outlet_anything(x->x_outlet, x->x_dragbutton, 2, atom); + break; + + default: + //post("pdp_xv: unknown event"); + break; } - //post("pdp_xv: received event"); } + // THIS SEEMS TO CRASH ON VERY LARGE IMAGES.. + //post("start"); + //post("XvPutImage xvi:%x",x->x_xvi); XvPutImage(x->x_dpy,x->x_xv_port,x->x_win,x->x_gc,x->x_xvi, 0,0,x->x_width,x->x_height, 0,0,x->x_winwidth,x->x_winheight); + //post("XFlush"); XFlush(x->x_dpy); + + //post("end"); + + + + } static void pdp_xv_bang_callback(t_pdp_xv *x) @@ -416,6 +506,11 @@ static void pdp_xv_bang_callback(t_pdp_xv *x) static void pdp_xv_bang(t_pdp_xv *x) { + /* check if window is initialized */ + if (!(x->x_initialized)){ + if (!pdp_xv_try_autocreate(x)) return; + } + /* if previous queued method returned schedule a new one, else ignore */ @@ -434,6 +529,11 @@ static void pdp_xv_input_0(t_pdp_xv *x, t_symbol *s, t_floatarg f) } +static void pdp_xv_vga(t_pdp_xv *x) +{ + pdp_xv_resize(x, 640, 480); +} + static void pdp_xv_autocreate(t_pdp_xv *x, t_floatarg f) { if (f != 0.0f) x->x_autocreate = PDP_XV_AUTOCREATE_RETRY; @@ -468,6 +568,7 @@ t_class *pdp_xv_class; void *pdp_xv_new(void) { t_pdp_xv *x = (t_pdp_xv *)pd_new(pdp_xv_class); + x->x_outlet = outlet_new(&x->x_obj, &s_anything); x->x_packet0 = -1; @@ -495,12 +596,17 @@ void *pdp_xv_new(void) x->x_last_encoding = -1; x->x_cursor = 0; + x->x_dragbutton = gensym("drag1"); + + //pdp_xv_create(x); return (void *)x; } + + #ifdef __cplusplus extern "C" { @@ -517,6 +623,7 @@ void pdp_xv_setup(void) class_addmethod(pdp_xv_class, (t_method)pdp_xv_bang, gensym("bang"), A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_random, gensym("random"), A_NULL); + class_addmethod(pdp_xv_class, (t_method)pdp_xv_create, gensym("open"), A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_create, gensym("create"), A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_autocreate, gensym("autocreate"), A_FLOAT, A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_destroy, gensym("destroy"), A_NULL); @@ -527,8 +634,13 @@ void pdp_xv_setup(void) class_addmethod(pdp_xv_class, (t_method)pdp_xv_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_cursor, gensym("cursor"), A_FLOAT, A_NULL); + /* some shortcuts for the lazy */ + class_addmethod(pdp_xv_class, (t_method)pdp_xv_vga, gensym("vga"), A_NULL); + } #ifdef __cplusplus } #endif + + diff --git a/scaf/Makefile b/scaf/Makefile index 2ac26a5..783b459 100644 --- a/scaf/Makefile +++ b/scaf/Makefile @@ -4,19 +4,39 @@ all: pdp_scaf.pd_linux pdp_scaf_all: make -C include - make -C system - make -C modules + make -C compiler + make -C rules make -C pdp clean: rm -f *~ rm -f pdp_scaf.pd_linux make -C include clean - make -C system clean - make -C modules clean + make -C compiler clean + make -C rules clean make -C pdp clean +mrproper: clean + rm -rf configure + rm -rf Makefile.config + rm -rf config.status + rm -rf config.log + rm -rf autom4te.cache pdp_scaf.pd_linux: pdp_scaf_all rm -f pdp_scaf.pd_linux - gcc -export_dynamic -shared -o pdp_scaf.pd_linux pdp/*.o system/scaf_feeder.o $(PDP_CA_LIBS) + gcc -export_dynamic -shared -o pdp_scaf.pd_linux pdp/*.o $(PDP_CA_LIBS) + +install: all + install -d $(prefix)/lib/scaf + install -m 755 compiler/scafc $(prefix)/bin + install -m 755 compiler/scafc.pl $(prefix)/lib/scaf + install -m 644 compiler/kernel.scaf $(prefix)/lib/scaf + install -m 644 compiler/scafmacro.s $(prefix)/lib/scaf + install -m 644 compiler/optim.rules $(prefix)/lib/scaf + install -m 755 rules/carules.scafo $(prefix)/lib/scaf/default.scafo + #Check if pd is installed in $(prefix)/lib/pd. + #If this fails the pdp_scaf lib and the docs won't be installed. + test -d $(prefix)/lib/pd + install -m 755 pdp_scaf.pd_linux $(prefix)/lib/pd/externs + install -m 644 doc/*.pd $(prefix)/lib/pd/doc/5.reference diff --git a/scaf/README b/scaf/README index 60ee4dd..e71d1c9 100644 --- a/scaf/README +++ b/scaf/README @@ -51,12 +51,16 @@ Requirements: Building: -Edit Makefile.config to reflect your system settings. For now this -should be the pd dir, the pdp dir and the pdp_scaf dir. - -type "make" in the top directory. Remember to type "make clean all" -after editing Makefile.config +./configure +make +make install +If you don't have both libraries in the same dir and want to keep +it that way, hardcode the paths in Makefile.config.in and run +configure. You need to do "make install" to install the scaf compiler +"scafc" and the default ruleset. This is to be able to load plain +(text) rule files and have the default rules loaded when you create +a pdp_ca object. Using: @@ -71,9 +75,9 @@ Directory structure: include/ header files pdp/ pdp external code -system/ forth system code +compiler/ forth system code test/ some test patches (cryptic doc) -modules/ ca rule libraries +rules/ ca rule libraries diff --git a/scaf/pdp/Makefile b/scaf/pdp/Makefile index 73c8892..5ec8a0d 100644 --- a/scaf/pdp/Makefile +++ b/scaf/pdp/Makefile @@ -2,7 +2,7 @@ current: all_modules include ../Makefile.config -OBJECTS = pdp_ca.o pdp_ca_system.o +OBJECTS = pdp_ca.o pdp_ca_system.o scaf_feeder.o all_modules: $(OBJECTS) diff --git a/scaf/pdp/pdp_ca.c b/scaf/pdp/pdp_ca.c index f9180cb..9724912 100644 --- a/scaf/pdp/pdp_ca.c +++ b/scaf/pdp/pdp_ca.c @@ -33,6 +33,8 @@ t_class *pdp_image2ca_class; // converter from grey/yv12 -> ca // *********************** CA CLASS STUFF ********************* +// this is defined in the makefile +// #define PDP_CA_RULES_LIB "/path/default.scafo" #define PDP_CA_STACKSIZE 256 #define PDP_CA_MODE_1D 1 @@ -64,6 +66,7 @@ typedef struct pdp_ca_struct char *x_ca_rulenames; int x_ca_nbrules; char ** x_ca_rulename; + t_symbol *x_lastrule; /* nb of iterations */ int x_iterations; @@ -477,6 +480,7 @@ static void pdp_ca_rule_string(t_pdp_ca *x, char *c) /* ok, so store routine address */ else{ x->x_ca_routine = ca_routine; + x->x_lastrule = gensym(c); } } @@ -503,7 +507,7 @@ static void pdp_ca_rule_index(t_pdp_ca *x, t_float f) /* set rule by index */ pdp_ca_rule_string(x, x->x_ca_rulename[i]); - + } @@ -534,7 +538,8 @@ static void pdp_ca_printrules(t_pdp_ca *x) } -static void pdp_ca_open(t_pdp_ca *x, t_symbol *s) +/* open code library */ +static void pdp_ca_openlib(t_pdp_ca *x, t_symbol *s) { char *c; @@ -545,8 +550,9 @@ static void pdp_ca_open(t_pdp_ca *x, t_symbol *s) /* try to open new lib */ if (!(x->x_ca_libhandle = dlopen(s->s_name, RTLD_NOW))){ - post("pdp_ca: can't open ca library %s, %s", s->s_name, dlerror()); + post("pdp_ca: can't open ca library %s\n%s", s->s_name, dlerror()); x->x_ca_libhandle = 0; + return; } /* scan for valid rules */ @@ -579,10 +585,59 @@ static void pdp_ca_open(t_pdp_ca *x, t_symbol *s) /* print rule names */ //pdp_ca_printrules(x); + /* set last selected rule */ + pdp_ca_rule(x, x->x_lastrule); } +/* compile source file and open resulting code library */ +static void pdp_ca_opensrc(t_pdp_ca *x, t_symbol *s) +{ + #define TMPSIZE 1024 + char commandline[TMPSIZE]; + char library[TMPSIZE]; + int status; + + /* setup compiler args */ + snprintf(library, TMPSIZE, "%so", s->s_name); + snprintf(commandline, TMPSIZE, "scafc %s %s", s->s_name, library); + + + + /* call compiler */ + if (system(commandline)) + { + post ("pdp_ca: error compiling %s", s->s_name); + } + else + { + post("pdp_ca: compiled %s", s->s_name); + pdp_ca_openlib(x, gensym(library)); + } +} + +/* open a source file or a library, depending on extension */ +static void pdp_ca_open(t_pdp_ca *x, t_symbol *s) +{ + char *name = s->s_name; + char *end = name; + while(*end) end++; + if (end == name){ + post("pdp_ca: invalid file name"); + return; + } + /* if the name ends with 'o' assume it is a library */ + if (end[-1] == 'o'){ + pdp_ca_openlib(x, s); + } + /* otherwize, assume it is a source file */ + else{ + pdp_ca_opensrc(x, s); + } + +} + /* init the current packet with random noise */ static void pdp_ca_rand(t_pdp_ca *x){ @@ -736,6 +791,8 @@ void *pdp_ca_new(void) pdp_ca_fullscreen1d(x, 0); x->x_packet_type = gensym("grey"); + x->x_lastrule = gensym("gameoflife"); + pdp_ca_openlib(x, gensym(PDP_CA_RULES_LIB)); return (void *)x; } @@ -878,9 +935,12 @@ void pdp_ca_setup(void) class_addmethod(pdp_ca_class, (t_method)pdp_ca_printrules, gensym("rules"), A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_rand, gensym("random"), A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_newca, gensym("ca"), A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(pdp_ca_class, (t_method)pdp_ca_newca, gensym("dim"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_horshift16, gensym("hshift16"), A_FLOAT, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_vershift, gensym("vshift"), A_FLOAT, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_close, gensym("close"), A_NULL); + class_addmethod(pdp_ca_class, (t_method)pdp_ca_openlib, gensym("openlib"), A_SYMBOL, A_NULL); + class_addmethod(pdp_ca_class, (t_method)pdp_ca_opensrc, gensym("opensrc"), A_SYMBOL, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_open, gensym("open"), A_SYMBOL, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_rule, gensym("rule"), A_SYMBOL, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_rule_index, gensym("ruleindex"), A_FLOAT, A_NULL); diff --git a/system/Makefile b/system/Makefile index acdb944..227e72e 100644 --- a/system/Makefile +++ b/system/Makefile @@ -1,20 +1,30 @@ -target: all_objects + +OBJECTS = pdp.o pdp_ut.o pdp_packet.o pdp_type.o pdp_queue.o pdp_comm.o \ + pdp_control.o pdp_llconv.o pdp_resample.o + +OBJECTS_MMX = pdp_imageproc_mmx.o pdp_llconv_mmx.o +OBJECTS_PORTABLE = pdp_imageproc_portable.o pdp_llconv_portable.o + + include ../Makefile.config -include Makefile.$(PDP_TARGET) +all: $(PDP_TARGET) common_objects -OBJECTS = pdp.o pdp_ut.o pdp_packet.o pdp_type.o pdp_queue.o pdp_comm.o \ - pdp_control.o pdp_llconv.o pdp_resample.o +linux_mmx: $(OBJECTS_MMX) + make -C mmx + +linux: $(OBJECTS_PORTABLE) + +darwin: $(OBJECTS_PORTABLE) pdp_main_clean: rm -f pdp.o -all_objects: pdp_main_clean $(OBJECTS) platform_targets +common_objects: pdp_main_clean $(OBJECTS) clean: rm -f *~ rm -f *.o make -C mmx clean - diff --git a/system/pdp.c b/system/pdp.c index e3c311b..5475c8d 100644 --- a/system/pdp.c +++ b/system/pdp.c @@ -18,7 +18,7 @@ * */ - +#include "pdp_config.h" #include "pdp.h" #include <stdio.h> @@ -63,8 +63,13 @@ void pdp_scope_setup(void); void pdp_scale_setup(void); void pdp_zoom_setup(void); void pdp_scan_setup(void); +void pdp_scanxy_setup(void); void pdp_sdl_setup(void); void pdp_cheby_setup(void); +void pdp_grey2mask_setup(void); +void pdp_constant_setup(void); +void pdp_slice_cut_setup(void); +void pdp_slice_glue_setup(void); @@ -92,9 +97,6 @@ void pdp_setup(void){ pdp_mul_setup(); pdp_mix_setup(); pdp_randmix_setup(); - pdp_xv_setup(); - pdp_qt_setup(); - pdp_v4l_setup(); pdp_reg_setup(); pdp_conv_setup(); pdp_bq_setup(); @@ -112,9 +114,34 @@ void pdp_setup(void){ pdp_scale_setup(); pdp_zoom_setup(); pdp_scan_setup(); - pdp_sdl_setup(); + pdp_scanxy_setup(); pdp_cheby_setup(); + pdp_grey2mask_setup(); + pdp_constant_setup(); + + + /* experimental stuff */ + pdp_slice_cut_setup(); + pdp_slice_glue_setup(); + + + /* optional modules */ + +#ifdef HAVE_PDP_QT + pdp_qt_setup(); +#endif + +#ifdef HAVE_PDP_XV + pdp_xv_setup(); +#endif +#ifdef HAVE_PDP_SDL + pdp_sdl_setup(); +#endif + +#ifdef HAVE_PDP_V4L + pdp_v4l_setup(); +#endif } diff --git a/system/pdp_imageproc_mmx.c b/system/pdp_imageproc_mmx.c index 4c347c6..fde790f 100644 --- a/system/pdp_imageproc_mmx.c +++ b/system/pdp_imageproc_mmx.c @@ -26,6 +26,36 @@ #include "pdp_imageproc.h" #include "m_pd.h" +/* round image dims to next multiple of 8 */ +u32 pdp_imageproc_legalwidth(int i) +{ + if (i>1024) return 1024; + if (i>0) return ((((i-1)>>3)+1)<<3); + return 8; + +} + +u32 pdp_imageproc_legalheight(int i) +{ + if (i>1024) return 1024; + if (i>0) return ((((i-1)>>3)+1)<<3); + return 8; +} +u32 pdp_imageproc_legalwidth_round_down(int i) +{ + if (i>1024) return 1024; + if (i>8) return ((i>>3)<<3); + return 8; + +} + +u32 pdp_imageproc_legalheight_round_down(int i) +{ + if (i>1024) return 1024; + if (i>8) return ((i>>3)<<3); + return 8; +} + // utility stuff inline static s16 float2fixed(float f) { diff --git a/system/pdp_imageproc_portable.c b/system/pdp_imageproc_portable.c index 6feddd3..86b91b8 100644 --- a/system/pdp_imageproc_portable.c +++ b/system/pdp_imageproc_portable.c @@ -24,6 +24,24 @@ #include <math.h> #include "pdp_imageproc.h" +/* all image dims are legal */ +u32 pdp_imageproc_legalwidth(int i) +{ + if (i>1024) return 1024; + if (i>0) return i; + return 1; +} + +u32 pdp_imageproc_legalheight(int i) +{ + if (i>1024) return 1024; + if (i>0) return i; + return 1; +} +u32 pdp_imageproc_legalwidth_round_down(int i) {return pdp_imageproc_legalwidth(i);} +u32 pdp_imageproc_legalheight_round_down(int i) {return pdp_imageproc_legalheight(i);} + + // utility stuff inline static s32 float2fixed(float f) { diff --git a/system/pdp_packet.c b/system/pdp_packet.c index 0c0b2c2..894c443 100644 --- a/system/pdp_packet.c +++ b/system/pdp_packet.c @@ -80,10 +80,13 @@ pdp_packet_new(unsigned int datatype, unsigned int datasize /*without header*/) /* remark: if p->size >= totalsize we can give away the packet */ /* but that would lead to unefficient use if we have a lot of packets */ /* of different sizes */ - if ((p->users == 0) && (p->size == totalsize) && (p->type == datatype)){ + if ((p->users == 0) && (p->size == totalsize)){ //post("pdp_new_object: can reuse %d", i); - p->users = 1; - return i; + memset(p, 0, PDP_HEADER_SIZE); //initialize header to 0 + p->type = datatype; + p->size = totalsize; + p->users = 1; + return i; } else{ //post("pdp_new_object: can't reuse %d, (%d users)", i, p->users); @@ -96,6 +99,7 @@ pdp_packet_new(unsigned int datatype, unsigned int datasize /*without header*/) align = ((unsigned int)p) & (PDP_ALIGN - 1); if (align) post("pdp_new_object: warning data misaligned by %x", align); pdp_stack[i] = p; + memset(p, 0, PDP_HEADER_SIZE); //initialize header to 0 p->type = datatype; p->size = totalsize; p->users = 1; diff --git a/system/pdp_resample.c b/system/pdp_resample.c index 12bc639..16a34df 100644 --- a/system/pdp_resample.c +++ b/system/pdp_resample.c @@ -137,3 +137,34 @@ void pdp_resample_zoom_tiled_bilin(s16 *src_image, s16 *dst_image, s32 w, s32 h, } */ + + +void pdp_resample_halve(s16 *src_image, s16 *dst_image, s32 src_w, s32 src_h) +{ + + int dst_x,dst_y; + int src_x = 0; + int src_y = 0; + int dst_w = src_w >> 1; + int dst_h = src_h >> 1; + s32 tmp1,tmp2,tmp3,tmp4; + + for(dst_y = 0; dst_y < dst_h * dst_w; dst_y += dst_w){ + for (dst_x = 0; dst_x < dst_w; dst_x++){ + + tmp1 = (s32)src_image[src_y + src_x]; + tmp2 = (s32)src_image[src_y + src_x + 1]; + tmp3 = (s32)src_image[src_y + src_x + src_w]; + tmp4 = (s32)src_image[src_y + src_x + src_w + 1]; + + tmp1 += tmp2; + tmp3 += tmp4; + + src_x += 2; + + dst_image[dst_x+dst_y] = (s16)((tmp1 + tmp3)>>2); + } + src_y += src_w << 1; + src_x = 0; + } +} |