diff options
author | Tom Schouten <doelie@users.sourceforge.net> | 2003-02-05 06:05:39 +0000 |
---|---|---|
committer | Tom Schouten <doelie@users.sourceforge.net> | 2003-02-05 06:05:39 +0000 |
commit | 7da1d644ff98078ad2a78d940ec991abff440b00 (patch) | |
tree | cd5942bd3be84b57228d4d978ec4753dbdc56a89 /modules | |
parent | 41faefa9874e70af29f1ad5ebc2a55f0be9a9cff (diff) |
pdp 0.8.3
svn path=/trunk/externals/pdp/; revision=382
Diffstat (limited to 'modules')
-rw-r--r-- | modules/Makefile | 2 | ||||
-rw-r--r-- | modules/pdp_cheby.c | 233 | ||||
-rw-r--r-- | modules/pdp_mul.c | 5 | ||||
-rw-r--r-- | modules/pdp_route.c | 2 | ||||
-rw-r--r-- | modules/pdp_scan.c | 231 | ||||
-rw-r--r-- | modules/pdp_sdl.c | 427 | ||||
-rw-r--r-- | modules/pdp_zoom.c | 112 |
7 files changed, 971 insertions, 41 deletions
diff --git a/modules/Makefile b/modules/Makefile index 3b5d402..8f743aa 100644 --- a/modules/Makefile +++ b/modules/Makefile @@ -6,7 +6,7 @@ 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_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_scale.o pdp_zoom.o pdp_scan.o pdp_sdl.o pdp_cheby.o all_modules: $(OBJECTS) diff --git a/modules/pdp_cheby.c b/modules/pdp_cheby.c new file mode 100644 index 0000000..4ba32a3 --- /dev/null +++ b/modules/pdp_cheby.c @@ -0,0 +1,233 @@ +/* + * 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_mmx.h" + + +typedef struct pdp_cheby_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + + int x_packet0; + int x_queue_id; + int x_dropped; // indicate if a packet was dropped during register_rw cycle + + int x_channel; + + void *x_cheby; + + int x_iterations; + int x_order; + +} t_pdp_cheby; + + + +static void pdp_cheby_process_yv12(t_pdp_cheby *x) +{ + t_pdp *header0 = pdp_packet_header(x->x_packet0); + void *data0 = pdp_packet_data (x->x_packet0); + + unsigned int w = header0->info.image.width; + unsigned int h = header0->info.image.height; + + unsigned int size = w*h; + unsigned int v_offset = size; + unsigned int u_offset = size + (size >> 2) ; + unsigned int i,j; + + short int * idata = (short int *)data0; + int ch = x->x_channel; + + if((ch == 0) || (ch==1)) pdp_imageproc_cheby_process(x->x_cheby, &idata[0], w, h, x->x_iterations ); + if((ch == 0) || (ch==2)) pdp_imageproc_cheby_process(x->x_cheby, &idata[v_offset], w>>1, h>>1, x->x_iterations); + if((ch == 0) || (ch==3)) pdp_imageproc_cheby_process(x->x_cheby, &idata[u_offset], w>>1, h>>1, x->x_iterations); + + return; + + +} + +static void pdp_cheby_process_grey(t_pdp_cheby *x) +{ + t_pdp *header0 = pdp_packet_header(x->x_packet0); + void *data0 = pdp_packet_data (x->x_packet0); + + unsigned int w = header0->info.image.width; + unsigned int h = header0->info.image.height; + + short int * idata = (short int *)data0; + int ch = x->x_channel; + + if((ch == 0) || (ch==1)) pdp_imageproc_cheby_process(x->x_cheby, &idata[0], w, h, x->x_iterations); + + return; + + +} + +static void pdp_cheby_process(t_pdp_cheby *x) +{ + t_pdp *header0 = pdp_packet_header(x->x_packet0); + + /* check data packets */ + + if ((header0) && (PDP_IMAGE == header0->type)){ + + /* pdp_cheby_process inputs and write into active inlet */ + switch(header0->info.image.encoding){ + + case PDP_IMAGE_YV12: + pdp_cheby_process_yv12(x); + break; + + case PDP_IMAGE_GREY: + pdp_cheby_process_grey(x); + break; + + default: + break; + /* don't know the type, so dont pdp_cheby_process */ + + } + } + +} + +static void pdp_cheby_sendpacket(t_pdp_cheby *x) +{ + /* unregister and propagate if valid packet */ + pdp_pass_if_valid(x->x_outlet0, &x->x_packet0); +} + +static void pdp_cheby_input_0(t_pdp_cheby *x, t_symbol *s, t_floatarg f) +{ + + int p = (int)f; + + if (s== gensym("register_rw")) x->x_dropped = pdp_packet_copy_rw_or_drop(&x->x_packet0, p); + + + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + + /* add the process method and callback to the process queue */ + + pdp_queue_add(x, pdp_cheby_process, pdp_cheby_sendpacket, &x->x_queue_id); + } + +} + + + +static void pdp_cheby_coef(t_pdp_cheby *x, t_floatarg c, t_floatarg f) +{ + pdp_imageproc_cheby_setcoef(x->x_cheby, (int)c, f); +} + +static void pdp_cheby_reset(t_pdp_cheby *x) +{ + int i; + for (i = 0; i <= x->x_order; i++) + pdp_imageproc_cheby_setcoef(x->x_cheby, i, 0); +} + +static void pdp_cheby_channel(t_pdp_cheby *x, t_floatarg f) +{ + int ch = (int)f; + if ((ch < 1) || (ch > 3)) ch = 0; + x->x_channel = ch; +} + +static void pdp_cheby_iterations(t_pdp_cheby *x, t_floatarg f) +{ + int i = (int)f; + if (i<0) i = 0; + x->x_iterations = i; + +} +static void pdp_cheby_free(t_pdp_cheby *x) +{ + pdp_queue_finish(x->x_queue_id); + pdp_imageproc_cheby_delete(x->x_cheby); + pdp_packet_mark_unused(x->x_packet0); + +} + +t_class *pdp_cheby_class; + + + +void *pdp_cheby_new(t_floatarg f) +{ + t_pdp_cheby *x = (t_pdp_cheby *)pd_new(pdp_cheby_class); + int order = (int)(f); + + if (order < 2) order = 2; + + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("iterations")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet0 = -1; + x->x_queue_id = -1; + + x->x_cheby = pdp_imageproc_cheby_new(order); + + // default: process all channels + x->x_channel = 0; + x->x_iterations = 1; + x->x_order = order; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_cheby_setup(void) +{ + + + pdp_cheby_class = class_new(gensym("pdp_cheby"), (t_newmethod)pdp_cheby_new, + (t_method)pdp_cheby_free, sizeof(t_pdp_cheby), 0, A_DEFFLOAT, A_NULL); + + + class_addmethod(pdp_cheby_class, (t_method)pdp_cheby_coef, gensym("coef"), A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(pdp_cheby_class, (t_method)pdp_cheby_iterations, gensym("iterations"), A_FLOAT, A_NULL); + class_addmethod(pdp_cheby_class, (t_method)pdp_cheby_channel, gensym("chan"), A_FLOAT, A_NULL); + class_addmethod(pdp_cheby_class, (t_method)pdp_cheby_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_cheby_class, (t_method)pdp_cheby_reset, gensym("reset"), A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_mul.c b/modules/pdp_mul.c index 8c06087..822a862 100644 --- a/modules/pdp_mul.c +++ b/modules/pdp_mul.c @@ -70,15 +70,10 @@ static void pdp_mul_process_grey(t_pdp_mul *x) unsigned int w = header0->info.image.width; unsigned int h = header0->info.image.height; - // set hight so it includes the chroma frames - h = h + (h>>1); pdp_imageproc_mul_process((short int*)data0, (short int*)data1, w, h); return; - - - } static void pdp_mul_process(t_pdp_mul *x) diff --git a/modules/pdp_route.c b/modules/pdp_route.c index 7b0a0a9..02197ad 100644 --- a/modules/pdp_route.c +++ b/modules/pdp_route.c @@ -116,7 +116,7 @@ void pdp_route_setup(void) pdp_route_class = class_new(gensym("pdp_route"), (t_newmethod)pdp_route_new, - (t_method)pdp_route_free, sizeof(t_pdp_route), 0, A_FLOAT, A_NULL); + (t_method)pdp_route_free, sizeof(t_pdp_route), 0, A_DEFFLOAT, A_NULL); class_addmethod(pdp_route_class, (t_method)pdp_route_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); diff --git a/modules/pdp_scan.c b/modules/pdp_scan.c new file mode 100644 index 0000000..49a985c --- /dev/null +++ b/modules/pdp_scan.c @@ -0,0 +1,231 @@ +/* + * 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_mmx.h" +#include <math.h> + +#define PDP_SCAN_COSTABLE_SIZE 1024 +static float pdp_cos[PDP_SCAN_COSTABLE_SIZE]; + +typedef struct pdp_scan_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + t_outlet *x_outlet1; + + float x_centerx; + float x_centery; + float x_sizeh; + float x_sizev; + + int x_packet0; + int x_packet1; + + int x_interpolate; + + +} t_pdp_scan; + + +static t_int *pdp_scan_perform(t_int *w) +{ + + t_pdp_scan *x = (t_pdp_scan *)(w[1]); + t_int n = (t_int)(w[2]); + t_float *in = (float *)(w[3]); + t_float *out = (float *)(w[4]); + + + /* check if valid image */ + if (-1 == x->x_packet0){ + while (n--) *out++ = 0; + return (w+5); + } + else{ + + t_pdp *header0 = pdp_packet_header(x->x_packet0); + short int *data0 = (short int *)pdp_packet_data (x->x_packet0); + short int *data1 = (short int *)pdp_packet_data (x->x_packet1); + int width = (float)header0->info.image.width; + float widthm1 = (float)header0->info.image.width - 1; + float heightm1 = (float)header0->info.image.height - 1; + int i; + + float scale = 1.0f / 32767.0f; + + if (x->x_interpolate && (-1 != x->x_packet1)){ + float a_old = 1.0f; + float a_new = 0.0f; + float a_inc = 1.0f / (float)n; + float old, new; + + while(n--){ + float phase = *in++; + int iphase = (int)(phase * PDP_SCAN_COSTABLE_SIZE); + float c = pdp_cos[iphase & (PDP_SCAN_COSTABLE_SIZE - 1)]; + float s = pdp_cos[(iphase - (PDP_SCAN_COSTABLE_SIZE>>1)) & (PDP_SCAN_COSTABLE_SIZE - 1)]; + int xxx = (int)((x->x_centerx + x->x_sizeh * c) * widthm1); + int yyy = (int)((x->x_centery + x->x_sizev * c) * heightm1); + int offset = yyy*width+xxx; + new = ((float)(data0[offset])) * scale; + old = ((float)(data1[offset])) * scale; + *out++ = a_old * old + a_new * new; + a_new += a_inc; + a_old -= a_inc; + } + + pdp_packet_mark_unused(x->x_packet1); + x->x_packet1 = -1; + } + else{ + while(n--){ + float phase = *in++; + int iphase = (int)(phase * PDP_SCAN_COSTABLE_SIZE); + float c = pdp_cos[iphase & (PDP_SCAN_COSTABLE_SIZE - 1)]; + float s = pdp_cos[(iphase - (PDP_SCAN_COSTABLE_SIZE>>1)) & (PDP_SCAN_COSTABLE_SIZE - 1)]; + int xxx = (int)((x->x_centerx + x->x_sizeh * c) * widthm1); + int yyy = (int)((x->x_centery + x->x_sizev * c) * heightm1); + *out++ = ((float)(data0[yyy*width+xxx])) * scale; + } + } + + return (w+5); + + } +} + + + + +static void pdp_scan_input_0(t_pdp_scan *x, t_symbol *s, t_floatarg f) +{ + int packet = (int)f; + + /* register */ + if (s== gensym("register_ro")){ + t_pdp *header = pdp_packet_header(packet); + if (!header) return; + if (PDP_IMAGE != header->type) return; + if ((header->info.image.encoding != PDP_IMAGE_YV12) && (header->info.image.encoding != PDP_IMAGE_GREY)) return; + + /* replace if not compatible or we are not interpolating */ + if (!x->x_interpolate || (!pdp_type_compat_image(x->x_packet0, packet))){ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = pdp_packet_copy_ro(packet); + } + /* otherwize keep the old one */ + else{ + pdp_packet_mark_unused(x->x_packet1); + x->x_packet1 = x->x_packet0; + x->x_packet0 = pdp_packet_copy_ro(packet); + } + } + + /* pass packet */ + if (s== gensym("process")){ + //if (-1 != x->x_packet0) outlet_pdp (x->x_outlet0, x->x_packet0); + } + + +} + + + + +static void pdp_scan_dsp (t_pdp_scan *x, t_signal **sp) +{ + dsp_add(pdp_scan_perform, 4, x, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec); + +} + + +static void pdp_scan_interpolate(t_pdp_scan *x, t_floatarg f) +{ + if (0.0 == f){ + x->x_interpolate = 0; + pdp_packet_mark_unused(x->x_packet1); + } + if (1.0 == f) x->x_interpolate = 1; +} + +static void pdp_scan_free(t_pdp_scan *x) +{ + pdp_packet_mark_unused(x->x_packet0); +} + + +t_class *pdp_scan_class; + + + +void *pdp_scan_new(void) +{ + t_pdp_scan *x = (t_pdp_scan *)pd_new(pdp_scan_class); + + + //x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + x->x_outlet1 = outlet_new(&x->x_obj, &s_signal); + x->x_packet0 = -1; + x->x_packet1 = -1; + + x->x_centerx = 0.5f; + x->x_centery = 0.5f; + x->x_sizeh = 0.3; + x->x_sizev = 0.3; + + pdp_scan_interpolate(x, 0); + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_scan_setup(void) +{ + int i; + for (i=0; i<PDP_SCAN_COSTABLE_SIZE; i++) + pdp_cos[i] = cos((double)(i) * 2 * M_PI / PDP_SCAN_COSTABLE_SIZE); + + + pdp_scan_class = class_new(gensym("pdp_scan~"), (t_newmethod)pdp_scan_new, + (t_method)pdp_scan_free, sizeof(t_pdp_scan), 0, A_NULL); + + CLASS_MAINSIGNALIN(pdp_scan_class, t_pdp_scan, x_f); + + class_addmethod(pdp_scan_class, (t_method)pdp_scan_interpolate, gensym("interpolate"), A_FLOAT, A_NULL); + class_addmethod(pdp_scan_class, (t_method)pdp_scan_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_scan_class, (t_method)pdp_scan_dsp, gensym("dsp"), A_NULL); + + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_sdl.c b/modules/pdp_sdl.c new file mode 100644 index 0000000..7bd8992 --- /dev/null +++ b/modules/pdp_sdl.c @@ -0,0 +1,427 @@ +/* + * Pure Data Packet module. + * Copyright (c) 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 + * 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. + * + */ + +/* + +pdp sdl output + +DONE: + +TODO: + * close window (event) + * fullscreen chose resolution + * event handling in different object (and look at mplayer for that!) + +*/ + + + +#include <stdio.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 "pdp.h" +#include "pdp_llconv.h" + + +/* initial image dimensions */ +#define PDP_SDL_W 320 +#define PDP_SDL_H 240 + +#define PDP_AUTOCREATE_RETRY 3 + + +typedef struct pdp_sdl_struct { + t_object x_obj; + t_float x_f; + + int x_packet0; + int x_queue_id; + + SDL_Surface *x_sdl_surface; + SDL_Overlay *x_sdl_overlay; + SDL_Rect x_sdl_rect; + + Uint32 x_sdl_format; + + int x_winwidth; + int x_winheight; + + unsigned int x_width; + unsigned int x_height; + int x_last_encoding; + + 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) { + Uint32 flags; + int size,i; + SDL_Surface *screen; + + /* 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; + } + } + + + +/* +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; + 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()); + 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(1); + + return screen; // Success +} + +static inline void pdp_sdl_getOverlay(t_pdp_sdl* x) { + x->x_sdl_overlay = SDL_CreateYUVOverlay(x->x_width, x->x_height, x->x_sdl_format, x->x_sdl_surface); +} + +static inline void pdp_sdl_freeOverlay(t_pdp_sdl* x) { + SDL_FreeYUVOverlay(x->x_sdl_overlay); +} + +static int pdp_sdl_drawImage(t_pdp_sdl* x, t_image *image, short int *pixels) { + + unsigned int width = image->width; + unsigned int height = image->height; + int encoding = image->encoding; + unsigned int* uintdata; + int i; + + + /* 8bit y fulscale and 8bit u,v 2x2 subsampled */ + //static short int gain[4] = {0x0100, 0x0100, 0x0100, 0x0100}; + int nbpixels = width * height; + long size = (width * height + (((width>>1)*(height>>1))<<1)); + + /* check if xvimage needs to be recreated */ + if ((width != x->x_width) || (height != x->x_height)){ + post("pdp_xv: replace image"); + x->x_width = width; + x->x_height = height; + pdp_sdl_freeOverlay(x); + pdp_sdl_getOverlay(x); + } + + SDL_LockYUVOverlay(x->x_sdl_overlay); + if (pixels) { + pdp_llconv(pixels,RIF_YVU__P411_S16, (Uint8 *)(* x->x_sdl_overlay->pixels), RIF_YVU__P411_U8, x->x_width, x->x_height); + } else bzero((Uint8 *)(* x->x_sdl_overlay->pixels), size); + SDL_UnlockYUVOverlay(x->x_sdl_overlay); + + return 1; +} + +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)){ +// disabled for now +// if media size is different to the one set, it will resize (yet never dither) + } +} + +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); + 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_initialized = 1; + post("created successfully"); + } + } + x->x_backfromthread = 1; + + return x->x_initialized; +} + +static void pdp_sdl_destroy(t_pdp_sdl *x); + +static void pdp_sdl_checkEvents(t_pdp_sdl *x) { + Uint8 *keys; + SDL_Event event; + + if (!SDL_PollEvent(&event)) return; + + switch( event.type ){ + case SDL_KEYDOWN: + case SDL_KEYUP: + keys = SDL_GetKeyState(NULL); + + if(keys[SDLK_UP]) { post("up"); } + if(keys[SDLK_DOWN]) { post("down"); } + + if(keys[SDLK_ESCAPE]) pdp_sdl_fullscreen(x,0); + break; + + case SDL_QUIT: + pdp_sdl_destroy(x); + break; + default: + break; + } + + +} + +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) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + void *data = pdp_packet_data (x->x_packet0); + + + if (!x->x_backfromthread) return; + + /* check if window is initialized */ + if (!(x->x_initialized)){ + post("trying to autocreate"); + if (!pdp_sdl_try_autocreate(x)) return; + } + + /* check for pending sdl events */ + pdp_sdl_checkEvents(x); + + /* check data packet */ + if (!(header)) { + post("pdp_sdl: invalid packet header"); + return; + } + if (PDP_IMAGE != header->type) { + post("pdp_sdl: packet is not a PDP_IMAGE"); + return; + } + if (header->info.image.encoding != PDP_IMAGE_YV12) { + post("pdp_sdl: packet is not a PDP_IMAGE_YV12"); + return; + } + + /* copy the packet to the sdlimage */ + pdp_sdl_drawImage(x, &header->info.image, (short int *)data); + + /* display the new image */ + pdp_sdl_bang(x); +} + +static void pdp_sdl_destroy(t_pdp_sdl *x) { + if (x->x_initialized){ + pdp_sdl_freeOverlay(x); + SDL_FreeSurface(x->x_sdl_surface); + x->x_initialized = 0; + } +} + +static void pdp_sdl_random(t_pdp_sdl *x) { + unsigned int i; + long *intdata = (long *)(* x->x_sdl_overlay->pixels); + SDL_LockYUVOverlay(x->x_sdl_overlay); + for(i=0; i<x->x_width*x->x_height/4; i++) intdata[i]=random(); + SDL_UnlockYUVOverlay(x->x_sdl_overlay); +} + +/* 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"); +// } +} + +static void pdp_sdl_bang_callback(t_pdp_sdl *x) +{ + x->x_backfromthread = 1; + + /* release the packet if there is one */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1;} + +static void pdp_sdl_bang(t_pdp_sdl *x) { + + /* if previous queued method returned + schedule a new one, else ignore */ + if (x->x_backfromthread) { + x->x_backfromthread = 0; + pdp_queue_add(x, pdp_sdl_bang_thread, pdp_sdl_bang_callback, &x->x_queue_id); + } +} + +static void pdp_sdl_input_0(t_pdp_sdl *x, t_symbol *s, t_floatarg f) { + + if (s == gensym("register_ro")) pdp_packet_copy_ro_or_drop(&x->x_packet0, (int)f); + if (s == gensym("process")) pdp_sdl_process(x); + +} + +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_fullscreen(t_pdp_sdl *x, t_floatarg f) { + if (f == x->x_fullscreen) return; + + x->x_fullscreen = (f != 0.0f); + + pdp_sdl_destroy(x); + 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(); +} + + +t_class *pdp_sdl_class; + +void *pdp_sdl_new(void) +{ + t_pdp_sdl *x = (t_pdp_sdl *)pd_new(pdp_sdl_class); + + x->x_packet0 = -1; + x->x_queue_id = -1; + + x->x_sdl_surface = NULL; + x->x_sdl_overlay = NULL; + x->x_sdl_format = SDL_YV12_OVERLAY; + + x->x_winwidth = PDP_SDL_W; + x->x_winheight = PDP_SDL_H; + + x->x_width = PDP_SDL_W; + x->x_height = PDP_SDL_H; + + x->x_backfromthread = 1; + x->x_initialized = 0; + pdp_sdl_autocreate(x,1); + + x->x_fullscreen = 0; + + return (void *)x; +} + + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_sdl_setup(void) +{ + + + pdp_sdl_class = class_new(gensym("pdp_sdl"), (t_newmethod)pdp_sdl_new, + (t_method)pdp_sdl_free, sizeof(t_pdp_sdl), 0, A_NULL); + + + 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_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_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_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/pdp_zoom.c b/modules/pdp_zoom.c index 33207ce..c89efb1 100644 --- a/modules/pdp_zoom.c +++ b/modules/pdp_zoom.c @@ -38,11 +38,7 @@ typedef struct pdp_zoom_struct int x_dropped; int x_queue_id; - float x_zoom_x; - float x_zoom_y; - - float x_center_x; - float x_center_y; + void *x_zoom; int x_quality; //not used @@ -67,10 +63,10 @@ static void pdp_zoom_process_yv12(t_pdp_zoom *x) unsigned int voffset = size; unsigned int uoffset = size + (size>>2); + pdp_imageproc_resample_affinemap_process(x->x_zoom, src_image, dst_image, w, h); + pdp_imageproc_resample_affinemap_process(x->x_zoom, src_image+voffset, dst_image+voffset, w>>1, h>>1); + pdp_imageproc_resample_affinemap_process(x->x_zoom, src_image+uoffset, dst_image+uoffset, w>>1, h>>1); - pdp_resample_zoom_tiled_bilin(src_image, dst_image, w, h, x->x_zoom_x, x->x_zoom_y, x->x_center_x, x->x_center_y); - pdp_resample_zoom_tiled_bilin(src_image+voffset, dst_image+voffset, w>>1, h>>1, x->x_zoom_x, x->x_zoom_y, x->x_center_x, x->x_center_y); - pdp_resample_zoom_tiled_bilin(src_image+uoffset, dst_image+uoffset, w>>1, h>>1, x->x_zoom_x, x->x_zoom_y, x->x_center_x, x->x_center_y); return; } @@ -89,7 +85,7 @@ static void pdp_zoom_process_grey(t_pdp_zoom *x) short int *src_image = (short int *)data0; short int *dst_image = (short int *)data1; - pdp_resample_zoom_tiled_bilin(src_image, dst_image, w, h, x->x_zoom_x, x->x_zoom_y, x->x_center_x, x->x_center_y); + pdp_imageproc_resample_affinemap_process(x->x_zoom, src_image, dst_image, w, h); return; @@ -160,30 +156,35 @@ static void pdp_zoom_input_0(t_pdp_zoom *x, t_symbol *s, t_floatarg f) -static void pdp_zoom_x(t_pdp_zoom *x, t_floatarg f) +static void pdp_zoom_zoom_x(t_pdp_zoom *x, t_floatarg f) { - x->x_zoom_x = f; + pdp_imageproc_resample_affinemap_setzoomx(x->x_zoom, f); } -static void pdp_zoom_y(t_pdp_zoom *x, t_floatarg f) +static void pdp_zoom_angle(t_pdp_zoom *x, t_floatarg f) { - x->x_zoom_y = f; + pdp_imageproc_resample_affinemap_setangle(x->x_zoom, f); } -static void pdp_zoom(t_pdp_zoom *x, t_floatarg f) +static void pdp_zoom_zoom_y(t_pdp_zoom *x, t_floatarg f) { - pdp_zoom_x(x, f); - pdp_zoom_y(x, f); + pdp_imageproc_resample_affinemap_setzoomy(x->x_zoom, f); +} + +static void pdp_zoom_zoom(t_pdp_zoom *x, t_floatarg f) +{ + pdp_zoom_zoom_x(x, f); + pdp_zoom_zoom_y(x, f); } static void pdp_zoom_center_x(t_pdp_zoom *x, t_floatarg f) { - x->x_center_x = (f + 0.5f); + pdp_imageproc_resample_affinemap_setcenterx(x->x_zoom, f); } static void pdp_zoom_center_y(t_pdp_zoom *x, t_floatarg f) { - x->x_center_y = (f + 0.5f); + pdp_imageproc_resample_affinemap_setcentery(x->x_zoom, f); } static void pdp_zoom_center(t_pdp_zoom *x, t_floatarg fx, t_floatarg fy) { @@ -191,6 +192,7 @@ static void pdp_zoom_center(t_pdp_zoom *x, t_floatarg fx, t_floatarg fy) pdp_zoom_center_y(x, fy); } +// not used static void pdp_zoom_quality(t_pdp_zoom *x, t_floatarg f) { if (f==0) x->x_quality = 0; @@ -205,30 +207,69 @@ t_class *pdp_zoom_class; void pdp_zoom_free(t_pdp_zoom *x) { pdp_queue_finish(x->x_queue_id); + pdp_imageproc_resample_affinemap_delete(x->x_zoom); pdp_packet_mark_unused(x->x_packet0); pdp_packet_mark_unused(x->x_packet1); } -void *pdp_zoom_new(t_floatarg fw, t_floatarg zoom) + +void pdp_zoom_init_common(t_pdp_zoom *x) +{ + 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_zoom = pdp_imageproc_resample_affinemap_new(); + + //quality is not used: all routines are "high quality" bilinear + //pdp_zoom_quality(x, 1); + pdp_zoom_center_x(x, 0.5f); + pdp_zoom_center_y(x, 0.5f); + +} + + +void *pdp_zoom_new(t_floatarg zoom) { t_pdp_zoom *x = (t_pdp_zoom *)pd_new(pdp_zoom_class); inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("zoom")); - + pdp_zoom_init_common(x); - x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + if (zoom == 0.0f) zoom = 1.0f; + pdp_zoom_zoom(x, zoom); + pdp_zoom_angle(x, 0.0f); - x->x_packet0 = -1; - x->x_packet1 = -1; - x->x_queue_id = -1; + return (void *)x; +} + +void *pdp_zrot_new(t_floatarg zoom, t_floatarg angle) +{ + t_pdp_zoom *x = (t_pdp_zoom *)pd_new(pdp_zoom_class); - pdp_zoom_quality(x, 1); - pdp_zoom_center_x(x, 0); - pdp_zoom_center_y(x, 0); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("zoom")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("angle")); - if (zoom = 0.0f) zoom = 1.0f; - pdp_zoom(x, zoom); + pdp_zoom_init_common(x); + + if (zoom == 0.0f) zoom = 1.0f; + pdp_zoom_zoom(x, zoom); + pdp_zoom_angle(x, angle); + + return (void *)x; +} + +void *pdp_rotate_new(t_floatarg angle) +{ + t_pdp_zoom *x = (t_pdp_zoom *)pd_new(pdp_zoom_class); + + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("angle")); + + pdp_zoom_init_common(x); + pdp_zoom_zoom(x, 1.0f); + pdp_zoom_angle(x, angle); return (void *)x; } @@ -243,18 +284,21 @@ extern "C" void pdp_zoom_setup(void) { - pdp_zoom_class = class_new(gensym("pdp_zoom"), (t_newmethod)pdp_zoom_new, - (t_method)pdp_zoom_free, sizeof(t_pdp_zoom), 0, A_DEFFLOAT, A_DEFFLOAT, A_NULL); + (t_method)pdp_zoom_free, sizeof(t_pdp_zoom), 0, A_DEFFLOAT, A_NULL); + + class_addcreator((t_newmethod)pdp_zrot_new, gensym("pdp_zrot"), A_DEFFLOAT, A_DEFFLOAT, A_NULL); + class_addcreator((t_newmethod)pdp_rotate_new, gensym("pdp_rotate"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_zoom_class, (t_method)pdp_zoom_quality, gensym("quality"), A_FLOAT, A_NULL); class_addmethod(pdp_zoom_class, (t_method)pdp_zoom_center_x, gensym("centerx"), A_FLOAT, A_NULL); class_addmethod(pdp_zoom_class, (t_method)pdp_zoom_center_y, gensym("centery"), A_FLOAT, A_NULL); class_addmethod(pdp_zoom_class, (t_method)pdp_zoom_center, gensym("center"), A_FLOAT, A_FLOAT, A_NULL); - class_addmethod(pdp_zoom_class, (t_method)pdp_zoom_x, gensym("zoomx"), A_FLOAT, A_NULL); - class_addmethod(pdp_zoom_class, (t_method)pdp_zoom_y, gensym("zoomy"), A_FLOAT, A_NULL); - class_addmethod(pdp_zoom_class, (t_method)pdp_zoom, gensym("zoom"), A_FLOAT, A_NULL); + class_addmethod(pdp_zoom_class, (t_method)pdp_zoom_zoom_x, gensym("zoomx"), A_FLOAT, A_NULL); + class_addmethod(pdp_zoom_class, (t_method)pdp_zoom_zoom_y, gensym("zoomy"), A_FLOAT, A_NULL); + class_addmethod(pdp_zoom_class, (t_method)pdp_zoom_zoom, gensym("zoom"), A_FLOAT, A_NULL); + class_addmethod(pdp_zoom_class, (t_method)pdp_zoom_angle, gensym("angle"), A_FLOAT, A_NULL); class_addmethod(pdp_zoom_class, (t_method)pdp_zoom_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); } |