/* * Pure Data Packet module. * Copyright (c) 2003 by Johannes Taelman * API updates by Tom Schouten * * 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_base.h" #include typedef struct pdp_cog_struct { t_object x_obj; t_float x_f; t_outlet *x_outlet0; t_outlet *x_outlet1; t_outlet *x_outlet2; t_outlet *x_outlet3; t_outlet *x_outlet4; int x_packet0; int x_threshold; int x_do_thresholding; } t_pdp_cog; static void _pdp_cog_perform(t_pdp_cog *x, int width, int height, short int *data0) { short int *pp; int nbpixels; int y; int h,v; int rowsums[width]; int columnsums[height]; float vsum,vvar,vcog,vstd; float hsum,hvar,hcog,hstd; pp=data0; nbpixels=width*height; for (h=0;hx_do_thresholding){ for (v=0;vx->x_threshold) ? d : ((d<-x->x_threshold)?(-d):0); columnsums[h]+= d; rs+=d; } rowsums[v]=rs; } } /* don't perform thresholding */ else{ for (v=0;vx_outlet4,vstd); outlet_float(x->x_outlet3,hstd); outlet_float(x->x_outlet2,vcog/height); outlet_float(x->x_outlet1,hcog/width); outlet_float(x->x_outlet0,(1.0f / (float)(0x7fff)) * hsum/(height*width)); } // packet is an image/*/* packet or invalid */ static void pdp_cog_perform(t_pdp_cog *x) { t_pdp *header0 = pdp_packet_header(x->x_packet0); void *data0 = pdp_packet_data(x->x_packet0); if (!header0 || !data0) return; _pdp_cog_perform(x, header0->info.image.width, header0->info.image.height, data0); } static void pdp_cog_input_0(t_pdp_cog *x, t_symbol *s, t_floatarg f) { int packet = (int)f; /* register */ if (s == gensym("register_ro")){ /* replace if not compatible or we are not interpolating */ pdp_packet_mark_unused(x->x_packet0); x->x_packet0 = pdp_packet_convert_ro(packet, pdp_gensym("image/*/*")); } if (s == gensym("process")){ pdp_cog_perform(x); } } static void pdp_cog_threshold(t_pdp_cog *x, t_floatarg f) { x->x_threshold=(int) (f * ((float) 0x7fff)); } static void pdp_cog_free(t_pdp_cog *x) { pdp_packet_mark_unused(x->x_packet0); } t_class *pdp_cog_class; void *pdp_cog_new(void) { t_pdp_cog *x = (t_pdp_cog *)pd_new(pdp_cog_class); x->x_outlet0 = outlet_new(&x->x_obj, &s_float); x->x_outlet1 = outlet_new(&x->x_obj, &s_float); x->x_outlet2 = outlet_new(&x->x_obj, &s_float); x->x_outlet3 = outlet_new(&x->x_obj, &s_float); x->x_outlet4 = outlet_new(&x->x_obj, &s_float); x->x_packet0 = -1; x->x_do_thresholding = 0; return (void *)x; } void *pdp_cog_abs_thresh_new(t_floatarg f) { t_pdp_cog *x = (t_pdp_cog *)pdp_cog_new(); inlet_new((void *)x, &x->x_obj.ob_pd, gensym("float"),gensym("threshold")); pdp_cog_threshold(x, f); x->x_do_thresholding = 1; return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_cog_setup(void) { pdp_cog_class = class_new(gensym("pdp_cog"), (t_newmethod)pdp_cog_new, (t_method)pdp_cog_free, sizeof(t_pdp_cog), 0,A_NULL); class_addcreator((t_newmethod)pdp_cog_abs_thresh_new, gensym("pdp_cog_abs_thresh"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_cog_class, (t_method)pdp_cog_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(pdp_cog_class, (t_method)pdp_cog_threshold, gensym("threshold"),A_DEFFLOAT, A_NULL); } #ifdef __cplusplus } #endif