Max 5 API Reference
00001 /* 00002 jit.matrix.c 00003 00004 Copyright 2001-2005 - Cycling '74 00005 Joshua Kit Clayton jkc@cycling74.com 00006 00007 */ 00008 00009 #include "jit.common.h" 00010 #include "jit.fixmath.h" 00011 #include "ext_obex.h" 00012 00013 /** 00014 * @defgroup matrixmod Matrix Module 00015 @ingroup jitter 00016 */ 00017 00018 typedef struct _jit_matrix 00019 { 00020 t_jit_object ob; 00021 t_jit_matrix_info info; 00022 void *data; // this is where we keep the "stuff" 00023 void **hdata; // if it stores data in a handle 00024 void *realdata; 00025 long realsize; 00026 } t_jit_matrix; 00027 00028 //default raster size 00029 #define JIT_MATRIX_DEF_TYPE _jit_sym_char 00030 #define JIT_MATRIX_DEF_FLAGS 0L 00031 #define JIT_MATRIX_DEF_DIMCOUNT 2 00032 #define JIT_MATRIX_DEF_DIMSIZE 1 00033 #define JIT_MATRIX_DEF_PLANECOUNT 4 00034 #define JIT_MATRIX_BIGMATRIX 2048 00035 00036 #define JIT_MATRIX_MAX_DATA_SIZE (2<<29L) 00037 #define JIT_MATRIX_INC_THRESH (1./(double)(1<<16L)) 00038 #define JIT_MATRIX_FUDGE (0.001) //to deal w/ fixed point roundoff error (nointerp) 00039 00040 #define DIRECTION(x) (((x)==0) ? 0 : (((x)>0) ? 1 : -1)) 00041 00042 #include "jit.frommatrix.h" 00043 00044 // for PowerPC use of "__dcbz" below... 00045 00046 #if TARGET_RT_MAC_MACHO && __ppc__ 00047 #include "ppc_intrinsics.h" 00048 #endif 00049 00050 static void *_jit_matrix_class; 00051 void *jit_matrix_new(t_jit_matrix_info *info); 00052 void *jit_matrix_newcopy(t_jit_matrix *copyme); 00053 void *jit_matrix_new_typed(t_symbol *s, long argc, t_atom *argv); 00054 t_jit_err jit_matrix_free(t_jit_matrix *x); 00055 t_jit_err jit_matrix_type(t_jit_matrix *x, void *attr, long argc, t_atom *argv); 00056 t_jit_err jit_matrix_dimensions(t_jit_matrix *x, void *attr, long argc, t_atom *argv); 00057 t_jit_err jit_matrix_planecount(t_jit_matrix *x, void *attr, long argc, t_atom *argv); 00058 t_jit_err jit_matrix_dosetinfo(t_jit_matrix *x, t_jit_matrix_info *info); 00059 t_jit_err jit_matrix_setinfo(t_jit_matrix *x, t_jit_matrix_info *info); 00060 t_jit_err jit_matrix_setinfo_typed(t_jit_matrix *x,t_symbol *s, long argc, t_atom *argv); 00061 t_jit_err jit_matrix_setinfo_ex(t_jit_matrix *x, t_jit_matrix_info *info); 00062 t_jit_err jit_matrix_getinfo(t_jit_matrix *x, t_jit_matrix_info *info); 00063 t_jit_err jit_matrix_getdata(t_jit_matrix *x, void **data); 00064 t_jit_err jit_matrix_data(t_jit_matrix *x, void *data); 00065 t_jit_err jit_matrix_data16(t_jit_matrix *x, void *data, long size); 00066 t_jit_err jit_matrix_freedata(t_jit_matrix *x); 00067 t_jit_err jit_matrix_rebuild(t_jit_matrix *x); 00068 t_jit_err jit_matrix_clear(t_jit_matrix *x); 00069 t_jit_err jit_matrix_clear_custom(t_jit_matrix *x, long cval); 00070 t_jit_err jit_matrix_setcell1d(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv); 00071 t_jit_err jit_matrix_setcell2d(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv); 00072 t_jit_err jit_matrix_setcell3d(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv); 00073 t_jit_err jit_matrix_setplane1d(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv); 00074 t_jit_err jit_matrix_setplane2d(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv); 00075 t_jit_err jit_matrix_setplane3d(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv); 00076 t_jit_err jit_matrix_setcell(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv); 00077 t_jit_err jit_matrix_getcell(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv, long *rac, t_atom **rav); 00078 t_jit_err jit_matrix_getcell_typed(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv, t_atom *rv); 00079 t_jit_err jit_matrix_setall(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv); 00080 t_jit_err jit_matrix_togworld(t_jit_matrix *x, GWorldPtr gp, t_gworld_conv_info *gcinfo); 00081 t_jit_err jit_matrix_fromgworld(t_jit_matrix *x, GWorldPtr gp, t_gworld_conv_info *gcinfo); 00082 t_jit_err jit_matrix_frommatrix(t_jit_matrix *dst_matrix, t_jit_matrix *src_matrix, t_matrix_conv_info *mcinfo); 00083 t_jit_err jit_matrix_frommatrix_trunc(t_jit_matrix *dst_matrix, t_jit_matrix *src_matrix); 00084 void *jit_matrix_getindex(t_jit_matrix *x, long i); //fake matrix as list for mops 00085 00086 void jit_matrix_setall_ndim(long dimcount, long *dim, long planecount, void *cells, t_jit_matrix_info *in_minfo, char *bip); 00087 00088 void jit_matrix_frommatrix_calculate_ndim(long dim, t_matrix_conv_info *mcinfo, t_jit_matrix_info *dst_minfo, char *dst_bp, 00089 t_jit_matrix_info *src_minfo, char *src_bp); 00090 void jit_matrix_frommatrix_2d_char(t_matrix_conv_info *mcinfo, t_jit_matrix_info *dst_minfo, char *dst_bp, 00091 t_jit_matrix_info *src_minfo, char *src_bp); 00092 void jit_matrix_frommatrix_2d_long(t_matrix_conv_info *mcinfo, t_jit_matrix_info *dst_minfo, char *dst_bp, 00093 t_jit_matrix_info *src_minfo, char *src_bp); 00094 void jit_matrix_frommatrix_2d_float32(t_matrix_conv_info *mcinfo, t_jit_matrix_info *dst_minfo, char *dst_bp, 00095 t_jit_matrix_info *src_minfo, char *src_bp); 00096 void jit_matrix_frommatrix_2d_float64(t_matrix_conv_info *mcinfo, t_jit_matrix_info *dst_minfo, char *dst_bp, 00097 t_jit_matrix_info *src_minfo, char *src_bp); 00098 00099 long jit_matrix_canfastcopy(t_matrix_conv_info *mcinfo, t_jit_matrix_info *dst_minfo, t_jit_matrix_info *src_minfo); 00100 t_jit_err jit_matrix_fastcopy(long size, void *dst, void *src); 00101 t_jit_err jit_matrix_fastcopy_altivec(long size, void *dst, void *src); 00102 00103 long jit_matrix_lock(t_jit_matrix *x, long lock); 00104 t_jit_err jit_matrix_op(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv); 00105 t_jit_err jit_matrix_exprfill(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv); 00106 t_jit_err jit_matrix_jit_gl_texture(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv); 00107 00108 t_symbol *ps_atomarray,*ps_nobox; 00109 static t_symbol *ps_getcell,*ps_jit_op,*ps_op,*ps_jit_expr,*ps_expr,*ps_tomatrix; 00110 00111 t_jit_err jit_matrix_init(void) 00112 { 00113 long i,attrflags=0; 00114 t_jit_object *attr; 00115 t_symbol *atsym; 00116 00117 atsym = _jit_sym_jit_attr_offset; 00118 00119 _jit_matrix_class = jit_class_new("jit_matrix",(method)jit_matrix_new,(method)jit_matrix_free, 00120 sizeof(t_jit_matrix),A_CANT,0L); //A_CANT = untyped 00121 00122 //add attributes 00123 attrflags = JIT_ATTR_GET_DEFER_LOW | JIT_ATTR_SET_USURP_LOW ; 00124 attr = jit_object_new(atsym,"type",_jit_sym_symbol,attrflags, 00125 (method)0L,(method)jit_matrix_type,calcoffset(t_jit_matrix,info.type)); 00126 jit_class_addattr(_jit_matrix_class,attr); 00127 00128 attr = jit_object_new(_jit_sym_jit_attr_offset_array,"dim",_jit_sym_long,JIT_MATRIX_MAX_DIMCOUNT,attrflags, 00129 (method)0L,(method)jit_matrix_dimensions,calcoffset(t_jit_matrix,info.dimcount),calcoffset(t_jit_matrix,info.dim)); 00130 jit_class_addattr(_jit_matrix_class,attr); 00131 00132 attr = jit_object_new(atsym,"planecount",_jit_sym_long,attrflags, 00133 (method)0L,(method)jit_matrix_planecount,calcoffset(t_jit_matrix,info.planecount)); 00134 jit_class_addattr(_jit_matrix_class,attr); 00135 00136 //user opaque attributes 00137 attrflags = JIT_ATTR_SET_OPAQUE_USER | JIT_ATTR_GET_DEFER_LOW; 00138 00139 attr = jit_object_new(_jit_sym_jit_attr_offset_array,"dimstride",_jit_sym_long,JIT_MATRIX_MAX_DIMCOUNT,attrflags, 00140 (method)0L,(method)0L,calcoffset(t_jit_matrix,info.dimcount),calcoffset(t_jit_matrix,info.dimstride)); 00141 jit_class_addattr(_jit_matrix_class,attr); 00142 00143 attr = jit_object_new(atsym,"size",_jit_sym_long,attrflags, 00144 (method)0L,(method)0L,calcoffset(t_jit_matrix,info.size)); 00145 jit_class_addattr(_jit_matrix_class,attr); 00146 00147 attrflags = JIT_ATTR_SET_OPAQUE_USER | JIT_ATTR_GET_OPAQUE_USER; 00148 00149 //may wish to expose some flags to the user? 00150 attr = jit_object_new(atsym,"flags",_jit_sym_long,attrflags, 00151 (method)0L,(method)0L,calcoffset(t_jit_matrix,info.flags)); 00152 jit_class_addattr(_jit_matrix_class,attr); 00153 00154 //add methods 00155 jit_class_addmethod(_jit_matrix_class, (method)jit_method_true, "class_jit_matrix" , A_CANT, 0L); 00156 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_getindex, "getindex", A_CANT, 0L); //fake as list for mops 00157 jit_class_addmethod(_jit_matrix_class, (method)jit_object_register, "register", A_CANT, 0L); //can register 00158 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_newcopy, "newcopy", A_CANT, 0L); 00159 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_setinfo, "setinfo", A_CANT, 0L); 00160 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_setinfo_ex, "setinfo_ex", A_CANT, 0L); 00161 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_getinfo, "getinfo", A_CANT, 0L); 00162 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_getdata, "getdata", A_CANT, 0L); 00163 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_data, "data", A_CANT, 0L); 00164 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_data16, "data16", A_CANT, 0L); 00165 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_freedata, "freedata", A_CANT, 0L); 00166 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_lock, "lock", A_CANT, 0L); 00167 //user methods 00168 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_clear, "clear", A_DEFER_LOW, 0L); 00169 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_clear_custom, "clear_custom", A_CANT, 0L); 00170 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_setcell, "setcell", A_DEFER_LOW, 0L); 00171 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_setall, "setall", A_DEFER_LOW, 0L); 00172 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_getcell, "getcell", A_CANT, 0L); //no defer since called via max 00173 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_setcell1d,"setcell1d",A_DEFER_LOW, 0L); 00174 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_setcell2d,"setcell2d",A_DEFER_LOW, 0L); 00175 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_setcell3d,"setcell3d",A_DEFER_LOW, 0L); 00176 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_setplane1d,"setplane1d",A_DEFER_LOW, 0L); 00177 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_setplane2d,"setplane2d",A_DEFER_LOW, 0L); 00178 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_setplane3d,"setplane3d",A_DEFER_LOW, 0L); 00179 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_togworld, "togworld", A_CANT, 0L); 00180 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_fromgworld, "fromgworld", A_CANT, 0L); 00181 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_frommatrix, "frommatrix", A_CANT, 0L); 00182 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_frommatrix_trunc, "frommatrix_trunc", A_CANT, 0L); 00183 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_op, "op", A_DEFER_LOW, 0L); 00184 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_exprfill, "exprfill", A_DEFER_LOW, 0L); 00185 jit_class_addmethod(_jit_matrix_class, (method)jit_matrix_jit_gl_texture, "jit_gl_texture", A_DEFER_LOW, 0L); 00186 00187 //additional typed wrapper methods 00188 jit_class_addtypedwrapper(_jit_matrix_class, (method)jit_matrix_new_typed, "new" , A_GIMME, 0L); 00189 jit_class_addtypedwrapper(_jit_matrix_class, (method)jit_matrix_setinfo_typed, "setinfo" , A_GIMME, 0L); 00190 jit_class_addtypedwrapper(_jit_matrix_class, (method)jit_matrix_getcell_typed, "getcell" , A_GIMMEBACK, 0L); 00191 //should add somethings for copying from matrices, newfrom matrices, etc. 00192 00193 jit_class_register(_jit_matrix_class); 00194 00195 ps_getcell = gensym("getcell"); 00196 ps_atomarray = gensym("atomarray"); 00197 ps_nobox = gensym("nobox"); 00198 ps_jit_op = gensym("jit_op"); 00199 ps_op = gensym("op"); 00200 ps_jit_expr = gensym("jit_expr"); 00201 ps_expr = gensym("expr"); 00202 ps_tomatrix = gensym("tomatrix"); 00203 00204 // initialize char to float lookups 00205 for (i=0;i<256;i++) 00206 _c2ftab[i] = (float) (_c2dtab[i] = ((double)i)/255.); 00207 00208 return JIT_ERR_NONE; 00209 } 00210 00211 /** 00212 * Constructs instance of t_jit_matrix. 00213 * 00214 * @ingroup matrixmod 00215 * 00216 * @param info t_jit_matrix_info struct pointer 00217 * 00218 * @return t_jit_matrix object pointer 00219 * 00220 * @warning This function is not exported, but is provided 00221 * for reference when calling via jit_object_new. 00222 */ 00223 void *jit_matrix_new(t_jit_matrix_info *info) 00224 { 00225 t_jit_matrix *x; 00226 t_jit_err err; 00227 00228 if (x=(t_jit_matrix *)jit_object_alloc(_jit_matrix_class)) { 00229 x->data = NULL; 00230 x->hdata = NULL; 00231 x->realdata = NULL; 00232 x->realsize = 0; 00233 if (info) { 00234 x->info = *info; 00235 if (x->info.flags&JIT_MATRIX_DATA_FLAGS_USE) { 00236 //leave data flags, but don't store JIT_MATRIX_DATA_FLAGS_USE 00237 x->info.flags &= ~JIT_MATRIX_DATA_FLAGS_USE; 00238 } else { 00239 x->info.flags &= ~(JIT_MATRIX_DATA_FLAGS_USE | 00240 JIT_MATRIX_DATA_REFERENCE | 00241 JIT_MATRIX_DATA_HANDLE); 00242 } 00243 err = jit_matrix_rebuild(x); 00244 } else { 00245 jit_matrix_info_default(&x->info); 00246 err = jit_matrix_rebuild(x); 00247 } 00248 if (err) { 00249 jit_object_free(x); 00250 x = NULL; 00251 } 00252 } 00253 return x; 00254 } 00255 00256 /** 00257 * Constructs instance of t_jit_matrix, copying from input. 00258 * 00259 * @ingroup matrixmod 00260 * 00261 * @param copyme t_jit_matrix object pointer 00262 * 00263 * @return t_jit_matrix object pointer 00264 * 00265 * @warning This function is not exported, but is provided 00266 * for reference when calling via jit_object_method 00267 * on an intance of t_jit_matrix. 00268 */ 00269 void *jit_matrix_newcopy(t_jit_matrix *copyme) 00270 { 00271 t_jit_matrix *x=NULL; 00272 long i=0,savelock; 00273 00274 if (copyme&&(x=(t_jit_matrix *)jit_object_alloc(_jit_matrix_class))) { 00275 savelock = jit_matrix_lock(copyme,1); 00276 x->info = copyme->info; 00277 if (x->info.flags&JIT_MATRIX_DATA_REFERENCE) { 00278 x->data = NULL; 00279 x->hdata = copyme->hdata; 00280 } else { 00281 x->data = NULL; 00282 x->hdata = NULL; 00283 } 00284 jit_matrix_lock(copyme,savelock); 00285 if (jit_matrix_rebuild(x)) { 00286 jit_object_free(x); 00287 x = NULL; 00288 } else { 00289 //copy the data? 00290 } 00291 } 00292 return x; 00293 } 00294 00295 void *jit_matrix_new_typed(t_symbol *s, long argc, t_atom *argv) 00296 { 00297 t_jit_matrix_info info; 00298 long i; 00299 00300 jit_matrix_info_default(&info); 00301 if (argc>0) 00302 info.planecount = CLAMP(jit_atom_getlong(argv),1,32); 00303 if (argc>1) 00304 info.type = jit_atom_getsym(argv+1); 00305 if (argc>2) { 00306 info.dimcount = MIN(32,argc-2); 00307 for (i=0;i<info.dimcount;i++) 00308 info.dim[i] = jit_atom_getlong(argv+i+2); 00309 } 00310 return jit_matrix_new(&info); 00311 } 00312 00313 t_jit_err jit_matrix_setinfo_typed(t_jit_matrix *x,t_symbol *s, long argc, t_atom *argv) 00314 { 00315 t_jit_matrix_info info; 00316 t_object *o=NULL; 00317 long i; 00318 00319 if (x) { 00320 jit_matrix_info_default(&info); 00321 if (argc&&(argv[0].a_type==A_OBJ)&& 00322 jit_object_method(argv[0].a_w.w_obj,_jit_sym_class_jit_matrix)) 00323 { 00324 // matrix object passed in (could also look for named symbols?) 00325 // perhaps make this a common function that could be called? 00326 jit_object_method(argv[0].a_w.w_obj,_jit_sym_getinfo,&info); 00327 } else { 00328 if ((argc==1)&&(argv[0].a_type==A_SYM)&& 00329 (o=jit_object_findregistered(argv[0].a_w.w_sym))&& 00330 jit_object_method(o,_jit_sym_class_jit_matrix)) 00331 { 00332 jit_object_method(o,_jit_sym_getinfo,&info); 00333 } else { 00334 jit_matrix_getinfo(x,&info); 00335 if (argc>0) 00336 info.planecount = CLAMP(jit_atom_getlong(argv),1,32); 00337 if (argc>1) 00338 info.type = jit_atom_getsym(argv+1); 00339 if (argc>2) { 00340 info.dimcount = MIN(32,argc-2); 00341 for (i=0;i<info.dimcount;i++) 00342 info.dim[i] = jit_atom_getlong(argv+i+2); 00343 } 00344 } 00345 } 00346 jit_matrix_setinfo(x,&info); 00347 } 00348 return JIT_ERR_NONE; 00349 } 00350 00351 /** 00352 * Frees instance of t_jit_matrix. 00353 * 00354 * @ingroup matrixmod 00355 * 00356 * @param x t_jit_matrix object pointer 00357 * 00358 * @return t_jit_err error code 00359 * 00360 * @warning Use jit_object_free instead. 00361 */ 00362 t_jit_err jit_matrix_free(t_jit_matrix *x) 00363 { 00364 void *data; 00365 00366 if (x) { 00367 //only free it if it's your memory 00368 if (!(x->info.flags&JIT_MATRIX_DATA_REFERENCE)) { 00369 if (x->info.flags&JIT_MATRIX_DATA_HANDLE) { 00370 data = x->hdata; 00371 x->data = NULL; //data being used as "valid" flag 00372 x->hdata = NULL; 00373 if (data) jit_handle_free(data); 00374 } else { 00375 data = x->data; 00376 x->data = NULL; //data being used as "valid" flag 00377 if (data) jit_matrix_freedata(x); 00378 } 00379 } 00380 } 00381 return JIT_ERR_NONE; 00382 } 00383 00384 t_jit_err jit_matrix_rebuild(t_jit_matrix *x) 00385 { 00386 long i,typesize=1; 00387 unsigned long size=0; 00388 void *data; 00389 00390 if (x) { 00391 // "rebuilding" notification for peek~ + poke~ since data ptr 00392 // is not safe to use as valid flag inside perform routine 00393 jit_object_notify(x,_jit_sym_rebuilding,NULL); 00394 data = x->data; 00395 x->data = NULL; //data being used as "valid" flag 00396 if (x->info.type==_jit_sym_char) 00397 typesize=sizeof(uchar); 00398 else if (x->info.type==_jit_sym_long) 00399 typesize=sizeof(long); 00400 else if (x->info.type==_jit_sym_float32) 00401 typesize=sizeof(float); 00402 else if (x->info.type==_jit_sym_float64) 00403 typesize=sizeof(double); 00404 else if (x->info.type==_jit_sym_symbol) 00405 typesize=sizeof(void *); 00406 else if (x->info.type==_jit_sym_object) 00407 typesize=sizeof(void *); 00408 else if (x->info.type==_jit_sym_pointer) 00409 typesize=sizeof(void *); 00410 else { 00411 jit_object_post((t_object *)x,"warning: attempting to allocate matrix with unknown type"); 00412 x->info.type=_jit_sym_char; 00413 typesize=sizeof(uchar); 00414 } 00415 if (x->info.flags&JIT_MATRIX_DATA_REFERENCE) { 00416 jit_object_notify(x,_jit_sym_modified,NULL); 00417 //jit_object_post((t_object *)x,"modifying reference"); 00418 return JIT_ERR_NONE; 00419 } 00420 if (x->info.planecount>JIT_MATRIX_MAX_PLANECOUNT) { 00421 jit_object_post((t_object *)x,"warning: attempting to allocate matrix with more than 32 planes"); 00422 } else if (x->info.planecount<1){ 00423 jit_object_post((t_object *)x,"warning: attempting to allocate matrix with less than 1 plane"); 00424 } 00425 CLIP(x->info.planecount,1,JIT_MATRIX_MAX_DIMCOUNT); 00426 00427 size = typesize * x->info.planecount; 00428 00429 for (i=0;i<JIT_MATRIX_MAX_DIMCOUNT;i++) { 00430 x->info.dim[i] = MAX(1,x->info.dim[i]); 00431 } 00432 for (i=0;i<x->info.dimcount;i++) { 00433 x->info.dimstride[i] = size; 00434 size *= x->info.dim[i]; 00435 //overflow error 00436 if ((size>=JIT_MATRIX_MAX_DATA_SIZE)||(size<(unsigned long)x->info.dimstride[i])) { 00437 jit_object_error((t_object *)x,"could not allocate matrix"); 00438 if (x->info.flags&JIT_MATRIX_DATA_HANDLE) { 00439 if (x->hdata) 00440 jit_handle_free(x->hdata); 00441 x->hdata = NULL; 00442 x->info.size = 0; 00443 jit_object_notify(x,_jit_sym_modified,NULL); 00444 return JIT_ERR_OUT_OF_MEM; 00445 } else { 00446 jit_matrix_freedata(x); 00447 x->data = NULL; 00448 x->info.size = 0; 00449 jit_object_notify(x,_jit_sym_modified,NULL); 00450 return JIT_ERR_OUT_OF_MEM; 00451 } 00452 } 00453 //round row dimension to nearest 16 bytes for altivec 00454 if (i==0&&!(x->info.flags&JIT_MATRIX_DATA_PACK_TIGHT)) { 00455 if (size%16) 00456 size = ((size/16)+1)*16; 00457 } 00458 } 00459 for (i=x->info.dimcount;i<JIT_MATRIX_MAX_DIMCOUNT;i++) { 00460 x->info.dim[i] = 1; 00461 x->info.dimstride[i] = 0; 00462 } 00463 if (x->info.flags&JIT_MATRIX_DATA_HANDLE) { 00464 if (x->hdata) { 00465 if (jit_handle_size_set(x->hdata,size)) { 00466 x->info.size = 0; 00467 jit_object_notify(x,_jit_sym_modified,NULL); 00468 return JIT_ERR_OUT_OF_MEM; 00469 } 00470 } else { 00471 if (!(x->hdata=jit_handle_new(size))) { 00472 x->info.size = 0; 00473 jit_object_notify(x,_jit_sym_modified,NULL); 00474 return JIT_ERR_OUT_OF_MEM; 00475 } 00476 } 00477 } else { 00478 jit_matrix_freedata(x); 00479 00480 if ((size==0)||(!(data=jit_getbytes(size+16)))) { 00481 jit_object_error((t_object *)x,"could not allocate matrix"); 00482 x->info.size = 0; 00483 x->data = NULL; 00484 00485 jit_object_notify(x,_jit_sym_modified,NULL); 00486 return JIT_ERR_OUT_OF_MEM; 00487 } 00488 x->realdata = data; 00489 x->realsize = size+16; 00490 data = (void *)(((unsigned long)x->realdata + 15L) & 0xFFFFFFF0L); 00491 } 00492 x->info.size = size; 00493 x->data = data; //data being used as "valid" flag 00494 jit_object_notify(x,_jit_sym_modified,NULL); 00495 jit_matrix_clear(x); 00496 return JIT_ERR_NONE; 00497 } else { 00498 return JIT_ERR_INVALID_PTR; 00499 } 00500 } 00501 00502 t_jit_err jit_matrix_type(t_jit_matrix *x, void *attr, long argc, t_atom *argv) 00503 { 00504 t_symbol *type; 00505 00506 if (x){ 00507 if (argc&&argv) { 00508 type=jit_atom_getsym(argv); 00509 if (x->info.type!=type) { 00510 x->info.type=type; 00511 return jit_matrix_rebuild(x); 00512 } else { 00513 return JIT_ERR_NONE; 00514 } 00515 } else { 00516 return JIT_ERR_NONE; 00517 } 00518 } 00519 return JIT_ERR_INVALID_PTR; 00520 } 00521 00522 t_jit_err jit_matrix_dimensions(t_jit_matrix *x, void *attr, long argc, t_atom *argv) 00523 { 00524 long i=0,zap=JIT_MATRIX_MAX_DIMCOUNT; 00525 long c,dimcount,dim[JIT_MATRIX_MAX_DIMCOUNT]; 00526 long rebuild=FALSE; 00527 00528 if (x) { 00529 CLIP(argc,0,JIT_MATRIX_MAX_DIMCOUNT); 00530 dimcount = argc; 00531 if (dimcount!=x->info.dimcount) rebuild = TRUE; 00532 if (argc&&argv) { 00533 zap -= argc; 00534 while (argc--) { 00535 c = jit_atom_getlong(argv+i); 00536 dim[i] = MAX(c,1); 00537 if (dim[i]!=x->info.dim[i]) rebuild = TRUE; 00538 i++; 00539 } 00540 } 00541 while (zap--) { 00542 dim[i] = 1; 00543 i++; 00544 } 00545 if (rebuild) { 00546 x->info.dimcount = dimcount; 00547 for (i=0;i<JIT_MATRIX_MAX_DIMCOUNT;i++) 00548 x->info.dim[i] = MAX(1,dim[i]); 00549 return jit_matrix_rebuild(x); 00550 } else { 00551 return JIT_ERR_NONE; 00552 } 00553 } 00554 return JIT_ERR_INVALID_PTR; 00555 } 00556 00557 t_jit_err jit_matrix_planecount(t_jit_matrix *x, void *attr, long argc, t_atom *argv) 00558 { 00559 long c=1; 00560 long planecount; 00561 00562 if (x) { 00563 if(argc&&argv) { 00564 c = jit_atom_getlong(argv); 00565 CLIP(c,1,JIT_MATRIX_MAX_PLANECOUNT); 00566 planecount=c; 00567 if (x->info.planecount!=planecount) { 00568 x->info.planecount=planecount; 00569 return jit_matrix_rebuild(x); 00570 } else { 00571 return JIT_ERR_NONE; 00572 } 00573 } 00574 } 00575 return JIT_ERR_INVALID_PTR; 00576 } 00577 00578 t_jit_err jit_matrix_dosetinfo(t_jit_matrix *x, t_jit_matrix_info *info) 00579 { 00580 long rebuild=FALSE,flags,i; 00581 00582 if (x) { 00583 if (info) { 00584 rebuild |= (x->info.type!=info->type); 00585 rebuild |= (x->info.planecount!=info->planecount); 00586 rebuild |= (x->info.dimcount!=info->dimcount); 00587 for (i=0;i<info->dimcount;i++) { 00588 rebuild |= (x->info.dim[i]!=info->dim[i]); 00589 } 00590 if (rebuild) { 00591 x->info.type = info->type; 00592 x->info.planecount = info->planecount; 00593 x->info.dimcount = info->dimcount; 00594 for (i=0;i<info->dimcount;i++) { 00595 x->info.dim[i] = MAX(1,info->dim[i]); 00596 } 00597 return jit_matrix_rebuild(x); 00598 } else 00599 return JIT_ERR_NONE; 00600 } else { 00601 jit_matrix_info_default(&x->info); 00602 return jit_matrix_rebuild(x); 00603 } 00604 } else { 00605 return JIT_ERR_INVALID_PTR; 00606 } 00607 } 00608 00609 /** 00610 * Sets all attributes according to the t_jit_matrix_info struct provided. 00611 * 00612 * @ingroup matrixmod 00613 * 00614 * @param x t_jit_matrix object pointer 00615 * @param info t_jit_matrix_info pointer 00616 * 00617 * @return t_jit_err error code 00618 * 00619 * @warning This function is not exported, but is provided 00620 * for reference when calling via jit_object_method 00621 * on an intance of t_jit_matrix. 00622 */ 00623 t_jit_err jit_matrix_setinfo(t_jit_matrix *x, t_jit_matrix_info *info) 00624 { 00625 t_jit_err rv; 00626 00627 rv = jit_matrix_dosetinfo(x, info); 00628 jit_object_notify(x, _jit_sym_setinfo, NULL); // i need this for uyvy dim changes (jb) 00629 return rv; 00630 } 00631 00632 /** 00633 * Sets all attributes according to the t_jit_matrix_info struct provided (including data flags). 00634 * 00635 * @ingroup matrixmod 00636 * 00637 * @param x t_jit_matrix object pointer 00638 * @param info t_jit_matrix_info pointer 00639 * 00640 * @return t_jit_err error code 00641 * 00642 * @warning This function is not exported, but is provided 00643 * for reference when calling via jit_object_method 00644 * on an intance of t_jit_matrix. 00645 */ 00646 t_jit_err jit_matrix_setinfo_ex(t_jit_matrix *x, t_jit_matrix_info *info) 00647 { 00648 if (x&&info) { 00649 if (info->flags&JIT_MATRIX_DATA_REFERENCE) { 00650 //currently this should only be used by jit.coerce + jit.submatrix 00651 x->info = *info; 00652 x->realsize = x->info.size; 00653 jit_object_notify(x, _jit_sym_modified, NULL); 00654 return JIT_ERR_NONE; 00655 } 00656 else if (x->info.flags&JIT_MATRIX_DATA_REFERENCE) { // so, do this without an explicit flag 00657 x->info.flags = info->flags & ~(JIT_MATRIX_DATA_REFERENCE); 00658 x->realdata = x->data = NULL; 00659 x->realsize = x->info.size = 0; 00660 x->info.type = _jit_sym_nothing; // force a rebuild 00661 } else { 00662 x->info.flags = info->flags; 00663 } 00664 } 00665 return jit_matrix_setinfo(x, info); 00666 } 00667 00668 /** 00669 * Retrieves all attributes, copying into the t_jit_matrix_info struct provided. 00670 * 00671 * @ingroup matrixmod 00672 * 00673 * @param x t_jit_matrix object pointer 00674 * @param info t_jit_matrix_info pointer 00675 * 00676 * @return t_jit_err error code 00677 * 00678 * @warning This function is not exported, but is provided 00679 * for reference when calling via jit_object_method 00680 * on an intance of t_jit_matrix. 00681 */ 00682 t_jit_err jit_matrix_getinfo(t_jit_matrix *x, t_jit_matrix_info *info) 00683 { 00684 if (x&&info) { 00685 *info = x->info; 00686 return JIT_ERR_NONE; 00687 } else { 00688 return JIT_ERR_INVALID_PTR; 00689 } 00690 } 00691 00692 void *jit_matrix_getindex(t_jit_matrix *x, long i) //matrix fakes as a list of matrices for mop code 00693 { 00694 if (x&&(i==0)) { 00695 return x; 00696 } else { 00697 return NULL; 00698 } 00699 } 00700 00701 /** 00702 * Retrieves matrix data pointer. 00703 * 00704 * @ingroup matrixmod 00705 * 00706 * @param x t_jit_matrix object pointer 00707 * @param data pointer to data pointer (set to NULL if matrix is not available) 00708 * 00709 * @return t_jit_err error code 00710 * 00711 * @warning This function is not exported, but is provided 00712 * for reference when calling via jit_object_method 00713 * on an intance of t_jit_matrix. 00714 */ 00715 t_jit_err jit_matrix_getdata(t_jit_matrix *x, void **data) 00716 { 00717 if (x&&data) { 00718 *data = x->data; 00719 return JIT_ERR_NONE; 00720 } else { 00721 return JIT_ERR_INVALID_PTR; 00722 } 00723 } 00724 00725 /** 00726 * Sets matrix data pointer. 00727 * 00728 * @ingroup matrixmod 00729 * 00730 * @param x t_jit_matrix object pointer 00731 * @param data data pointer 00732 * 00733 * @return t_jit_err error code 00734 * 00735 * @warning This function is not exported, but is provided 00736 * for reference when calling via jit_object_method 00737 * on an intance of t_jit_matrix. 00738 */ 00739 t_jit_err jit_matrix_data(t_jit_matrix *x, void *data) 00740 { 00741 if (x) { 00742 x->data = data; 00743 x->realdata = data; 00744 return JIT_ERR_NONE; 00745 } else { 00746 return JIT_ERR_INVALID_PTR; 00747 } 00748 } 00749 00750 t_jit_err jit_matrix_data16(t_jit_matrix *x, void *data, long size) 00751 { 00752 if (x) { 00753 x->data = (void *)((unsigned long)x->realdata & 0xFFFFFFF0); 00754 x->info.size = size - ((unsigned long)data - (unsigned long)x->data); 00755 x->realdata = data; 00756 x->realsize = size; 00757 return JIT_ERR_NONE; 00758 } else { 00759 return JIT_ERR_INVALID_PTR; 00760 } 00761 } 00762 00763 /** 00764 * Frees matrix's internal data pointer if an internal reference and sets to NULL. 00765 * 00766 * @ingroup matrixmod 00767 * 00768 * @param x t_jit_matrix object pointer 00769 * 00770 * @return t_jit_err error code 00771 * 00772 * @warning This function is not exported, but is provided 00773 * for reference when calling via jit_object_method 00774 * on an intance of t_jit_matrix. 00775 */ 00776 t_jit_err jit_matrix_freedata(t_jit_matrix *x) 00777 { 00778 if (x) { 00779 if (x->realdata&&x->realsize&& !(x->info.flags & JIT_MATRIX_DATA_REFERENCE)) 00780 jit_freebytes(x->realdata,x->realsize); 00781 x->realdata = x->data = NULL; 00782 x->realsize = x->info.size = 0; 00783 return JIT_ERR_NONE; 00784 } else { 00785 return JIT_ERR_INVALID_PTR; 00786 } 00787 } 00788 00789 /** 00790 * Initializes matrix info struct to default values. 00791 * 00792 * @ingroup matrixmod 00793 * 00794 * @param info t_jit_matrix_info struct pointer 00795 * 00796 * @return t_jit_err error code 00797 * 00798 * @warning This function is not exported, but is provided 00799 * for reference when calling via jit_object_method 00800 * on an intance of t_jit_matrix. 00801 */ 00802 t_jit_err jit_matrix_info_default(t_jit_matrix_info *info) 00803 { 00804 long i=0; 00805 00806 if (info) { 00807 info->size = 0; 00808 info->type = JIT_MATRIX_DEF_TYPE; 00809 info->flags = JIT_MATRIX_DEF_FLAGS; 00810 info->dimcount = JIT_MATRIX_DEF_DIMCOUNT; 00811 info->planecount = JIT_MATRIX_DEF_PLANECOUNT; 00812 for (i=0;i<JIT_MATRIX_MAX_DIMCOUNT;i++) { 00813 info->dim[i]=1; 00814 info->dimstride[i]=0; 00815 } 00816 for (i=0;i<JIT_MATRIX_DEF_DIMCOUNT;i++) { 00817 info->dim[i]=JIT_MATRIX_DEF_DIMSIZE; 00818 } 00819 return JIT_ERR_NONE; 00820 } else { 00821 return JIT_ERR_INVALID_PTR; 00822 } 00823 } 00824 00825 /** 00826 * Sets all cells in matrix to the zero. 00827 * See Jitter user documentation for more information. 00828 * 00829 * @ingroup matrixmod 00830 * 00831 * @param x t_jit_matrix object pointer 00832 * 00833 * @return t_jit_err error code 00834 * 00835 * @warning This function is not exported, but is provided 00836 * for reference when calling via jit_object_method 00837 * on an intance of t_jit_matrix. 00838 */ 00839 t_jit_err jit_matrix_clear(t_jit_matrix *x) 00840 { 00841 long savelock; 00842 long size,*lp; 00843 char *cp; 00844 00845 if (x) { 00846 savelock = jit_matrix_lock(x,1); 00847 if (!x->data) { 00848 jit_matrix_lock(x,savelock); 00849 return JIT_ERR_GENERIC; 00850 } 00851 if (x->info.size%4) { 00852 size = (x->info.size/4)+1; 00853 lp = ((long *)(x->data))-1; 00854 while (--size) *++lp=0; 00855 size = (x->info.size%4)+1; 00856 cp = ((char *)lp)-1; 00857 while (--size) *++cp=0; 00858 } else { 00859 size = (x->info.size/4)+1; 00860 lp = ((long *)(x->data))-1; 00861 while (--size) *++lp=0; 00862 } 00863 jit_matrix_lock(x,savelock); 00864 return JIT_ERR_NONE; 00865 } else { 00866 return JIT_ERR_INVALID_PTR; 00867 } 00868 } 00869 00870 t_jit_err jit_matrix_clear_custom(t_jit_matrix *x, long cval) 00871 { 00872 long savelock; 00873 long size,*lp; 00874 char *cp; 00875 long val = BE_I32(cval); 00876 00877 if (x) { 00878 savelock = jit_matrix_lock(x,1); 00879 if (!x->data) { 00880 jit_matrix_lock(x,savelock); 00881 return JIT_ERR_GENERIC; 00882 } 00883 if (x->info.size%4) { 00884 size = (x->info.size/4)+1; 00885 lp = ((long *)(x->data))-1; 00886 while (--size) *++lp=val; 00887 size = (x->info.size%4)+1; 00888 cp = ((char *)lp)-1; 00889 while (--size) *++cp=val; 00890 } else { 00891 size = (x->info.size/4)+1; 00892 lp = ((long *)(x->data))-1; 00893 while (--size) *++lp=val; 00894 } 00895 jit_matrix_lock(x,savelock); 00896 return JIT_ERR_NONE; 00897 } else { 00898 return JIT_ERR_INVALID_PTR; 00899 } 00900 } 00901 00902 // utilities for js/java efficiency (no symbol generation for val/plane keywords is 25-50% performance boost 00903 /** 00904 * Sets cell at index to the value provided. 00905 * See Jitter user documentation for more information. 00906 * 00907 * @ingroup matrixmod 00908 * 00909 * @param x t_jit_matrix object pointer 00910 * @param s message symbol pointer 00911 * @param argc argument count 00912 * @param argv argument vector 00913 * 00914 * @return t_jit_err error code 00915 * 00916 * @warning This function is not exported, but is provided 00917 * for reference when calling via jit_object_method 00918 * on an intance of t_jit_matrix. 00919 */ 00920 t_jit_err jit_matrix_setcell1d(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv) 00921 { 00922 long i; 00923 t_atom a[128]; 00924 00925 if (argc<1) return JIT_ERR_NONE; 00926 if (argc>100) argc=100; 00927 00928 jit_atom_setlong(a,jit_atom_getlong(argv)); 00929 jit_atom_setsym(a+1,_jit_sym_val); 00930 for (i=1;i<argc;i++) { 00931 a[i+1] = argv[i]; 00932 } 00933 jit_matrix_setcell(x,s,argc+1,a); 00934 return JIT_ERR_NONE; 00935 } 00936 00937 /** 00938 * Sets cell at index to the value provided. 00939 * See Jitter user documentation for more information. 00940 * 00941 * @ingroup matrixmod 00942 * 00943 * @param x t_jit_matrix object pointer 00944 * @param s message symbol pointer 00945 * @param argc argument count 00946 * @param argv argument vector 00947 * 00948 * @return t_jit_err error code 00949 * 00950 * @warning This function is not exported, but is provided 00951 * for reference when calling via jit_object_method 00952 * on an intance of t_jit_matrix. 00953 */ 00954 t_jit_err jit_matrix_setcell2d(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv) 00955 { 00956 long i; 00957 t_atom a[128]; 00958 00959 if (argc<2) return JIT_ERR_NONE; 00960 if (argc>100) argc=100; 00961 00962 jit_atom_setlong(a,jit_atom_getlong(argv)); 00963 jit_atom_setlong(a+1,jit_atom_getlong(argv+1)); 00964 jit_atom_setsym(a+2,_jit_sym_val); 00965 for (i=2;i<argc;i++) { 00966 a[i+1] = argv[i]; 00967 } 00968 jit_matrix_setcell(x,s,argc+1,a); 00969 return JIT_ERR_NONE; 00970 } 00971 00972 /** 00973 * Sets cell at index to the value provided. 00974 * See Jitter user documentation for more information. 00975 * 00976 * @ingroup matrixmod 00977 * 00978 * @param x t_jit_matrix object pointer 00979 * @param s message symbol pointer 00980 * @param argc argument count 00981 * @param argv argument vector 00982 * 00983 * @return t_jit_err error code 00984 * 00985 * @warning This function is not exported, but is provided 00986 * for reference when calling via jit_object_method 00987 * on an intance of t_jit_matrix. 00988 */ 00989 t_jit_err jit_matrix_setcell3d(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv) 00990 { 00991 long i; 00992 t_atom a[128]; 00993 00994 if (argc<3) return JIT_ERR_NONE; 00995 if (argc>100) argc=100; 00996 00997 jit_atom_setlong(a,jit_atom_getlong(argv)); 00998 jit_atom_setlong(a+1,jit_atom_getlong(argv+1)); 00999 jit_atom_setlong(a+2,jit_atom_getlong(argv+2)); 01000 jit_atom_setsym(a+3,_jit_sym_val); 01001 for (i=3;i<argc;i++) { 01002 a[i+1] = argv[i]; 01003 } 01004 jit_matrix_setcell(x,s,argc+1,a); 01005 return JIT_ERR_NONE; 01006 } 01007 01008 /** 01009 * Sets plane of cell at index to the value provided. 01010 * See Jitter user documentation for more information. 01011 * 01012 * @ingroup matrixmod 01013 * 01014 * @param x t_jit_matrix object pointer 01015 * @param s message symbol pointer 01016 * @param argc argument count 01017 * @param argv argument vector 01018 * 01019 * @return t_jit_err error code 01020 * 01021 * @warning This function is not exported, but is provided 01022 * for reference when calling via jit_object_method 01023 * on an intance of t_jit_matrix. 01024 */ 01025 t_jit_err jit_matrix_setplane1d(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv) 01026 { 01027 long i; 01028 t_atom a[128]; 01029 01030 if (argc<2) return JIT_ERR_NONE; 01031 if (argc>100) argc=100; 01032 01033 jit_atom_setlong(a,jit_atom_getlong(argv)); 01034 jit_atom_setsym(a+1,_jit_sym_plane); 01035 jit_atom_setlong(a+2,jit_atom_getlong(argv+1)); 01036 jit_atom_setsym(a+3,_jit_sym_val); 01037 for (i=2;i<argc;i++) { 01038 a[i+2] = argv[i]; 01039 } 01040 jit_matrix_setcell(x,s,argc+2,a); 01041 return JIT_ERR_NONE; 01042 } 01043 01044 /** 01045 * Sets plane of cell at index to the value provided. 01046 * See Jitter user documentation for more information. 01047 * 01048 * @ingroup matrixmod 01049 * 01050 * @param x t_jit_matrix object pointer 01051 * @param s message symbol pointer 01052 * @param argc argument count 01053 * @param argv argument vector 01054 * 01055 * @return t_jit_err error code 01056 * 01057 * @warning This function is not exported, but is provided 01058 * for reference when calling via jit_object_method 01059 * on an intance of t_jit_matrix. 01060 */ 01061 t_jit_err jit_matrix_setplane2d(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv) 01062 { 01063 long i; 01064 t_atom a[128]; 01065 01066 if (argc<3) return JIT_ERR_NONE; 01067 if (argc>100) argc=100; 01068 01069 jit_atom_setlong(a,jit_atom_getlong(argv)); 01070 jit_atom_setlong(a+1,jit_atom_getlong(argv+1)); 01071 jit_atom_setsym(a+2,_jit_sym_plane); 01072 jit_atom_setlong(a+3,jit_atom_getlong(argv+2)); 01073 jit_atom_setsym(a+4,_jit_sym_val); 01074 for (i=3;i<argc;i++) { 01075 a[i+2] = argv[i]; 01076 } 01077 jit_matrix_setcell(x,s,argc+2,a); 01078 return JIT_ERR_NONE; 01079 } 01080 01081 /** 01082 * Sets plane of cell at index to the value provided. 01083 * See Jitter user documentation for more information. 01084 * 01085 * @ingroup matrixmod 01086 * 01087 * @param x t_jit_matrix object pointer 01088 * @param s message symbol pointer 01089 * @param argc argument count 01090 * @param argv argument vector 01091 * 01092 * @return t_jit_err error code 01093 * 01094 * @warning This function is not exported, but is provided 01095 * for reference when calling via jit_object_method 01096 * on an intance of t_jit_matrix. 01097 */ 01098 t_jit_err jit_matrix_setplane3d(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv) 01099 { 01100 long i; 01101 t_atom a[128]; 01102 01103 if (argc<4) return JIT_ERR_NONE; 01104 if (argc>100) argc=100; 01105 01106 jit_atom_setlong(a,jit_atom_getlong(argv)); 01107 jit_atom_setlong(a+1,jit_atom_getlong(argv+1)); 01108 jit_atom_setlong(a+2,jit_atom_getlong(argv+2)); 01109 jit_atom_setsym(a+3,_jit_sym_plane); 01110 jit_atom_setlong(a+4,jit_atom_getlong(argv+3)); 01111 jit_atom_setsym(a+5,_jit_sym_val); 01112 for (i=4;i<argc;i++) { 01113 a[i+2] = argv[i]; 01114 } 01115 jit_matrix_setcell(x,s,argc+2,a); 01116 return JIT_ERR_NONE; 01117 } 01118 01119 /** 01120 * Sets cell at index to the value provided. 01121 * See Jitter user documentation for more information. 01122 * 01123 * @ingroup matrixmod 01124 * 01125 * @param x t_jit_matrix object pointer 01126 * @param s message symbol pointer 01127 * @param argc argument count 01128 * @param argv argument vector 01129 * 01130 * @return t_jit_err error code 01131 * 01132 * @warning This function is not exported, but is provided 01133 * for reference when calling via jit_object_method 01134 * on an intance of t_jit_matrix. 01135 */ 01136 t_jit_err jit_matrix_setcell(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv) 01137 { 01138 long savelock; 01139 long stride,i,j,plane=0,useplane=0; 01140 long cell[JIT_MATRIX_MAX_DIMCOUNT]; 01141 char *p; 01142 01143 if (x) { 01144 if (argc&&argv) { 01145 //parse args 01146 for (i=0;(i<argc)&&(i<=JIT_MATRIX_MAX_DIMCOUNT);i++) { 01147 if ((argv[i].a_type==A_SYM)&&(argv[i].a_w.w_sym==_jit_sym_val)) { 01148 goto pikka; 01149 } 01150 if ((argv[i].a_type==A_SYM)&&(argv[i].a_w.w_sym==_jit_sym_plane)) { 01151 useplane = 1; 01152 goto pikka; 01153 } 01154 cell[i] = jit_atom_getlong(argv+i); 01155 } 01156 goto pakka; //too many dimensions without "val" token 01157 pikka: 01158 if (useplane) { 01159 for (j=i;j<x->info.dimcount;j++) cell[j] = 0; 01160 if (++i<argc) plane = jit_atom_getlong(argv+i); 01161 if (plane>=x->info.planecount) goto pakka; 01162 i++; 01163 if ((argv[i].a_type!=A_SYM)||(argv[i].a_w.w_sym!=_jit_sym_val)) { 01164 goto pakka; 01165 } 01166 i++; 01167 savelock = jit_matrix_lock(x,1); 01168 if (!x->data) goto pakka; 01169 //find ptr 01170 p = ((char *)(x->data)); 01171 for (j=0;j<x->info.dimcount;j++) { 01172 if ((cell[j]>=0)&&(cell[j]<x->info.dim[j])) 01173 p += cell[j]*x->info.dimstride[j]; 01174 else goto pakka; 01175 } 01176 if (i<argc) { 01177 if (x->info.type==_jit_sym_char) { 01178 ((uchar *)p)[plane] = jit_atom_getcharfix(argv+i); 01179 } else if (x->info.type==_jit_sym_long) { 01180 ((long *)p)[plane] = jit_atom_getlong(argv+i); 01181 } else if (x->info.type==_jit_sym_float32) { 01182 ((float *)p)[plane] = jit_atom_getfloat(argv+i); 01183 } else if (x->info.type==_jit_sym_float64) { 01184 ((double *)p)[plane] = jit_atom_getfloat(argv+i); 01185 } else if (x->info.type==_jit_sym_symbol) { 01186 ((t_symbol **)p)[plane] = jit_atom_getsym(argv+i); 01187 } else if (x->info.type==_jit_sym_object) { 01188 ((t_object **)p)[plane] = jit_atom_getobj(argv+i); 01189 } 01190 } 01191 } else { 01192 for (j=i;j<x->info.dimcount;j++) cell[j] = 0; 01193 savelock = jit_matrix_lock(x,1); 01194 if (!x->data) goto pakka; 01195 //find ptr 01196 p = ((char *)(x->data)); 01197 for (j=0;j<x->info.dimcount;j++) { 01198 if ((cell[j]>=0)&&(cell[j]<x->info.dim[j])) 01199 p += cell[j]*x->info.dimstride[j]; 01200 else goto pakka; 01201 } 01202 for (i++,j=0;j<x->info.planecount;i++,j++) { 01203 if (i<argc) { 01204 if (x->info.type==_jit_sym_char) { 01205 *((uchar *)p) = jit_atom_getcharfix(argv+i); p+=1; 01206 } else if (x->info.type==_jit_sym_long) { 01207 *((long *)p) = jit_atom_getlong(argv+i); p+=4; 01208 } else if (x->info.type==_jit_sym_float32) { 01209 *((float *)p) = jit_atom_getfloat(argv+i); p+=4; 01210 } else if (x->info.type==_jit_sym_float64) { 01211 *((double *)p) = jit_atom_getfloat(argv+i); p+=8; 01212 } else if (x->info.type==_jit_sym_symbol) { 01213 *((t_symbol **)p) = jit_atom_getsym(argv+i); p+=4; 01214 } else if (x->info.type==_jit_sym_object) { 01215 *((t_object **)p) = jit_atom_getobj(argv+i); p+=4; 01216 } 01217 } else { 01218 if (x->info.type==_jit_sym_char) { 01219 *p = 0; p+=1; 01220 } else if (x->info.type==_jit_sym_long) { 01221 *((long *)p) = 0; p+=4; 01222 } else if (x->info.type==_jit_sym_float32) { 01223 *((float *)p) = 0; p+=4; 01224 } else if (x->info.type==_jit_sym_float64) { 01225 *((double *)p) = 0; p+=8; 01226 } else if (x->info.type==_jit_sym_symbol) { 01227 *((t_symbol **)p) = 0; p+=4; 01228 } else if (x->info.type==_jit_sym_object) { 01229 *((t_object **)p) = 0; p+=4; 01230 } 01231 } 01232 } 01233 } 01234 jit_matrix_lock(x,savelock); 01235 } 01236 return JIT_ERR_NONE; 01237 } else { 01238 return JIT_ERR_INVALID_PTR; 01239 } 01240 01241 pakka: 01242 jit_matrix_lock(x,savelock); 01243 return JIT_ERR_OUT_OF_BOUNDS; 01244 } 01245 01246 /** 01247 * Gets cell at index to the value provided. 01248 * See Jitter user documentation for more information. 01249 * 01250 * @ingroup matrixmod 01251 * 01252 * @param x t_jit_matrix object pointer 01253 * @param s message symbol pointer 01254 * @param argc argument count 01255 * @param argv argument vector 01256 * @param rac return value atom count 01257 * @param rav return value atom vector 01258 * 01259 * @return t_jit_err error code 01260 * 01261 * @warning This function is not exported, but is provided 01262 * for reference when calling via jit_object_method 01263 * on an intance of t_jit_matrix. 01264 */ 01265 t_jit_err jit_matrix_getcell(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv, long *rac, t_atom **rav) 01266 { 01267 long savelock; 01268 long stride,i,off; 01269 long cell[JIT_MATRIX_MAX_DIMCOUNT]; 01270 char *p; 01271 01272 //perhaps allow caller to pass in memory. 01273 *rac = 0; 01274 *rav = NULL; 01275 01276 if (x) { 01277 if (argc&&argv) { 01278 //parse args 01279 for (i=0;(i<argc)&&(i<JIT_MATRIX_MAX_DIMCOUNT);) { 01280 cell[i] = jit_atom_getlong(argv+i); 01281 i++; 01282 } 01283 01284 for (;i<x->info.dimcount;i++) cell[i] = 0; 01285 01286 savelock = jit_matrix_lock(x,1); 01287 if (!x->data) goto pakka; 01288 //find ptr 01289 p = ((char *)(x->data)); 01290 for (i=0;i<x->info.dimcount;i++) { 01291 if ((cell[i]>=0)&&(cell[i]<x->info.dim[i])) 01292 p += cell[i]*x->info.dimstride[i]; 01293 else goto pakka; 01294 } 01295 if (!(*rav=jit_getbytes(sizeof(t_atom)*(x->info.dimcount+x->info.planecount+1)))) 01296 goto pakka; 01297 *rac = x->info.dimcount+x->info.planecount+1; 01298 for (i=0;i<x->info.dimcount;i++) { 01299 jit_atom_setlong((*rav)+i,cell[i]); 01300 } 01301 jit_atom_setsym((*rav)+i,_jit_sym_val); 01302 off = i+1; 01303 for (i=0;i<x->info.planecount;i++) { 01304 if (x->info.type==_jit_sym_char) { 01305 jit_atom_setlong((*rav)+off+i,*((uchar *)p)); p+=1; 01306 } else if (x->info.type==_jit_sym_long) { 01307 jit_atom_setlong((*rav)+off+i,*((long *)p)); p+=4; 01308 } else if (x->info.type==_jit_sym_float32) { 01309 jit_atom_setfloat((*rav)+off+i,*((float *)p)); p+=4; 01310 } else if (x->info.type==_jit_sym_float64) { 01311 jit_atom_setfloat((*rav)+off+i,*((double *)p)); p+=8; 01312 } else if (x->info.type==_jit_sym_symbol) { 01313 jit_atom_setsym((*rav)+off+i,*((t_symbol **)p)); p+=4; 01314 } else if (x->info.type==_jit_sym_object) { 01315 jit_atom_setobj((*rav)+off+i,*((t_object **)p)); p+=4; 01316 } 01317 01318 } 01319 jit_matrix_lock(x,savelock); 01320 } 01321 return JIT_ERR_NONE; 01322 } else { 01323 return JIT_ERR_INVALID_PTR; 01324 } 01325 01326 pakka: 01327 jit_matrix_lock(x,savelock); 01328 return JIT_ERR_OUT_OF_BOUNDS; 01329 } 01330 01331 t_jit_err jit_matrix_getcell_typed(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv, t_atom *rv) 01332 { 01333 long rac=0,i; 01334 t_atom *rav=NULL; 01335 t_jit_err err; 01336 01337 if (err=jit_matrix_getcell(x,ps_getcell,argc,argv,&rac,&rav)) 01338 return JIT_ERR_GENERIC; 01339 if (rac&&rav) { 01340 if (rv&&rac) { 01341 for (i=0;(i<rac)&&(rav[i].a_w.w_sym!=_jit_sym_val);i++) 01342 ; 01343 if (rav[i].a_w.w_sym==_jit_sym_val) 01344 i++; 01345 jit_atom_setobj(rv,object_new(ps_nobox,ps_atomarray,rac-i,rav+i)); 01346 jit_freebytes(rav, sizeof(t_atom)*rac); 01347 return JIT_ERR_NONE; 01348 } 01349 jit_freebytes(rav, sizeof(t_atom)*rac); 01350 } 01351 return JIT_ERR_GENERIC; 01352 } 01353 01354 /** 01355 * Sets all cells to the value provided. 01356 * See Jitter user documentation for more information. 01357 * 01358 * @ingroup matrixmod 01359 * 01360 * @param x t_jit_matrix object pointer 01361 * @param s message symbol pointer 01362 * @param argc argument count 01363 * @param argv argument vector 01364 * 01365 * @return t_jit_err error code 01366 * 01367 * @warning This function is not exported, but is provided 01368 * for reference when calling via jit_object_method 01369 * on an intance of t_jit_matrix. 01370 */ 01371 t_jit_err jit_matrix_setall(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv) 01372 { 01373 long savelock,i; 01374 uchar cval[JIT_MATRIX_MAX_PLANECOUNT]; 01375 long lval[JIT_MATRIX_MAX_PLANECOUNT]; 01376 float fval[JIT_MATRIX_MAX_PLANECOUNT]; 01377 double dval[JIT_MATRIX_MAX_PLANECOUNT]; 01378 void *cells; 01379 01380 if (x) { 01381 CLIP(argc,0,JIT_MATRIX_MAX_PLANECOUNT); 01382 if (argc&&argv) { 01383 if (x->info.type==_jit_sym_char) { 01384 for (i=0;i<argc;i++) cval[i] = jit_atom_getcharfix(argv+i); 01385 if (argc==1) 01386 for (;i<x->info.planecount;i++) cval[i] = cval[0]; 01387 else 01388 for (;i<x->info.planecount;i++) cval[i] = 0; 01389 cells = cval; 01390 } else if (x->info.type==_jit_sym_long) { 01391 for (i=0;i<argc;i++) lval[i] = jit_atom_getlong(argv+i); 01392 if (argc==1) 01393 for (;i<x->info.planecount;i++) lval[i] = lval[0]; 01394 else 01395 for (;i<x->info.planecount;i++) lval[i] = 0; 01396 cells = lval; 01397 } else if (x->info.type==_jit_sym_float32) { 01398 for (i=0;i<argc;i++) fval[i] = jit_atom_getfloat(argv+i); 01399 if (argc==1) 01400 for (;i<x->info.planecount;i++) fval[i] = fval[0]; 01401 else 01402 for (;i<x->info.planecount;i++) fval[i] = 0; 01403 cells = fval; 01404 } else if (x->info.type==_jit_sym_float64) { 01405 for (i=0;i<argc;i++) dval[i] = jit_atom_getfloat(argv+i); 01406 if (argc==1) 01407 for (;i<x->info.planecount;i++) dval[i] = dval[0]; 01408 else 01409 for (;i<x->info.planecount;i++) dval[i] = 0; 01410 cells = dval; 01411 } 01412 savelock = jit_matrix_lock(x,1); 01413 if (!x->data) goto pakka; 01414 jit_matrix_setall_ndim(x->info.dimcount, x->info.dim, x->info.planecount, cells, &x->info, x->data); 01415 jit_matrix_lock(x,savelock); 01416 } 01417 return JIT_ERR_NONE; 01418 } else { 01419 return JIT_ERR_INVALID_PTR; 01420 } 01421 01422 pakka: 01423 jit_matrix_lock(x,savelock); 01424 return JIT_ERR_OUT_OF_BOUNDS; 01425 } 01426 01427 #ifdef WIN_32 01428 #define ASM_DWORD_PTR dword ptr 01429 #else 01430 #define ASM_DWORD_PTR 01431 #endif 01432 01433 void jit_matrix_setall_ndim(long dimcount, long *dim, long planecount, void *cells, t_jit_matrix_info *in_minfo, char *bip) 01434 { 01435 long i,j,n; 01436 char *ip; 01437 t_jit_op_info in_opinfo,val_opinfo; 01438 01439 if (dimcount<1) return; //safety 01440 01441 switch(dimcount) { 01442 case 1: 01443 dim[1]=1; 01444 case 2: 01445 n = dim[0]; 01446 in_opinfo.stride = in_minfo->dim[0]>1?in_minfo->planecount:0; 01447 val_opinfo.stride = 0; 01448 if (in_minfo->type==_jit_sym_char) { 01449 for (i=0;i<dim[1];i++){ 01450 for (j=0;j<planecount;j++) { 01451 in_opinfo.p = bip + i*in_minfo->dimstride[1] + j%in_minfo->planecount; 01452 val_opinfo.p = &(((uchar *)cells)[j]); 01453 jit_op_vector_pass_char(n, NULL, &val_opinfo, NULL, &in_opinfo); 01454 } 01455 } 01456 } else if (in_minfo->type==_jit_sym_long) { 01457 for (i=0;i<dim[1];i++){ 01458 for (j=0;j<planecount;j++) { 01459 in_opinfo.p = bip + i*in_minfo->dimstride[1] + (j%in_minfo->planecount)*4; 01460 val_opinfo.p = &(((long *)cells)[j]); 01461 jit_op_vector_pass_long(n, NULL, &val_opinfo, NULL, &in_opinfo); 01462 } 01463 } 01464 } else if (in_minfo->type==_jit_sym_float32) { 01465 for (i=0;i<dim[1];i++){ 01466 for (j=0;j<planecount;j++) { 01467 in_opinfo.p = bip + i*in_minfo->dimstride[1] + (j%in_minfo->planecount)*4; 01468 val_opinfo.p = &(((float *)cells)[j]); 01469 jit_op_vector_pass_float32(n, NULL, &val_opinfo, NULL, &in_opinfo); 01470 } 01471 } 01472 } else if (in_minfo->type==_jit_sym_float64) { 01473 for (i=0;i<dim[1];i++){ 01474 for (j=0;j<planecount;j++) { 01475 in_opinfo.p = bip + i*in_minfo->dimstride[1] + (j%in_minfo->planecount)*8; 01476 val_opinfo.p = &(((double *)cells)[j]); 01477 jit_op_vector_pass_float64(n, NULL, &val_opinfo, NULL, &in_opinfo); 01478 } 01479 } 01480 } 01481 break; 01482 default: 01483 for (i=0;i<dim[dimcount-1];i++) { 01484 ip = bip + i*in_minfo->dimstride[dimcount-1]; 01485 jit_matrix_setall_ndim(dimcount-1,dim,planecount,cells,in_minfo,ip); 01486 } 01487 } 01488 } 01489 01490 /** 01491 * Copies Jitter matrix data to GWorld data. 01492 * 01493 * @ingroup matrixmod 01494 * 01495 * @param x t_jit_matrix object pointer 01496 * @param gp gworld pointer 01497 * @param gcinfo conversion information pointer 01498 * 01499 * @return t_jit_err error code 01500 * 01501 * @warning This function is not exported, but is provided 01502 * for reference when calling via jit_object_method 01503 * on an intance of t_jit_matrix. 01504 */ 01505 t_jit_err jit_matrix_togworld(t_jit_matrix *x, GWorldPtr gp, t_gworld_conv_info *gcinfo) 01506 { 01507 long savelock,i,j; 01508 long srcheight,srcwidth,srccellstride,srcrowstride; 01509 long dstheight,dstwidth,dstrowstride; 01510 uchar *srcaddress,*dstaddress; 01511 PixMapHandle pmh; 01512 long pmap0,pmap1,pmap2,pmap3; 01513 long flags=0,xdir,ydir; 01514 long xmin,xmax,ymin,ymax; 01515 double dxinc=0,dyinc=0; 01516 Rect r; 01517 long quickswap = FALSE; 01518 long widfactor; 01519 01520 if (x&&gp) { 01521 pmh = GetGWorldPixMap(gp); 01522 if (!pmh) { 01523 goto pakka; 01524 } 01525 LockPixels(pmh); 01526 savelock = jit_matrix_lock(x,1); 01527 01528 srcaddress = x->data; 01529 dstaddress = (uchar *)GetPixBaseAddr(pmh); 01530 if ((!srcaddress)||(!dstaddress)) { 01531 UnlockPixels(pmh); 01532 jit_matrix_lock(x,savelock); 01533 goto pakka; 01534 } 01535 srcwidth = x->info.dim[0]; 01536 srcheight = x->info.dim[1]; 01537 GetPortBounds(gp,&r); 01538 if ((**pmh).pixelSize == 16) // uyvy 01539 widfactor = 1L; 01540 else 01541 widfactor = 0L; 01542 dstwidth = (r.right-r.left) >> widfactor; 01543 dstheight = (r.bottom-r.top); 01544 srccellstride = x->info.dimstride[0]; 01545 srcrowstride = x->info.dimstride[1]; 01546 dstrowstride = GetPixRowBytes(pmh); 01547 01548 if (gcinfo) { 01549 flags = gcinfo->flags; 01550 pmap0 = CLAMP(gcinfo->planemap[0] % x->info.planecount,0,3); 01551 pmap1 = CLAMP(gcinfo->planemap[1] % x->info.planecount,0,3); 01552 pmap2 = CLAMP(gcinfo->planemap[2] % x->info.planecount,0,3); 01553 pmap3 = CLAMP(gcinfo->planemap[3] % x->info.planecount,0,3); 01554 if (flags&JIT_MATRIX_CONVERT_SRCDIM) { 01555 if (gcinfo->srcrect.top<0) gcinfo->srcrect.top = 0; 01556 else if (gcinfo->srcrect.top>=srcheight) gcinfo->srcrect.top = srcheight-1; 01557 if (gcinfo->srcrect.bottom<0) gcinfo->srcrect.bottom = 0; 01558 else if (gcinfo->srcrect.bottom>=srcheight) gcinfo->srcrect.bottom = srcheight-1; 01559 if (gcinfo->srcrect.left<0) gcinfo->srcrect.left = 0; 01560 else if (gcinfo->srcrect.left>=srcwidth) gcinfo->srcrect.left = srcwidth-1; 01561 if (gcinfo->srcrect.right<0) gcinfo->srcrect.right = 0; 01562 else if (gcinfo->srcrect.right>=srcwidth) gcinfo->srcrect.right = srcwidth-1; 01563 srcheight = gcinfo->srcrect.bottom - gcinfo->srcrect.top; 01564 srcheight = (srcheight>=0) ? srcheight+1 : srcheight-1; 01565 srcwidth = gcinfo->srcrect.right - gcinfo->srcrect.left; 01566 srcwidth = (srcwidth>=0) ? srcwidth+1 : srcwidth-1; 01567 srcaddress += (srccellstride*gcinfo->srcrect.left) + (srcrowstride*gcinfo->srcrect.top); 01568 } 01569 if (flags&JIT_MATRIX_CONVERT_DSTDIM) { 01570 if (gcinfo->dstrect.top<0) gcinfo->dstrect.top = 0; 01571 else if (gcinfo->dstrect.top>=dstheight) gcinfo->dstrect.top = dstheight-1; 01572 if (gcinfo->dstrect.bottom<0) gcinfo->dstrect.bottom = 0; 01573 else if (gcinfo->dstrect.bottom>=dstheight) gcinfo->dstrect.bottom = dstheight-1; 01574 if (gcinfo->dstrect.left<0) gcinfo->dstrect.left = 0; 01575 else if (gcinfo->dstrect.left>=dstwidth) gcinfo->dstrect.left = dstwidth-1; 01576 if (gcinfo->dstrect.right<0) gcinfo->dstrect.right = 0; 01577 else if (gcinfo->dstrect.right>=dstwidth) gcinfo->dstrect.right = dstwidth-1; 01578 dstheight = ABS(gcinfo->dstrect.bottom - gcinfo->dstrect.top) + 1; 01579 dstwidth = ABS(gcinfo->dstrect.right - gcinfo->dstrect.left) + 1; 01580 dstaddress += (4*MIN(gcinfo->dstrect.left,gcinfo->dstrect.right)) + 01581 (dstrowstride*MIN(gcinfo->dstrect.top,gcinfo->dstrect.bottom)); 01582 } 01583 } else { 01584 pmap0 = 0; 01585 pmap1 = 1 % x->info.planecount; 01586 pmap2 = 2 % x->info.planecount; 01587 pmap3 = 3 % x->info.planecount; 01588 } 01589 01590 if ((x->info.planecount==4) && 01591 (pmap0==3) && 01592 (pmap1==2) && 01593 (pmap2==1) && 01594 (pmap3==0)) 01595 { 01596 quickswap = TRUE; 01597 } 01598 01599 //calculate scale factor 01600 if (gcinfo&&(gcinfo->flags&JIT_MATRIX_CONVERT_INTERP)) { 01601 if ((ABS(srcwidth)>1)&&(ABS(dstwidth)>1)) 01602 dxinc = ((double)srcwidth-DIRECTION(srcwidth))/((double)dstwidth-1); 01603 if ((ABS(srcheight)>1)&&(ABS(dstheight)>1)) 01604 dyinc = ((double)srcheight-DIRECTION(srcheight))/((double)dstheight-1); 01605 } else { 01606 if ((ABS(srcwidth)>1)&&(ABS(dstwidth)>1)) 01607 dxinc = ((double)srcwidth)/((double)dstwidth); 01608 if ((ABS(srcheight)>1)&&(ABS(dstheight)>1)) 01609 dyinc = ((double)srcheight)/((double)dstheight); 01610 } 01611 01612 //compensate for potential FP error 01613 if (ABS(dxinc)<JIT_MATRIX_INC_THRESH) dxinc = 0; 01614 if (ABS(dyinc)<JIT_MATRIX_INC_THRESH) dyinc = 0; 01615 01616 xdir = DIRECTION(dxinc); 01617 ydir = DIRECTION(dyinc); 01618 01619 switch (xdir) 01620 { 01621 case 1: xmax = srcwidth-1; xmin = 0; break; 01622 case -1: xmin = srcwidth+1; xmax = 0; break; 01623 default: xmin = xmax = 0; break; 01624 } 01625 switch (ydir) 01626 { 01627 case 1: ymax = srcheight-1; ymin = 0; break; 01628 case -1: ymin = srcheight+1; ymax = 0; break; 01629 default: ymin = ymax = 0; break; 01630 } 01631 01632 //xidx,yidx should be the top left of the src rect(clip to zero) 01633 //xinc,yinc should be the ratio of the source vs. destination rects 01634 if (x->info.type==_jit_sym_char) { 01635 Fixed xidx=0,xinc=0,yidx=0,yinc=0; 01636 Fixed xfudge,yfudge; 01637 01638 xfudge = DoubleToFixed((xdir>=0)?JIT_MATRIX_FUDGE:1.-JIT_MATRIX_FUDGE); 01639 yfudge = DoubleToFixed((ydir>=0)?JIT_MATRIX_FUDGE:1.-JIT_MATRIX_FUDGE); 01640 01641 xinc = DoubleToFixed(dxinc); 01642 yinc = DoubleToFixed(dyinc); 01643 01644 if (flags&JIT_MATRIX_CONVERT_INTERP) { 01645 uchar *src,*src2,*dst,*x0,*x1,*x2,*x3; 01646 long xidx_int,xidx_int2,yidx_int,yidx_int2; 01647 Fixed c0,c1,c2,c3; 01648 Fixed xfrak,yfrak,xfrak_inv,yfrak_inv; 01649 01650 for(i=0;i<dstheight;i++) 01651 { 01652 yidx_int = FixedToInt(yidx); 01653 yidx_int2 = yidx_int+ydir; 01654 CLIP(yidx_int2,ymin,ymax); 01655 src = (uchar *)(srcaddress + (yidx_int * srcrowstride)); 01656 src2 = (uchar *)(srcaddress + (yidx_int2 * srcrowstride)); //this should never be past the end 01657 dst = (uchar *)(dstaddress + (i * dstrowstride)); 01658 01659 --dst; 01660 xidx = 0; 01661 yfrak = FixedFraction(yidx); 01662 if (ydir<0&&yfrak!=0) yfrak = fixed1-yfrak; //FixedFraction() always positive 01663 yfrak_inv = fixed1-yfrak; 01664 for(j=0;j<dstwidth;j++) 01665 { 01666 xidx_int = FixedToInt(xidx); 01667 xidx_int2 = xidx_int+xdir; 01668 CLIP(xidx_int2,xmin,xmax); 01669 xfrak = FixedFraction(xidx); 01670 if (xdir<0&&xfrak!=0) xfrak = fixed1-xfrak; //FixedFraction() always positive 01671 xfrak_inv = fixed1-xfrak; 01672 xidx_int *= srccellstride; 01673 xidx_int2 *= srccellstride; 01674 x0 = src + xidx_int; 01675 x1 = src + xidx_int2; 01676 x2 = src2 + xidx_int; 01677 x3 = src2 + xidx_int2; 01678 c0 = FixMul(xfrak_inv,yfrak_inv); 01679 c1 = FixMul(xfrak,yfrak_inv); 01680 c2 = FixMul(xfrak_inv,yfrak); 01681 c3 = FixMul(xfrak,yfrak); 01682 *++dst=((long)(*(x0+pmap0))*c0 + (long)(*(x1+pmap0))*c1 + (long)(*(x2+pmap0))*c2 + (long)(*(x3+pmap0))*c3)>>16L; 01683 *++dst=((long)(*(x0+pmap1))*c0 + (long)(*(x1+pmap1))*c1 + (long)(*(x2+pmap1))*c2 + (long)(*(x3+pmap1))*c3)>>16L; 01684 *++dst=((long)(*(x0+pmap2))*c0 + (long)(*(x1+pmap2))*c1 + (long)(*(x2+pmap2))*c2 + (long)(*(x3+pmap2))*c3)>>16L; 01685 *++dst=((long)(*(x0+pmap3))*c0 + (long)(*(x1+pmap3))*c1 + (long)(*(x2+pmap3))*c2 + (long)(*(x3+pmap3))*c3)>>16L; 01686 xidx+=xinc; 01687 } 01688 yidx+=yinc; 01689 } 01690 01691 } else { 01692 long xidx_int,yidx_int; 01693 01694 yidx = yfudge; 01695 01696 if ((x->info.planecount==4)&&(quickswap||((pmap0==0)&&(pmap1==1)&&(pmap2==2)&&(pmap3==3)))) { 01697 long *src,*dst; 01698 long quad=dstwidth/4; 01699 long rem=dstwidth%4; 01700 //optimized cases 01701 if (xinc==fixed1) { 01702 for(i=0;i<dstheight;i++) 01703 { 01704 yidx_int = FixedToInt(yidx); 01705 CLIP(yidx_int,ymin,ymax); 01706 src = (long *)(srcaddress + (yidx_int*srcrowstride)); 01707 dst = (long *)(dstaddress + (i*dstrowstride)); 01708 01709 if (quickswap) { 01710 #ifdef JIT_LITTLE_ENDIAN 01711 for(j=0;j<quad;j++) { 01712 __asm { 01713 // load pointers 01714 MOV esi,ASM_DWORD_PTR src 01715 MOV edi,ASM_DWORD_PTR dst 01716 // move + swap one 32bit word, increment ptrs 01717 MOV eax,[esi] 01718 BSWAP eax 01719 MOV [edi],eax 01720 ADD esi,4 01721 ADD edi,4 01722 // move + swap one 32bit word, increment ptrs 01723 MOV eax,[esi] 01724 BSWAP eax 01725 MOV [edi],eax 01726 ADD esi,4 01727 ADD edi,4 01728 // move + swap one 32bit word, increment ptrs 01729 MOV eax,[esi] 01730 BSWAP eax 01731 MOV [edi],eax 01732 ADD esi,4 01733 ADD edi,4 01734 // move + swap one 32bit word, increment ptrs 01735 MOV eax,[esi] 01736 BSWAP eax 01737 MOV [edi],eax 01738 ADD esi,4 01739 ADD edi,4 01740 // write pointers 01741 MOV ASM_DWORD_PTR src,esi 01742 MOV ASM_DWORD_PTR dst,edi 01743 } 01744 } 01745 01746 for(j=0;j<rem;j++) { 01747 __asm { 01748 // load pointers 01749 MOV esi,ASM_DWORD_PTR src 01750 MOV edi,ASM_DWORD_PTR dst 01751 // move + swap one 32bit word, increment ptrs 01752 MOV eax,[esi] 01753 BSWAP eax 01754 MOV [edi],eax 01755 ADD esi,4 01756 ADD edi,4 01757 // write pointers 01758 MOV ASM_DWORD_PTR src,esi 01759 MOV ASM_DWORD_PTR dst,edi 01760 } 01761 } 01762 #else 01763 --dst; 01764 --src; 01765 for(j=0;j<quad;j++) { 01766 FAST_INC(src); 01767 FAST_INC(dst); 01768 ((char *)dst)[0] = ((char *)src)[3]; 01769 ((char *)dst)[1] = ((char *)src)[2]; 01770 ((char *)dst)[2] = ((char *)src)[1]; 01771 ((char *)dst)[3] = ((char *)src)[0]; 01772 FAST_INC(src); 01773 FAST_INC(dst); 01774 ((char *)dst)[0] = ((char *)src)[3]; 01775 ((char *)dst)[1] = ((char *)src)[2]; 01776 ((char *)dst)[2] = ((char *)src)[1]; 01777 ((char *)dst)[3] = ((char *)src)[0]; 01778 FAST_INC(src); 01779 FAST_INC(dst); 01780 ((char *)dst)[0] = ((char *)src)[3]; 01781 ((char *)dst)[1] = ((char *)src)[2]; 01782 ((char *)dst)[2] = ((char *)src)[1]; 01783 ((char *)dst)[3] = ((char *)src)[0]; 01784 FAST_INC(src); 01785 FAST_INC(dst); 01786 ((char *)dst)[0] = ((char *)src)[3]; 01787 ((char *)dst)[1] = ((char *)src)[2]; 01788 ((char *)dst)[2] = ((char *)src)[1]; 01789 ((char *)dst)[3] = ((char *)src)[0]; 01790 } 01791 for(j=0;j<rem;j++) { 01792 FAST_INC(src); 01793 FAST_INC(dst); 01794 ((char *)dst)[0] = ((char *)src)[3]; 01795 ((char *)dst)[1] = ((char *)src)[2]; 01796 ((char *)dst)[2] = ((char *)src)[1]; 01797 ((char *)dst)[3] = ((char *)src)[0]; 01798 } 01799 #endif 01800 } else { 01801 FAST_INC_SETUP(src); 01802 FAST_INC_SETUP(dst); 01803 for(j=0;j<quad;j++) 01804 { 01805 FAST_INC_DEREF(dst) = FAST_INC_DEREF(src); 01806 FAST_INC_DEREF(dst) = FAST_INC_DEREF(src); 01807 FAST_INC_DEREF(dst) = FAST_INC_DEREF(src); 01808 FAST_INC_DEREF(dst) = FAST_INC_DEREF(src); 01809 } 01810 for(j=0;j<rem;j++) 01811 { 01812 FAST_INC_DEREF(dst) = FAST_INC_DEREF(src); 01813 } 01814 } 01815 yidx+=yinc; 01816 } 01817 } else { 01818 for(i=0;i<dstheight;i++) 01819 { 01820 yidx_int = FixedToInt(yidx); 01821 CLIP(yidx_int,ymin,ymax); 01822 src = (long *)(srcaddress + (yidx_int*srcrowstride)); 01823 dst = (long *)(dstaddress + (i*dstrowstride)); 01824 01825 xidx = xfudge; 01826 01827 //should only need clipping at boundaries 01828 xidx_int = FixedToInt(xidx); 01829 CLIP(xidx_int,xmin,xmax); 01830 *dst=*(src + xidx_int); 01831 xidx+=xinc; 01832 01833 if (quickswap) 01834 *dst = SWAP32(*dst); 01835 01836 dst++; 01837 01838 if (quickswap) { 01839 long tmp; 01840 for(j=2;j<dstwidth;j++) 01841 { 01842 tmp=*(src + FixedToInt(xidx)); 01843 *dst++ = SWAP32(tmp); 01844 xidx+=xinc; 01845 } 01846 } else { 01847 for(j=2;j<dstwidth;j++) 01848 { 01849 *dst++=*(src + FixedToInt(xidx)); 01850 xidx+=xinc; 01851 } 01852 } 01853 if (dstwidth>1) { 01854 xidx_int = FixedToInt(xidx); 01855 CLIP(xidx_int,xmin,xmax); 01856 *dst=*(src + xidx_int); 01857 if (quickswap) 01858 *dst = SWAP32(*dst); 01859 } 01860 01861 yidx+=yinc; 01862 } 01863 } 01864 } else { 01865 uchar *src0,*src,*dst; 01866 01867 for(i=0;i<dstheight;i++) 01868 { 01869 yidx_int = FixedToInt(yidx); 01870 CLIP(yidx_int,ymin,ymax); 01871 src0 = (uchar *)(srcaddress + (yidx_int*srcrowstride)); 01872 dst = (uchar *)(dstaddress + (i*dstrowstride)); 01873 01874 --dst; 01875 xidx = xfudge; 01876 01877 for(j=0;j<dstwidth;j++) 01878 { 01879 xidx_int = FixedToInt(xidx); 01880 CLIP(xidx_int,xmin,xmax); 01881 src = src0 + (xidx_int*srccellstride); 01882 *++dst=*(src+pmap0); 01883 *++dst=*(src+pmap1); 01884 *++dst=*(src+pmap2); 01885 *++dst=*(src+pmap3); 01886 xidx+=xinc; 01887 } 01888 yidx+=yinc; 01889 } 01890 } 01891 } 01892 } else if (x->info.type==_jit_sym_long) { 01893 srccellstride /= 4; 01894 01895 if (flags&JIT_MATRIX_CONVERT_INTERP) { 01896 uchar *dst; 01897 long *src,*src2,*x0,*x1,*x2,*x3; 01898 long xidx_int,xidx_int2,yidx_int,yidx_int2; 01899 float c0,c1,c2,c3; 01900 float xfrak,yfrak,xfrak_inv,yfrak_inv; 01901 double xidx=0,xinc=0,yidx=0,yinc=0; 01902 01903 xinc = dxinc; 01904 yinc = dyinc; 01905 01906 for(i=0;i<dstheight;i++) 01907 { 01908 yidx_int = (long)yidx; 01909 yidx_int2 = yidx_int+ydir; 01910 CLIP(yidx_int2,ymin,ymax); 01911 src = (long *)(srcaddress + (yidx_int * srcrowstride)); 01912 src2 = (long *)(srcaddress + (yidx_int2 * srcrowstride)); //this should never be past the end 01913 dst = (uchar *)(dstaddress + (i * dstrowstride)); 01914 01915 --dst; 01916 xidx = 0; 01917 yfrak = yidx-((long)yidx); 01918 if (ydir<0) yfrak = -yfrak; //float frak is neg 01919 yfrak_inv = 1-yfrak; 01920 for(j=0;j<dstwidth;j++) 01921 { 01922 xidx_int = (long)xidx; 01923 xidx_int2 = xidx_int+xdir; 01924 CLIP(xidx_int2,xmin,xmax); 01925 xfrak = xidx-xidx_int; 01926 if (xdir<0) xfrak = -xfrak; //float frak is neg 01927 xfrak_inv = 1-xfrak; 01928 xidx_int *= srccellstride; 01929 xidx_int2 *= srccellstride; 01930 x0 = src + xidx_int; 01931 x1 = src + xidx_int2; 01932 x2 = src2 + xidx_int; 01933 x3 = src2 + xidx_int2; 01934 c0 = xfrak_inv*yfrak_inv; 01935 c1 = xfrak*yfrak_inv; 01936 c2 = xfrak_inv*yfrak; 01937 c3 = xfrak*yfrak; 01938 *++dst=(uchar)((float)(*(x0+pmap0))*c0 + (float)(*(x1+pmap0))*c1 + (float)(*(x2+pmap0))*c2 + (float)(*(x3+pmap0))*c3); 01939 *++dst=(uchar)((float)(*(x0+pmap1))*c0 + (float)(*(x1+pmap1))*c1 + (float)(*(x2+pmap1))*c2 + (float)(*(x3+pmap1))*c3); 01940 *++dst=(uchar)((float)(*(x0+pmap2))*c0 + (float)(*(x1+pmap2))*c1 + (float)(*(x2+pmap2))*c2 + (float)(*(x3+pmap2))*c3); 01941 *++dst=(uchar)((float)(*(x0+pmap3))*c0 + (float)(*(x1+pmap3))*c1 + (float)(*(x2+pmap3))*c2 + (float)(*(x3+pmap3))*c3); 01942 xidx+=xinc; 01943 } 01944 yidx+=yinc; 01945 } 01946 } else { 01947 uchar *dst; 01948 long *src0,*src; 01949 Fixed xidx=0,xinc=0,yidx=0,yinc=0; 01950 Fixed xfudge,yfudge; 01951 long xidx_int,yidx_int; 01952 01953 xfudge = DoubleToFixed((xdir>=0)?JIT_MATRIX_FUDGE:1.-JIT_MATRIX_FUDGE); 01954 yfudge = DoubleToFixed((ydir>=0)?JIT_MATRIX_FUDGE:1.-JIT_MATRIX_FUDGE); 01955 01956 xinc = DoubleToFixed(dxinc); 01957 yinc = DoubleToFixed(dyinc); 01958 01959 yidx = yfudge; 01960 01961 for(i=0;i<dstheight;i++) 01962 { 01963 yidx_int = FixedToInt(yidx); 01964 CLIP(yidx_int,ymin,ymax); 01965 src0 = (long *)(srcaddress + (yidx_int*srcrowstride)); 01966 dst = (uchar *)(dstaddress + (i*dstrowstride)); 01967 01968 --dst; 01969 xidx = xfudge; 01970 01971 for(j=0;j<dstwidth;j++) 01972 { 01973 xidx_int = FixedToInt(xidx); 01974 CLIP(xidx_int,xmin,xmax); 01975 src = src0 + (xidx_int*srccellstride); 01976 *++dst=(uchar)(*(src+pmap0)); 01977 *++dst=(uchar)(*(src+pmap1)); 01978 *++dst=(uchar)(*(src+pmap2)); 01979 *++dst=(uchar)(*(src+pmap3)); 01980 xidx+=xinc; 01981 } 01982 yidx+=yinc; 01983 } 01984 } 01985 } else if (x->info.type==_jit_sym_float32) { 01986 srccellstride /= 4; 01987 01988 if (flags&JIT_MATRIX_CONVERT_INTERP) { 01989 uchar *dst; 01990 float *src,*src2,*x0,*x1,*x2,*x3; 01991 long xidx_int,xidx_int2,yidx_int,yidx_int2; 01992 float c0,c1,c2,c3; 01993 float xfrak,yfrak,xfrak_inv,yfrak_inv; 01994 double xidx=0,xinc=0,yidx=0,yinc=0; 01995 float tmp; 01996 01997 xinc = dxinc; 01998 yinc = dyinc; 01999 02000 for(i=0;i<dstheight;i++) 02001 { 02002 yidx_int = (long)yidx; 02003 yidx_int2 = yidx_int+ydir; 02004 CLIP(yidx_int2,ymin,ymax); 02005 src = (float *)(srcaddress + (yidx_int * srcrowstride)); 02006 src2 = (float *)(srcaddress + (yidx_int2 * srcrowstride)); //this should never be past the end 02007 dst = (uchar *)(dstaddress + (i * dstrowstride)); 02008 02009 --dst; 02010 xidx = 0; 02011 yfrak = yidx-((long)yidx); 02012 if (ydir<0) yfrak = -yfrak; //float frak is neg 02013 yfrak_inv = 1-yfrak; 02014 for(j=0;j<dstwidth;j++) 02015 { 02016 xidx_int = (long)xidx; 02017 xidx_int2 = xidx_int+xdir; 02018 CLIP(xidx_int2,xmin,xmax); 02019 xfrak = xidx-xidx_int; 02020 if (xdir<0) xfrak = -xfrak; //float frak is neg 02021 xfrak_inv = 1-xfrak; 02022 xidx_int *= srccellstride; 02023 xidx_int2 *= srccellstride; 02024 x0 = src + xidx_int; 02025 x1 = src + xidx_int2; 02026 x2 = src2 + xidx_int; 02027 x3 = src2 + xidx_int2; 02028 c0 = xfrak_inv*yfrak_inv; 02029 c1 = xfrak*yfrak_inv; 02030 c2 = xfrak_inv*yfrak; 02031 c3 = xfrak*yfrak; 02032 02033 tmp = ((float)(*(x0+pmap0))*c0 + (float)(*(x1+pmap0))*c1 + (float)(*(x2+pmap0))*c2 + (float)(*(x3+pmap0))*c3); 02034 *++dst = FM_CONVFN_FLOATTOCHAR(tmp); 02035 tmp = ((float)(*(x0+pmap1))*c0 + (float)(*(x1+pmap1))*c1 + (float)(*(x2+pmap1))*c2 + (float)(*(x3+pmap1))*c3); 02036 *++dst = FM_CONVFN_FLOATTOCHAR(tmp); 02037 tmp = ((float)(*(x0+pmap2))*c0 + (float)(*(x1+pmap2))*c1 + (float)(*(x2+pmap2))*c2 + (float)(*(x3+pmap2))*c3); 02038 *++dst = FM_CONVFN_FLOATTOCHAR(tmp); 02039 tmp = ((float)(*(x0+pmap3))*c0 + (float)(*(x1+pmap3))*c1 + (float)(*(x2+pmap3))*c2 + (float)(*(x3+pmap3))*c3); 02040 *++dst = FM_CONVFN_FLOATTOCHAR(tmp); 02041 xidx+=xinc; 02042 } 02043 yidx+=yinc; 02044 } 02045 } else { 02046 uchar *dst; 02047 float *src0,*src; 02048 Fixed xidx=0,xinc=0,yidx=0,yinc=0; 02049 Fixed xfudge,yfudge; 02050 long xidx_int,yidx_int; 02051 float tmp; 02052 02053 xfudge = DoubleToFixed((xdir>=0)?JIT_MATRIX_FUDGE:1.-JIT_MATRIX_FUDGE); 02054 yfudge = DoubleToFixed((ydir>=0)?JIT_MATRIX_FUDGE:1.-JIT_MATRIX_FUDGE); 02055 02056 xinc = DoubleToFixed(dxinc); 02057 yinc = DoubleToFixed(dyinc); 02058 02059 yidx = yfudge; 02060 02061 for(i=0;i<dstheight;i++) 02062 { 02063 yidx_int = FixedToInt(yidx); 02064 CLIP(yidx_int,ymin,ymax); 02065 src0 = (float *)(srcaddress + (yidx_int*srcrowstride)); 02066 dst = (uchar *)(dstaddress + (i*dstrowstride)); 02067 02068 --dst; 02069 xidx = xfudge; 02070 02071 for(j=0;j<dstwidth;j++) 02072 { 02073 xidx_int = FixedToInt(xidx); 02074 CLIP(xidx_int,xmin,xmax); 02075 src = src0 + (xidx_int*srccellstride); 02076 tmp = *(src+pmap0); 02077 *++dst = FM_CONVFN_FLOATTOCHAR(tmp); 02078 tmp = *(src+pmap1); 02079 *++dst = FM_CONVFN_FLOATTOCHAR(tmp); 02080 tmp = *(src+pmap2); 02081 *++dst = FM_CONVFN_FLOATTOCHAR(tmp); 02082 tmp = *(src+pmap3); 02083 *++dst = FM_CONVFN_FLOATTOCHAR(tmp); 02084 xidx+=xinc; 02085 } 02086 yidx+=yinc; 02087 } 02088 } 02089 } else if (x->info.type==_jit_sym_float64) { 02090 srccellstride /= 8; 02091 02092 if (flags&JIT_MATRIX_CONVERT_INTERP) { 02093 uchar *dst; 02094 double *src,*src2,*x0,*x1,*x2,*x3; 02095 long xidx_int,xidx_int2,yidx_int,yidx_int2; 02096 double c0,c1,c2,c3; 02097 double xfrak,yfrak,xfrak_inv,yfrak_inv; 02098 double xidx=0,xinc=0,yidx=0,yinc=0; 02099 double tmp; 02100 02101 xinc = dxinc; 02102 yinc = dyinc; 02103 02104 for(i=0;i<dstheight;i++) 02105 { 02106 yidx_int = (long)yidx; 02107 yidx_int2 = yidx_int+ydir; 02108 CLIP(yidx_int2,ymin,ymax); 02109 src = (double *)(srcaddress + (yidx_int * srcrowstride)); 02110 src2 = (double *)(srcaddress + (yidx_int2 * srcrowstride)); //this should never be past the end 02111 dst = (uchar *)(dstaddress + (i * dstrowstride)); 02112 02113 --dst; 02114 xidx = 0; 02115 yfrak = yidx-((long)yidx); 02116 if (ydir<0) yfrak = -yfrak; //float frak is neg 02117 yfrak_inv = 1-yfrak; 02118 for(j=0;j<dstwidth;j++) 02119 { 02120 xidx_int = (long)xidx; 02121 xidx_int2 = xidx_int+xdir; 02122 CLIP(xidx_int2,xmin,xmax); 02123 xfrak = xidx-xidx_int; 02124 if (xdir<0) xfrak = -xfrak; //float frak is neg 02125 xfrak_inv = 1-xfrak; 02126 xidx_int *= 4; 02127 xidx_int2 *= 4; 02128 x0 = src + xidx_int; 02129 x1 = src + xidx_int2; 02130 x2 = src2 + xidx_int; 02131 x3 = src2 + xidx_int2; 02132 c0 = xfrak_inv*yfrak_inv; 02133 c1 = xfrak*yfrak_inv; 02134 c2 = xfrak_inv*yfrak; 02135 c3 = xfrak*yfrak; 02136 tmp = ((double)(*(x0+pmap0))*c0 + (double)(*(x1+pmap0))*c1 + (double)(*(x2+pmap0))*c2 + (double)(*(x3+pmap0))*c3); 02137 *++dst = FM_CONVFN_DOUBLETOCHAR(tmp); 02138 tmp = ((double)(*(x0+pmap1))*c0 + (double)(*(x1+pmap1))*c1 + (double)(*(x2+pmap1))*c2 + (double)(*(x3+pmap1))*c3); 02139 *++dst = FM_CONVFN_DOUBLETOCHAR(tmp); 02140 tmp = ((double)(*(x0+pmap2))*c0 + (double)(*(x1+pmap2))*c1 + (double)(*(x2+pmap2))*c2 + (double)(*(x3+pmap2))*c3); 02141 *++dst = FM_CONVFN_DOUBLETOCHAR(tmp); 02142 tmp = ((double)(*(x0+pmap3))*c0 + (double)(*(x1+pmap3))*c1 + (double)(*(x2+pmap3))*c2 + (double)(*(x3+pmap3))*c3); 02143 *++dst = FM_CONVFN_DOUBLETOCHAR(tmp); 02144 xidx+=xinc; 02145 } 02146 yidx+=yinc; 02147 } 02148 } else { 02149 uchar *dst; 02150 double *src0,*src; 02151 Fixed xidx=0,xinc=0,yidx=0,yinc=0; 02152 Fixed xfudge,yfudge; 02153 long xidx_int,yidx_int; 02154 double tmp; 02155 02156 xfudge = DoubleToFixed((xdir>=0)?JIT_MATRIX_FUDGE:1.-JIT_MATRIX_FUDGE); 02157 yfudge = DoubleToFixed((ydir>=0)?JIT_MATRIX_FUDGE:1.-JIT_MATRIX_FUDGE); 02158 02159 xinc = DoubleToFixed(dxinc); 02160 yinc = DoubleToFixed(dyinc); 02161 02162 yidx = yfudge; 02163 02164 for(i=0;i<dstheight;i++) 02165 { 02166 yidx_int = FixedToInt(yidx); 02167 CLIP(yidx_int,ymin,ymax); 02168 src0 = (double *)(srcaddress + (yidx_int*srcrowstride)); 02169 dst = (uchar *)(dstaddress + (i*dstrowstride)); 02170 02171 --dst; 02172 xidx = xfudge; 02173 02174 for(j=0;j<dstwidth;j++) 02175 { 02176 xidx_int = FixedToInt(xidx); 02177 CLIP(xidx_int,xmin,xmax); 02178 src = src0 + (xidx_int*srccellstride); 02179 tmp = *(src+pmap0); 02180 *++dst = FM_CONVFN_DOUBLETOCHAR(tmp); 02181 tmp = *(src+pmap1); 02182 *++dst = FM_CONVFN_DOUBLETOCHAR(tmp); 02183 tmp = *(src+pmap2); 02184 *++dst = FM_CONVFN_DOUBLETOCHAR(tmp); 02185 tmp = *(src+pmap3); 02186 *++dst = FM_CONVFN_DOUBLETOCHAR(tmp); 02187 xidx+=xinc; 02188 } 02189 yidx+=yinc; 02190 } 02191 } 02192 } 02193 02194 UnlockPixels(pmh); 02195 jit_matrix_lock(x,savelock); 02196 return JIT_ERR_NONE; 02197 } else { 02198 return JIT_ERR_INVALID_PTR; 02199 } 02200 02201 pakka: 02202 return JIT_ERR_GENERIC; 02203 } 02204 02205 /** 02206 * Copies Jitter matrix data from GWorld data. 02207 * 02208 * @ingroup matrixmod 02209 * 02210 * @param x t_jit_matrix object pointer 02211 * @param gp gworld pointer 02212 * @param gcinfo conversion information pointer 02213 * 02214 * @return t_jit_err error code 02215 * 02216 * @warning This function is not exported, but is provided 02217 * for reference when calling via jit_object_method 02218 * on an intance of t_jit_matrix. 02219 */ 02220 t_jit_err jit_matrix_fromgworld(t_jit_matrix *x, GWorldPtr gp, t_gworld_conv_info *gcinfo) 02221 { 02222 long savelock,i,j; 02223 long srcheight,srcwidth,srcrowstride; 02224 long dstheight,dstwidth,dstcellstride,dstrowstride; 02225 uchar *srcaddress,*dstaddress; 02226 PixMapHandle pmh; 02227 long pmap0,pmap1,pmap2,pmap3; 02228 long flags=0,xdir,ydir; 02229 long xmin,xmax,ymin,ymax; 02230 double dxinc=0,dyinc=0; 02231 Rect r; 02232 long quickswap=FALSE; 02233 long widfactor; 02234 02235 if (x&&gp) { 02236 pmh = GetGWorldPixMap(gp); 02237 if (!pmh) { 02238 goto pakka; 02239 } 02240 LockPixels(pmh); 02241 savelock = jit_matrix_lock(x,1); 02242 02243 dstaddress = x->data; 02244 srcaddress = (uchar *)GetPixBaseAddr(pmh); 02245 if ((!srcaddress)||(!dstaddress)) { 02246 UnlockPixels(pmh); 02247 jit_matrix_lock(x,savelock); 02248 goto pakka; 02249 } 02250 dstwidth = x->info.dim[0]; 02251 dstheight = x->info.dim[1]; 02252 GetPortBounds(gp,&r); 02253 if ((**pmh).pixelSize == 16) // uyvy 02254 widfactor = 1L; 02255 else 02256 widfactor = 0L; 02257 srcwidth = (r.right-r.left) >> widfactor; 02258 srcheight = (r.bottom-r.top); 02259 dstcellstride = x->info.dimstride[0]; 02260 dstrowstride = x->info.dimstride[1]; 02261 srcrowstride = GetPixRowBytes(pmh); 02262 02263 if (gcinfo) { 02264 flags = gcinfo->flags; 02265 pmap0 = CLAMP(gcinfo->planemap[0] % x->info.planecount,0,3); 02266 pmap1 = CLAMP(gcinfo->planemap[1] % x->info.planecount,0,3); 02267 pmap2 = CLAMP(gcinfo->planemap[2] % x->info.planecount,0,3); 02268 pmap3 = CLAMP(gcinfo->planemap[3] % x->info.planecount,0,3); 02269 if (flags&JIT_MATRIX_CONVERT_DSTDIM) { 02270 if (gcinfo->dstrect.top<0) gcinfo->dstrect.top = 0; 02271 else if (gcinfo->dstrect.top>=dstheight) gcinfo->dstrect.top = dstheight-1; 02272 if (gcinfo->dstrect.bottom<0) gcinfo->dstrect.bottom = 0; 02273 else if (gcinfo->dstrect.bottom>=dstheight) gcinfo->dstrect.bottom = dstheight-1; 02274 if (gcinfo->dstrect.left<0) gcinfo->dstrect.left = 0; 02275 else if (gcinfo->dstrect.left>=dstwidth) gcinfo->dstrect.left = dstwidth-1; 02276 if (gcinfo->dstrect.right<0) gcinfo->dstrect.right = 0; 02277 else if (gcinfo->dstrect.right>=dstwidth) gcinfo->dstrect.right = dstwidth-1; 02278 dstheight = ABS(gcinfo->dstrect.bottom - gcinfo->dstrect.top) + 1; 02279 dstwidth = ABS(gcinfo->dstrect.right - gcinfo->dstrect.left) + 1; 02280 dstaddress += (dstcellstride*MIN(gcinfo->dstrect.left,gcinfo->dstrect.right)) + 02281 (dstrowstride*MIN(gcinfo->dstrect.top,gcinfo->dstrect.bottom)); 02282 } 02283 if (flags&JIT_MATRIX_CONVERT_SRCDIM) { 02284 if (gcinfo->srcrect.top<0) gcinfo->srcrect.top = 0; 02285 else if (gcinfo->srcrect.top>=srcheight) gcinfo->srcrect.top = srcheight-1; 02286 if (gcinfo->srcrect.bottom<0) gcinfo->srcrect.bottom = 0; 02287 else if (gcinfo->srcrect.bottom>=srcheight) gcinfo->srcrect.bottom = srcheight-1; 02288 if (gcinfo->srcrect.left<0) gcinfo->srcrect.left = 0; 02289 else if (gcinfo->srcrect.left>=srcwidth) gcinfo->srcrect.left = srcwidth-1; 02290 if (gcinfo->srcrect.right<0) gcinfo->srcrect.right = 0; 02291 else if (gcinfo->srcrect.right>=srcwidth) gcinfo->srcrect.right = srcwidth-1; 02292 srcheight = gcinfo->srcrect.bottom - gcinfo->srcrect.top; 02293 srcwidth = gcinfo->srcrect.right - gcinfo->srcrect.left; 02294 if (srcheight>=0) srcheight++; else srcheight--; 02295 if (srcwidth>=0) srcwidth++; else srcwidth--; 02296 srcaddress += (4*gcinfo->srcrect.left) + (srcrowstride*gcinfo->srcrect.top); 02297 } 02298 } else { 02299 pmap0 = 0; 02300 pmap1 = 1 % x->info.planecount; 02301 pmap2 = 2 % x->info.planecount; 02302 pmap3 = 3 % x->info.planecount; 02303 02304 } 02305 02306 if ((x->info.planecount==4) && 02307 (pmap0==3) && 02308 (pmap1==2) && 02309 (pmap2==1) && 02310 (pmap3==0)) 02311 { 02312 quickswap = TRUE; 02313 } 02314 02315 //calculate scale factor 02316 if (gcinfo&&(gcinfo->flags&JIT_MATRIX_CONVERT_INTERP)) { 02317 if ((ABS(srcwidth)>1)&&(ABS(dstwidth)>1)) 02318 dxinc = ((double)srcwidth-DIRECTION(srcwidth))/((double)dstwidth-1); 02319 if ((ABS(srcheight)>1)&&(ABS(dstheight)>1)) 02320 dyinc = ((double)srcheight-DIRECTION(srcheight))/((double)dstheight-1); 02321 } else { 02322 if ((ABS(srcwidth)>1)&&(ABS(dstwidth)>1)) 02323 dxinc = ((double)srcwidth)/((double)dstwidth); 02324 if ((ABS(srcheight)>1)&&(ABS(dstheight)>1)) 02325 dyinc = ((double)srcheight)/((double)dstheight); 02326 } 02327 02328 //compensate for potential FP error 02329 if (ABS(dxinc)<JIT_MATRIX_INC_THRESH) dxinc = 0; 02330 if (ABS(dyinc)<JIT_MATRIX_INC_THRESH) dyinc = 0; 02331 02332 xdir = DIRECTION(dxinc); 02333 ydir = DIRECTION(dyinc); 02334 02335 switch (xdir) 02336 { 02337 case 1: xmax = srcwidth-1; xmin = 0; break; 02338 case -1: xmin = srcwidth+1; xmax = 0; break; 02339 default: xmin = xmax = 0; break; 02340 } 02341 switch (ydir) 02342 { 02343 case 1: ymax = srcheight-1; ymin = 0; break; 02344 case -1: ymin = srcheight+1; ymax = 0; break; 02345 default: ymin = ymax = 0; break; 02346 } 02347 02348 //xidx,yidx should be the top left of the src rect(clip to zero) 02349 //xinc,yinc should be the ratio of the source vs. destination rects 02350 if (x->info.type==_jit_sym_char) { 02351 Fixed xidx=0,xinc=0,yidx=0,yinc=0; 02352 Fixed xfudge,yfudge; 02353 02354 xfudge = DoubleToFixed((xdir>=0)?JIT_MATRIX_FUDGE:1.-JIT_MATRIX_FUDGE); 02355 yfudge = DoubleToFixed((ydir>=0)?JIT_MATRIX_FUDGE:1.-JIT_MATRIX_FUDGE); 02356 02357 xinc = DoubleToFixed(dxinc); 02358 yinc = DoubleToFixed(dyinc); 02359 02360 if (flags&JIT_MATRIX_CONVERT_INTERP) { 02361 uchar *src,*src2,*dst,*x0,*x1,*x2,*x3; 02362 long xidx_int,xidx_int2,yidx_int,yidx_int2; 02363 Fixed c0,c1,c2,c3; 02364 Fixed xfrak,yfrak,xfrak_inv,yfrak_inv; 02365 02366 for(i=0;i<dstheight;i++) 02367 { 02368 yidx_int = FixedToInt(yidx); 02369 yidx_int2 = yidx_int+ydir; 02370 CLIP(yidx_int2,ymin,ymax); 02371 src = (uchar *)(srcaddress + (yidx_int * srcrowstride)); 02372 src2 = (uchar *)(srcaddress + (yidx_int2 * srcrowstride)); //this should never be past the end 02373 dst = (uchar *)(dstaddress + (i * dstrowstride)); 02374 02375 xidx = 0; 02376 yfrak = FixedFraction(yidx); 02377 if (ydir<0&&yfrak!=0) yfrak = fixed1-yfrak; //FixedFraction() always positive 02378 yfrak_inv = fixed1-yfrak; 02379 for(j=0;j<dstwidth;j++) 02380 { 02381 xidx_int = FixedToInt(xidx); 02382 xidx_int2 = xidx_int+xdir; 02383 CLIP(xidx_int2,xmin,xmax); 02384 xidx_int *= 4; 02385 xidx_int2 *= 4; 02386 xfrak = FixedFraction(xidx); 02387 if (xdir<0&&xfrak!=0) xfrak = fixed1-xfrak; //FixedFraction() always positive 02388 xfrak_inv = fixed1-xfrak; 02389 x0 = src + xidx_int; 02390 x1 = src + xidx_int2; 02391 x2 = src2 + xidx_int; 02392 x3 = src2 + xidx_int2; 02393 c0 = FixMul(xfrak_inv,yfrak_inv); 02394 c1 = FixMul(xfrak,yfrak_inv); 02395 c2 = FixMul(xfrak_inv,yfrak); 02396 c3 = FixMul(xfrak,yfrak); 02397 *(dst+pmap0)=(uchar)(((long)(*x0)*c0 + (long)(*x1)*c1 + (long)(*x2)*c2 + (long)(*x3)*c3)>>16L); 02398 *(dst+pmap1)=(uchar)(((long)(*++x0)*c0 + (long)(*++x1)*c1 + (long)(*++x2)*c2 + (long)(*++x3)*c3)>>16L); 02399 *(dst+pmap2)=(uchar)(((long)(*++x0)*c0 + (long)(*++x1)*c1 + (long)(*++x2)*c2 + (long)(*++x3)*c3)>>16L); 02400 *(dst+pmap3)=(uchar)(((long)(*++x0)*c0 + (long)(*++x1)*c1 + (long)(*++x2)*c2 + (long)(*++x3)*c3)>>16L); 02401 xidx+=xinc; 02402 dst+=dstcellstride; 02403 } 02404 yidx+=yinc; 02405 } 02406 02407 } else { 02408 long xidx_int,yidx_int; 02409 02410 yidx = yfudge; 02411 02412 if ((x->info.planecount==4)&&(quickswap||((pmap0==0)&&(pmap1==1)&&(pmap2==2)&&(pmap3==3)))) { 02413 long *src,*dst; 02414 //optimized cases 02415 if (xinc==fixed1) { 02416 for(i=0;i<dstheight;i++) 02417 { 02418 yidx_int = FixedToInt(yidx); 02419 CLIP(yidx_int,ymin,ymax); 02420 src = (long *)(srcaddress + (yidx_int*srcrowstride)); 02421 dst = (long *)(dstaddress + (i*dstrowstride)); 02422 02423 --dst; 02424 --src; 02425 if (quickswap) { 02426 for(j=0;j<dstwidth;j++) { 02427 FAST_INC(src); 02428 FAST_INC(dst); 02429 ((char *)dst)[0] = ((char *)src)[3]; 02430 ((char *)dst)[1] = ((char *)src)[2]; 02431 ((char *)dst)[2] = ((char *)src)[1]; 02432 ((char *)dst)[3] = ((char *)src)[0]; 02433 } 02434 } else { 02435 for(j=0;j<dstwidth;j++) 02436 { 02437 *++dst=*++src; 02438 } 02439 } 02440 yidx+=yinc; 02441 } 02442 } else { 02443 for(i=0;i<dstheight;i++) 02444 { 02445 yidx_int = FixedToInt(yidx); 02446 CLIP(yidx_int,ymin,ymax); 02447 src = (long *)(srcaddress + (yidx_int*srcrowstride)); 02448 dst = (long *)(dstaddress + (i*dstrowstride)); 02449 02450 xidx = xfudge; 02451 02452 //should only need clipping at boundaries 02453 xidx_int = FixedToInt(xidx); 02454 CLIP(xidx_int,xmin,xmax); 02455 *dst=*(src + xidx_int); 02456 xidx+=xinc; 02457 02458 if (quickswap) 02459 *dst = SWAP32(*dst); 02460 02461 dst++; 02462 02463 if (quickswap) { 02464 long tmp; 02465 for(j=2;j<dstwidth;j++) 02466 { 02467 tmp=*(src + FixedToInt(xidx)); 02468 *dst++ = SWAP32(tmp); 02469 xidx+=xinc; 02470 } 02471 } else { 02472 for(j=2;j<dstwidth;j++) 02473 { 02474 *dst++=*(src + FixedToInt(xidx)); 02475 xidx+=xinc; 02476 } 02477 } 02478 if (dstwidth>1) { 02479 xidx_int = FixedToInt(xidx); 02480 CLIP(xidx_int,xmin,xmax); 02481 *dst=*(src + xidx_int); 02482 if (quickswap) 02483 *dst = SWAP32(*dst); 02484 } 02485 02486 yidx+=yinc; 02487 } 02488 } 02489 } else { 02490 uchar *src0,*src,*dst; 02491 02492 for(i=0;i<dstheight;i++) 02493 { 02494 yidx_int = FixedToInt(yidx); 02495 CLIP(yidx_int,ymin,ymax); 02496 src0 = (uchar *)(srcaddress + (yidx_int*srcrowstride)); 02497 dst = (uchar *)(dstaddress + (i*dstrowstride)); 02498 02499 xidx = xfudge; 02500 for(j=0;j<dstwidth;j++) 02501 { 02502 xidx_int = FixedToInt(xidx); 02503 CLIP(xidx_int,xmin,xmax); 02504 src = src0 + (xidx_int*4); 02505 *(dst+pmap0)=*src; 02506 *(dst+pmap1)=*++src; 02507 *(dst+pmap2)=*++src; 02508 *(dst+pmap3)=*++src; 02509 xidx+=xinc; 02510 dst+=dstcellstride; 02511 } 02512 yidx+=yinc; 02513 } 02514 } 02515 } 02516 } else if (x->info.type==_jit_sym_long) { 02517 Fixed xidx=0,xinc=0,yidx=0,yinc=0; 02518 Fixed xfudge,yfudge; 02519 02520 xfudge = DoubleToFixed((xdir>=0)?JIT_MATRIX_FUDGE:1.-JIT_MATRIX_FUDGE); 02521 yfudge = DoubleToFixed((ydir>=0)?JIT_MATRIX_FUDGE:1.-JIT_MATRIX_FUDGE); 02522 02523 xinc = DoubleToFixed(dxinc); 02524 yinc = DoubleToFixed(dyinc); 02525 02526 dstcellstride /= 4; 02527 02528 if (flags&JIT_MATRIX_CONVERT_INTERP) { 02529 uchar *src,*src2; 02530 long *dst,*x0,*x1,*x2,*x3; 02531 long xidx_int,xidx_int2,yidx_int,yidx_int2; 02532 Fixed c0,c1,c2,c3; 02533 Fixed xfrak,yfrak,xfrak_inv,yfrak_inv; 02534 02535 for(i=0;i<dstheight;i++) 02536 { 02537 yidx_int = FixedToInt(yidx); 02538 yidx_int2 = yidx_int+ydir; 02539 CLIP(yidx_int2,ymin,ymax); 02540 src = (uchar *)(srcaddress + (yidx_int * srcrowstride)); 02541 src2 = (uchar *)(srcaddress + (yidx_int2 * srcrowstride)); //this should never be past the end 02542 dst = (long *)(dstaddress + (i * dstrowstride)); 02543 02544 xidx = 0; 02545 yfrak = FixedFraction(yidx); 02546 if (ydir<0&&yfrak!=0) yfrak = fixed1-yfrak; //FixedFraction() always positive 02547 yfrak_inv = fixed1-yfrak; 02548 for(j=0;j<dstwidth;j++) 02549 { 02550 xidx_int = FixedToInt(xidx); 02551 xidx_int2 = xidx_int+xdir; 02552 CLIP(xidx_int2,xmin,xmax); 02553 xidx_int *= 4; 02554 xidx_int2 *= 4; 02555 xfrak = FixedFraction(xidx); 02556 if (xdir<0&&xfrak!=0) xfrak = fixed1-xfrak; //FixedFraction() always positive 02557 xfrak_inv = fixed1-xfrak; 02558 x0 = (long *)(src + xidx_int); 02559 x1 = (long *)(src + xidx_int2); 02560 x2 = (long *)(src2 + xidx_int); 02561 x3 = (long *)(src2 + xidx_int2); 02562 c0 = FixMul(xfrak_inv,yfrak_inv); 02563 c1 = FixMul(xfrak,yfrak_inv); 02564 c2 = FixMul(xfrak_inv,yfrak); 02565 c3 = FixMul(xfrak,yfrak); 02566 *(dst+pmap0)=((long)(*x0)*c0 + (long)(*x1)*c1 + (long)(*x2)*c2 + (long)(*x3)*c3)>>16L; 02567 *(dst+pmap1)=((long)(*++x0)*c0 + (long)(*++x1)*c1 + (long)(*++x2)*c2 + (long)(*++x3)*c3)>>16L; 02568 *(dst+pmap2)=((long)(*++x0)*c0 + (long)(*++x1)*c1 + (long)(*++x2)*c2 + (long)(*++x3)*c3)>>16L; 02569 *(dst+pmap3)=((long)(*++x0)*c0 + (long)(*++x1)*c1 + (long)(*++x2)*c2 + (long)(*++x3)*c3)>>16L; 02570 xidx+=xinc; 02571 dst+=dstcellstride; 02572 } 02573 yidx+=yinc; 02574 } 02575 } else { 02576 long *dst; 02577 uchar *src0,*src; 02578 long xidx_int,yidx_int; 02579 02580 yidx = yfudge; 02581 02582 for(i=0;i<dstheight;i++) 02583 { 02584 yidx_int = FixedToInt(yidx); 02585 CLIP(yidx_int,ymin,ymax); 02586 src0 = (uchar *)(srcaddress + (yidx_int*srcrowstride)); 02587 dst = (long *)(dstaddress + (i*dstrowstride)); 02588 02589 xidx = xfudge; 02590 for(j=0;j<dstwidth;j++) 02591 { 02592 xidx_int = FixedToInt(xidx); 02593 CLIP(xidx_int,xmin,xmax); 02594 src = src0 + (xidx_int*4); 02595 *(dst+pmap0)=(long)(*src); 02596 *(dst+pmap1)=(long)(*++src); 02597 *(dst+pmap2)=(long)(*++src); 02598 *(dst+pmap3)=(long)(*++src); 02599 xidx+=xinc; 02600 dst+=dstcellstride; 02601 } 02602 yidx+=yinc; 02603 } 02604 } 02605 } else if (x->info.type==_jit_sym_float32) { 02606 dstcellstride /= 4; 02607 02608 if (flags&JIT_MATRIX_CONVERT_INTERP) { 02609 uchar *src,*src2; 02610 float *dst,*x0,*x1,*x2,*x3; 02611 long xidx_int,xidx_int2,yidx_int,yidx_int2; 02612 float c0,c1,c2,c3; 02613 float xfrak,yfrak,xfrak_inv,yfrak_inv; 02614 double xidx=0,xinc=0,yidx=0,yinc=0; 02615 02616 xinc = dxinc; 02617 yinc = dyinc; 02618 02619 for(i=0;i<dstheight;i++) 02620 { 02621 yidx_int = (long)yidx; 02622 yidx_int2 = yidx_int+ydir; 02623 CLIP(yidx_int2,ymin,ymax); 02624 src = (uchar *)(srcaddress + (yidx_int * srcrowstride)); 02625 src2 = (uchar *)(srcaddress + (yidx_int2 * srcrowstride)); //this should never be past the end 02626 dst = (float *)(dstaddress + (i * dstrowstride)); 02627 02628 xidx = 0; 02629 yfrak = yidx-((long)yidx); 02630 if (ydir<0) yfrak = -yfrak; //float frak is neg 02631 yfrak_inv = 1-yfrak; 02632 for(j=0;j<dstwidth;j++) 02633 { 02634 xidx_int = (long)xidx; 02635 xidx_int2 = xidx_int+xdir; 02636 CLIP(xidx_int2,xmin,xmax); 02637 xfrak = xidx-xidx_int; 02638 if (xdir<0) xfrak = -xfrak; //float frak is neg 02639 xfrak_inv = 1-xfrak; 02640 xidx_int *= 4; 02641 xidx_int2 *= 4; 02642 x0 = (float *)(src + xidx_int); 02643 x1 = (float *)(src + xidx_int2); 02644 x2 = (float *)(src2 + xidx_int); 02645 x3 = (float *)(src2 + xidx_int2); 02646 c0 = xfrak_inv*yfrak_inv; 02647 c1 = xfrak*yfrak_inv; 02648 c2 = xfrak_inv*yfrak; 02649 c3 = xfrak*yfrak; 02650 *(dst+pmap0)=((float)(*(x0))*c0 + (float)(*(x1))*c1 + (float)(*(x2))*c2 + (float)(*(x3))*c3)*(1./255.); 02651 *(dst+pmap1)=((float)(*(++x0))*c0 + (float)(*(++x1))*c1 + (float)(*(++x2))*c2 + (float)(*(++x3))*c3)*(1./255.); 02652 *(dst+pmap2)=((float)(*(++x0))*c0 + (float)(*(++x1))*c1 + (float)(*(++x2))*c2 + (float)(*(++x3))*c3)*(1./255.); 02653 *(dst+pmap3)=((float)(*(++x0))*c0 + (float)(*(++x1))*c1 + (float)(*(++x2))*c2 + (float)(*(++x3))*c3)*(1./255.); 02654 xidx+=xinc; 02655 dst+=dstcellstride; 02656 } 02657 yidx+=yinc; 02658 } 02659 } else { 02660 float *dst; 02661 uchar *src0,*src; 02662 Fixed xidx=0,xinc=0,yidx=0,yinc=0; 02663 Fixed xfudge,yfudge; 02664 long xidx_int,yidx_int; 02665 02666 xfudge = DoubleToFixed((xdir>=0)?JIT_MATRIX_FUDGE:1.-JIT_MATRIX_FUDGE); 02667 yfudge = DoubleToFixed((ydir>=0)?JIT_MATRIX_FUDGE:1.-JIT_MATRIX_FUDGE); 02668 02669 xinc = DoubleToFixed(dxinc); 02670 yinc = DoubleToFixed(dyinc); 02671 02672 yidx = yfudge; 02673 02674 for(i=0;i<dstheight;i++) 02675 { 02676 yidx_int = FixedToInt(yidx); 02677 CLIP(yidx_int,ymin,ymax); 02678 src0 = (uchar *)(srcaddress + (yidx_int*srcrowstride)); 02679 dst = (float *)(dstaddress + (i*dstrowstride)); 02680 02681 xidx = xfudge; 02682 for(j=0;j<dstwidth;j++) 02683 { 02684 xidx_int = FixedToInt(xidx); 02685 CLIP(xidx_int,xmin,xmax); 02686 src = src0 + (xidx_int*4); 02687 *(dst+pmap0)=(float)(*src)*(1./255.); 02688 *(dst+pmap1)=(float)(*++src)*(1./255.); 02689 *(dst+pmap2)=(float)(*++src)*(1./255.); 02690 *(dst+pmap3)=(float)(*++src)*(1./255.); 02691 xidx+=xinc; 02692 dst+=dstcellstride; 02693 } 02694 yidx+=yinc; 02695 } 02696 } 02697 } else if (x->info.type==_jit_sym_float64) { 02698 dstcellstride /= 8; 02699 02700 if (flags&JIT_MATRIX_CONVERT_INTERP) { 02701 uchar *src,*src2; 02702 double *dst,*x0,*x1,*x2,*x3; 02703 long xidx_int,xidx_int2,yidx_int,yidx_int2; 02704 double c0,c1,c2,c3; 02705 double xfrak,yfrak,xfrak_inv,yfrak_inv; 02706 double xidx=0,xinc=0,yidx=0,yinc=0; 02707 02708 xinc = dxinc; 02709 yinc = dyinc; 02710 02711 for(i=0;i<dstheight;i++) 02712 { 02713 yidx_int = (long)yidx; 02714 yidx_int2 = yidx_int+ydir; 02715 CLIP(yidx_int2,ymin,ymax); 02716 src = (uchar *)(srcaddress + (yidx_int * srcrowstride)); 02717 src2 = (uchar *)(srcaddress + (yidx_int2 * srcrowstride)); //this should never be past the end 02718 dst = (double *)(dstaddress + (i * dstrowstride)); 02719 02720 xidx = 0; 02721 yfrak = yidx-((long)yidx); 02722 if (ydir<0) yfrak = -yfrak; //float frak is neg 02723 yfrak_inv = 1-yfrak; 02724 for(j=0;j<dstwidth;j++) 02725 { 02726 xidx_int = (long)xidx; 02727 xidx_int2 = xidx_int+xdir; 02728 CLIP(xidx_int2,xmin,xmax); 02729 xfrak = xidx-xidx_int; 02730 if (xdir<0) xfrak = -xfrak; //float frak is neg 02731 xfrak_inv = 1-xfrak; 02732 xidx_int *= 4; 02733 xidx_int2 *= 4; 02734 x0 = (double *)(src + xidx_int); 02735 x1 = (double *)(src + xidx_int2); 02736 x2 = (double *)(src2 + xidx_int); 02737 x3 = (double *)(src2 + xidx_int2); 02738 c0 = xfrak_inv*yfrak_inv; 02739 c1 = xfrak*yfrak_inv; 02740 c2 = xfrak_inv*yfrak; 02741 c3 = xfrak*yfrak; 02742 *(dst+pmap0)=((double)(*(x0))*c0 + (double)(*(x1))*c1 + (double)(*(x2))*c2 + (double)(*(x3))*c3)*(1./255.); 02743 *(dst+pmap1)=((double)(*(++x0))*c0 + (double)(*(++x1))*c1 + (double)(*(++x2))*c2 + (double)(*(++x3))*c3)*(1./255.); 02744 *(dst+pmap2)=((double)(*(++x0))*c0 + (double)(*(++x1))*c1 + (double)(*(++x2))*c2 + (double)(*(++x3))*c3)*(1./255.); 02745 *(dst+pmap3)=((double)(*(++x0))*c0 + (double)(*(++x1))*c1 + (double)(*(++x2))*c2 + (double)(*(++x3))*c3)*(1./255.); 02746 xidx+=xinc; 02747 dst+=dstcellstride; 02748 } 02749 yidx+=yinc; 02750 } 02751 } else { 02752 double *dst; 02753 uchar *src0,*src; 02754 Fixed xidx=0,xinc=0,yidx=0,yinc=0; 02755 Fixed xfudge,yfudge; 02756 long xidx_int,yidx_int; 02757 02758 xfudge = DoubleToFixed((xdir>=0)?JIT_MATRIX_FUDGE:1.-JIT_MATRIX_FUDGE); 02759 yfudge = DoubleToFixed((ydir>=0)?JIT_MATRIX_FUDGE:1.-JIT_MATRIX_FUDGE); 02760 02761 xinc = DoubleToFixed(dxinc); 02762 yinc = DoubleToFixed(dyinc); 02763 02764 yidx = yfudge; 02765 02766 for(i=0;i<dstheight;i++) 02767 { 02768 yidx_int = FixedToInt(yidx); 02769 CLIP(yidx_int,ymin,ymax); 02770 src0 = (uchar *)(srcaddress + (yidx_int*srcrowstride)); 02771 dst = (double *)(dstaddress + (i*dstrowstride)); 02772 02773 xidx = xfudge; 02774 for(j=0;j<dstwidth;j++) 02775 { 02776 xidx_int = FixedToInt(xidx); 02777 CLIP(xidx_int,xmin,xmax); 02778 src = src0 + (xidx_int*4); 02779 *(dst+pmap0)=(double)(*src)*(1./255.); 02780 *(dst+pmap1)=(double)(*++src)*(1./255.); 02781 *(dst+pmap2)=(double)(*++src)*(1./255.); 02782 *(dst+pmap3)=(double)(*++src)*(1./255.); 02783 xidx+=xinc; 02784 dst+=dstcellstride; 02785 } 02786 yidx+=yinc; 02787 } 02788 } 02789 } 02790 02791 UnlockPixels(pmh); 02792 jit_matrix_lock(x,savelock); 02793 return JIT_ERR_NONE; 02794 } else { 02795 return JIT_ERR_INVALID_PTR; 02796 } 02797 02798 pakka: 02799 return JIT_ERR_GENERIC; 02800 } 02801 02802 /** 02803 * Copies Jitter matrix data from another matrix. 02804 * 02805 * @ingroup matrixmod 02806 * 02807 * @param dst_matrix destination t_jit_matrix object pointer 02808 * @param src_matrix destination t_jit_matrix object pointer 02809 * @param mcinfo conversion information pointer 02810 * 02811 * @return t_jit_err error code 02812 * 02813 * @warning This function is not exported, but is provided 02814 * for reference when calling via jit_object_method 02815 * on an intance of t_jit_matrix. 02816 */ 02817 t_jit_err jit_matrix_frommatrix(t_jit_matrix *dst_matrix, t_jit_matrix *src_matrix, t_matrix_conv_info *mcinfo) 02818 { 02819 t_jit_matrix_info dst_minfo,src_minfo; 02820 long dimsize[JIT_MATRIX_MAX_DIMCOUNT]; 02821 long i,dst_savelock,src_savelock; 02822 char *dst_data=NULL,*src_data=NULL; 02823 t_jit_err err=JIT_ERR_GENERIC; 02824 long dimcount; 02825 02826 if (dst_matrix&&src_matrix) { 02827 dst_savelock = (long)jit_object_method(dst_matrix,_jit_sym_lock,1); 02828 src_savelock = (long)jit_object_method(src_matrix,_jit_sym_lock,1); 02829 jit_object_method(dst_matrix,_jit_sym_getinfo,&dst_minfo); 02830 jit_object_method(src_matrix,_jit_sym_getinfo,&src_minfo); 02831 jit_object_method(dst_matrix,_jit_sym_getdata,&dst_data); 02832 jit_object_method(src_matrix,_jit_sym_getdata,&src_data); 02833 if (!dst_data) goto out; 02834 if (!src_data) goto out; 02835 if (mcinfo) { //make sure these values are in bounds 02836 if (mcinfo->flags&JIT_MATRIX_CONVERT_DSTDIM) { 02837 for (i=0;i<JIT_MATRIX_MAX_DIMCOUNT;i++) { 02838 if (mcinfo->dstdimstart[i]<0) mcinfo->dstdimstart[i] = 0; 02839 else if (mcinfo->dstdimstart[i]>=dst_minfo.dim[i]) mcinfo->dstdimstart[i] = dst_minfo.dim[i]-1; 02840 if (mcinfo->dstdimend[i]<0) mcinfo->dstdimend[i] = 0; 02841 else if (mcinfo->dstdimend[i]>=dst_minfo.dim[i]) mcinfo->dstdimend[i] = dst_minfo.dim[i]-1; 02842 } 02843 } 02844 if (mcinfo->flags&JIT_MATRIX_CONVERT_SRCDIM) { 02845 for (i=0;i<JIT_MATRIX_MAX_DIMCOUNT;i++) { 02846 if (mcinfo->srcdimstart[i]<0) mcinfo->srcdimstart[i] = 0; 02847 else if (mcinfo->srcdimstart[i]>=src_minfo.dim[i]) mcinfo->srcdimstart[i] = src_minfo.dim[i]-1; 02848 if (mcinfo->srcdimend[i]<0) mcinfo->srcdimend[i] = 0; 02849 else if (mcinfo->srcdimend[i]>=src_minfo.dim[i]) mcinfo->srcdimend[i] = src_minfo.dim[i]-1; 02850 } 02851 } 02852 } 02853 if (jit_matrix_canfastcopy(mcinfo, &dst_minfo, &src_minfo)) { 02854 jit_matrix_fastcopy(dst_minfo.size, dst_data, src_data); 02855 } else { 02856 dimcount = MAX(dst_minfo.dimcount,src_minfo.dimcount); 02857 jit_matrix_frommatrix_calculate_ndim(dimcount, mcinfo, &dst_minfo, dst_data, 02858 &src_minfo, src_data); 02859 } 02860 jit_object_method(src_matrix,_jit_sym_lock,src_savelock); 02861 jit_object_method(dst_matrix,_jit_sym_lock,dst_savelock); 02862 return JIT_ERR_NONE; 02863 } else { 02864 return JIT_ERR_INVALID_PTR; 02865 } 02866 out: 02867 return err; 02868 } 02869 02870 t_jit_err jit_matrix_frommatrix_trunc(t_jit_matrix *dst_matrix, t_jit_matrix *src_matrix) 02871 { 02872 t_jit_matrix_info dst_minfo,src_minfo; 02873 t_matrix_conv_info mcinfo; 02874 long i; 02875 02876 if (dst_matrix&&src_matrix) { 02877 //no need to lock since we are only grabbing info structs, not data pointer 02878 jit_object_method(dst_matrix,_jit_sym_getinfo,&dst_minfo); 02879 jit_object_method(src_matrix,_jit_sym_getinfo,&src_minfo); 02880 02881 mcinfo.flags = JIT_MATRIX_CONVERT_DSTDIM | JIT_MATRIX_CONVERT_SRCDIM; 02882 02883 for (i=0;i<JIT_MATRIX_MAX_DIMCOUNT;i++) { 02884 mcinfo.srcdimstart[i] = mcinfo.dstdimstart[i] = 0; 02885 mcinfo.srcdimend[i] = mcinfo.dstdimend[i] = 0; 02886 } 02887 02888 for (i=0;i<JIT_MATRIX_MAX_PLANECOUNT;i++) { 02889 mcinfo.planemap[i] = i; 02890 } 02891 02892 //use minimum dimensions for both srcrect + dstrect 02893 for (i=0;i<dst_minfo.dimcount;i++) { 02894 mcinfo.srcdimend[i] = mcinfo.dstdimend[i] = MIN(src_minfo.dim[i],src_minfo.dim[i])-1; 02895 } 02896 02897 return (t_jit_err) jit_object_method(dst_matrix,_jit_sym_frommatrix,src_matrix,&mcinfo); 02898 } else { 02899 return JIT_ERR_INVALID_PTR; 02900 } 02901 return JIT_ERR_GENERIC; 02902 } 02903 02904 void jit_matrix_frommatrix_calculate_ndim(long dim, t_matrix_conv_info *mcinfo, t_jit_matrix_info *dst_minfo, char *dst_bp, 02905 t_jit_matrix_info *src_minfo, char *src_bp) 02906 { 02907 long i,j,typesize; 02908 long dst_dimsize,src_dimsize; 02909 char *dst_p,*src_p; 02910 double src_inc; 02911 02912 if (dim<1) return; //safety 02913 02914 switch(dim) { 02915 case 1: 02916 //do we need to do anything special here? 02917 dst_minfo->dim[1] = 1; 02918 case 2: 02919 if (dst_minfo->type==_jit_sym_char) 02920 jit_matrix_frommatrix_2d_char(mcinfo,dst_minfo,dst_bp,src_minfo,src_bp); 02921 else if (dst_minfo->type==_jit_sym_long) 02922 jit_matrix_frommatrix_2d_long(mcinfo,dst_minfo,dst_bp,src_minfo,src_bp); 02923 else if (dst_minfo->type==_jit_sym_float32) 02924 jit_matrix_frommatrix_2d_float32(mcinfo,dst_minfo,dst_bp,src_minfo,src_bp); 02925 else if (dst_minfo->type==_jit_sym_float64) 02926 jit_matrix_frommatrix_2d_float64(mcinfo,dst_minfo,dst_bp,src_minfo,src_bp); 02927 break; 02928 default: 02929 i = dim-1; 02930 dst_dimsize = dst_minfo->dim[i]; 02931 src_dimsize = src_minfo->dim[i]; 02932 if (mcinfo) { 02933 //start/end points for this dimension 02934 if (mcinfo->flags&JIT_MATRIX_CONVERT_DSTDIM) { 02935 dst_dimsize = ABS(mcinfo->dstdimend[i] - mcinfo->dstdimstart[i]) + 1; 02936 dst_bp += (dst_minfo->dimstride[i]*MIN(mcinfo->dstdimstart[i],mcinfo->dstdimend[i])); 02937 } 02938 if (mcinfo->flags&JIT_MATRIX_CONVERT_SRCDIM) { 02939 src_dimsize = (mcinfo->srcdimend[i] - mcinfo->srcdimstart[i]); 02940 if (src_dimsize>=0) src_dimsize++; else src_dimsize--; 02941 src_bp += (src_minfo->dimstride[i]*mcinfo->srcdimstart[i]); 02942 } 02943 } 02944 if (src_dimsize&&dst_dimsize) 02945 src_inc = ((double)src_dimsize)/((double)dst_dimsize); 02946 else 02947 src_inc = 0; 02948 //no interpolation for dimensions > 2. 02949 for (j=0;j<dst_dimsize;j++) { 02950 dst_p = dst_bp + j * dst_minfo->dimstride[i]; 02951 src_p = src_bp + (long)((double)j*src_inc) * src_minfo->dimstride[i]; 02952 jit_matrix_frommatrix_calculate_ndim(dim-1,mcinfo,dst_minfo,dst_p,src_minfo,src_p); 02953 } 02954 } 02955 } 02956 02957 long jit_matrix_info_typesize(t_jit_matrix_info *minfo) 02958 { 02959 if (minfo->type==_jit_sym_char) return 1; 02960 if (minfo->type==_jit_sym_float64) return 8; 02961 else return 4; 02962 } 02963 02964 void jit_matrix_frommatrix_2d_char(t_matrix_conv_info *mcinfo, t_jit_matrix_info *dst_minfo, char *dst_bp, 02965 t_jit_matrix_info *src_minfo, char *src_bp) 02966 { 02967 long quickswap = FALSE; 02968 FM_PREAMBLE(); 02969 02970 if ((planecount==4) && (src_minfo->planecount==4) && 02971 (planemap[0]==3) && 02972 (planemap[1]==2) && 02973 (planemap[2]==1) && 02974 (planemap[3]==0) && 02975 (dst_cellstride==4) && 02976 (src_cellstride==4)) 02977 { 02978 quickswap = TRUE; 02979 } 02980 02981 if (src_minfo->type==_jit_sym_char) { 02982 if (bigmatrix||interp) 02983 { 02984 if (unity) { 02985 FM_COPY_UNITY_ALL(uchar,uchar,FM_CONVFN_CHAR); 02986 } else if (interp) { 02987 if (bigmatrix) { 02988 FM_COPY_INTERP_ALL_DOUBLE(uchar,uchar,FM_MULFN_DOUBLE,FM_CONVFN_CHAR); 02989 } else { 02990 FM_COPY_INTERP_ALL_FIXED(uchar,uchar,FM_MULFN_LONG,FM_CONVFN_CHARFIXTOCHAR); 02991 } 02992 } else { 02993 if (bigmatrix) { 02994 FM_COPY_ALL_DOUBLE(uchar,uchar,FM_CONVFN_CHAR); 02995 } else { 02996 FM_COPY_ALL_FIXED(uchar,uchar,FM_CONVFN_CHAR); 02997 } 02998 } 02999 } else { //leaving optimized cases for char for the time being, could revisit 03000 Fixed xidx=0,xinc=0,yidx=0,yinc=0; 03001 Fixed xfudge,yfudge; 03002 03003 xfudge = DoubleToFixed((xdir>=0)?JIT_MATRIX_FUDGE:1.-JIT_MATRIX_FUDGE); 03004 yfudge = DoubleToFixed((ydir>=0)?JIT_MATRIX_FUDGE:1.-JIT_MATRIX_FUDGE); 03005 03006 xinc = DoubleToFixed(dxinc); 03007 yinc = DoubleToFixed(dyinc); 03008 03009 yidx = yfudge; 03010 03011 if (quickswap||((planecount==4)&&(src_minfo->planecount==4)&& 03012 (planemap[0]==0)&&(planemap[1]==1)&&(planemap[2]==2)&&(planemap[3]==3))) 03013 { 03014 long *src,*dst,tmp; 03015 long xidx_int,yidx_int; 03016 long quad=dst_width/4; 03017 long rem=dst_width%4; 03018 03019 if ((dst_cellstride==4)&&(src_cellstride==4)) { 03020 //optimized cases 03021 if (xinc==fixed1) { 03022 for(i=0;i<dst_height;i++) { 03023 yidx_int = FixedToInt(yidx); 03024 CLIP(yidx_int,ymin,ymax); 03025 src = (long *)(src_bp + (yidx_int*src_rowstride)); 03026 dst = (long *)(dst_bp + (i*dst_rowstride)); 03027 03028 if (quickswap) { 03029 #ifdef JIT_LITTLE_ENDIAN 03030 for(j=0;j<quad;j++) { 03031 __asm { 03032 // load pointers 03033 MOV esi,ASM_DWORD_PTR src 03034 MOV edi,ASM_DWORD_PTR dst 03035 // move + swap one 32bit word, increment ptrs 03036 MOV eax,[esi] 03037 BSWAP eax 03038 MOV [edi],eax 03039 ADD esi,4 03040 ADD edi,4 03041 // move + swap one 32bit word, increment ptrs 03042 MOV eax,[esi] 03043 BSWAP eax 03044 MOV [edi],eax 03045 ADD esi,4 03046 ADD edi,4 03047 // move + swap one 32bit word, increment ptrs 03048 MOV eax,[esi] 03049 BSWAP eax 03050 MOV [edi],eax 03051 ADD esi,4 03052 ADD edi,4 03053 // move + swap one 32bit word, increment ptrs 03054 MOV eax,[esi] 03055 BSWAP eax 03056 MOV [edi],eax 03057 ADD esi,4 03058 ADD edi,4 03059 // write pointers 03060 MOV ASM_DWORD_PTR src,esi 03061 MOV ASM_DWORD_PTR dst,edi 03062 } 03063 } 03064 03065 for(j=0;j<rem;j++) { 03066 __asm { 03067 // load pointers 03068 MOV esi,ASM_DWORD_PTR src 03069 MOV edi,ASM_DWORD_PTR dst 03070 // move + swap one 32bit word, increment ptrs 03071 MOV eax,[esi] 03072 BSWAP eax 03073 MOV [edi],eax 03074 ADD esi,4 03075 ADD edi,4 03076 // write pointers 03077 MOV ASM_DWORD_PTR src,esi 03078 MOV ASM_DWORD_PTR dst,edi 03079 } 03080 } 03081 #else 03082 --dst; 03083 --src; 03084 for(j=0;j<quad;j++) { 03085 FAST_INC(src); 03086 FAST_INC(dst); 03087 ((char *)dst)[0] = ((char *)src)[3]; 03088 ((char *)dst)[1] = ((char *)src)[2]; 03089 ((char *)dst)[2] = ((char *)src)[1]; 03090 ((char *)dst)[3] = ((char *)src)[0]; 03091 FAST_INC(src); 03092 FAST_INC(dst); 03093 ((char *)dst)[0] = ((char *)src)[3]; 03094 ((char *)dst)[1] = ((char *)src)[2]; 03095 ((char *)dst)[2] = ((char *)src)[1]; 03096 ((char *)dst)[3] = ((char *)src)[0]; 03097 FAST_INC(src); 03098 FAST_INC(dst); 03099 ((char *)dst)[0] = ((char *)src)[3]; 03100 ((char *)dst)[1] = ((char *)src)[2]; 03101 ((char *)dst)[2] = ((char *)src)[1]; 03102 ((char *)dst)[3] = ((char *)src)[0]; 03103 FAST_INC(src); 03104 FAST_INC(dst); 03105 ((char *)dst)[0] = ((char *)src)[3]; 03106 ((char *)dst)[1] = ((char *)src)[2]; 03107 ((char *)dst)[2] = ((char *)src)[1]; 03108 ((char *)dst)[3] = ((char *)src)[0]; 03109 } 03110 for(j=0;j<rem;j++) { 03111 FAST_INC(src); 03112 FAST_INC(dst); 03113 ((char *)dst)[0] = ((char *)src)[3]; 03114 ((char *)dst)[1] = ((char *)src)[2]; 03115 ((char *)dst)[2] = ((char *)src)[1]; 03116 ((char *)dst)[3] = ((char *)src)[0]; 03117 } 03118 #endif 03119 } else { 03120 FAST_INC_SETUP(src); 03121 FAST_INC_SETUP(dst); 03122 for(j=0;j<quad;j++) { 03123 FAST_INC_DEREF(dst)=FAST_INC_DEREF(src); 03124 FAST_INC_DEREF(dst)=FAST_INC_DEREF(src); 03125 FAST_INC_DEREF(dst)=FAST_INC_DEREF(src); 03126 FAST_INC_DEREF(dst)=FAST_INC_DEREF(src); 03127 } 03128 for(j=0;j<rem;j++) { 03129 FAST_INC_DEREF(dst)=FAST_INC_DEREF(src); 03130 } 03131 } 03132 yidx+=yinc; 03133 } 03134 } else { 03135 for(i=0;i<dst_height;i++) { 03136 yidx_int = FixedToInt(yidx); 03137 CLIP(yidx_int,ymin,ymax); 03138 src = (long *)(src_bp + (yidx_int*src_rowstride)); 03139 dst = (long *)(dst_bp + (i*dst_rowstride)); 03140 03141 xidx = xfudge; 03142 03143 //should only need clipping at boundaries 03144 xidx_int = FixedToInt(xidx); 03145 CLIP(xidx_int,xmin,xmax); 03146 *dst=*(src + xidx_int); 03147 xidx+=xinc; 03148 03149 if (quickswap) 03150 *dst = SWAP32(*dst); 03151 03152 dst++; 03153 03154 if (quickswap) { 03155 long tmp; 03156 for(j=2;j<dst_width;j++) 03157 { 03158 tmp=*(src + FixedToInt(xidx)); 03159 *dst++ = SWAP32(tmp); 03160 xidx+=xinc; 03161 } 03162 } else { 03163 for(j=2;j<dst_width;j++) 03164 { 03165 *dst++=*(src + FixedToInt(xidx)); 03166 xidx+=xinc; 03167 } 03168 } 03169 03170 if (dst_width>1) { 03171 xidx_int = FixedToInt(xidx); 03172 CLIP(xidx_int,xmin,xmax); 03173 *dst=*(src + xidx_int); 03174 if (quickswap) 03175 *dst = SWAP32(*dst); 03176 } 03177 03178 yidx+=yinc; 03179 } 03180 } 03181 } else { 03182 dst_cellstride/=4; 03183 src_cellstride/=4; 03184 if (xinc==fixed1) { 03185 for(i=0;i<dst_height;i++) { 03186 yidx_int = FixedToInt(yidx); 03187 CLIP(yidx_int,ymin,ymax); 03188 src = (long *)(src_bp + (yidx_int*src_rowstride)); 03189 dst = (long *)(dst_bp + (i*dst_rowstride)); 03190 for(j=0;j<dst_width;j++) { 03191 *dst=*src; 03192 dst+=dst_cellstride; 03193 src+=src_cellstride; 03194 } 03195 yidx+=yinc; 03196 } 03197 } else { 03198 for(i=0;i<dst_height;i++) { 03199 yidx_int = FixedToInt(yidx); 03200 CLIP(yidx_int,ymin,ymax); 03201 src = (long *)(src_bp + (yidx_int*src_rowstride)); 03202 dst = (long *)(dst_bp + (i*dst_rowstride)); 03203 xidx = xfudge; 03204 for(j=0;j<dst_width;j++) { 03205 xidx_int = FixedToInt(xidx); 03206 CLIP(xidx_int,xmin,xmax); 03207 *dst=*(src + xidx_int*src_cellstride); 03208 dst+=dst_cellstride; 03209 xidx+=xinc; 03210 } 03211 yidx+=yinc; 03212 } 03213 } 03214 } 03215 } else { 03216 if (unity) { 03217 FM_COPY_UNITY_ALL(uchar,uchar,FM_CONVFN_CHAR); 03218 } else { 03219 FM_COPY_ALL_FIXED(uchar,uchar,FM_CONVFN_CHAR); 03220 } 03221 } 03222 } 03223 } else if (src_minfo->type==_jit_sym_long) { 03224 if (unity) { 03225 FM_COPY_UNITY_ALL(long,uchar,FM_CONVFN_CHAR); 03226 } else if (interp) { 03227 FM_COPY_INTERP_ALL_DOUBLE(long,uchar,FM_MULFN_DOUBLE,FM_CONVFN_LONGTOCHAR); 03228 } else { 03229 if (bigmatrix) { 03230 FM_COPY_ALL_DOUBLE(long,uchar,FM_CONVFN_LONGTOCHAR); 03231 } else { 03232 FM_COPY_ALL_FIXED(long,uchar,FM_CONVFN_LONGTOCHAR); 03233 } 03234 } 03235 } else if (src_minfo->type==_jit_sym_float32) { 03236 if (unity) { 03237 FM_COPY_UNITY_ALL(float,uchar,FM_CONVFN_FLOATTOCHAR); 03238 } else if (interp) { 03239 FM_COPY_INTERP_ALL_DOUBLE(float,uchar,FM_MULFN_DOUBLE,FM_CONVFN_FLOATTOCHAR); 03240 } else { 03241 if (bigmatrix) { 03242 FM_COPY_ALL_DOUBLE(float,uchar,FM_CONVFN_FLOATTOCHAR); 03243 } else { 03244 FM_COPY_ALL_FIXED(float,uchar,FM_CONVFN_FLOATTOCHAR); 03245 } 03246 } 03247 } else if (src_minfo->type==_jit_sym_float64) { 03248 if (unity) { 03249 FM_COPY_UNITY_ALL(double,uchar,FM_CONVFN_DOUBLETOCHAR); 03250 } else if (interp) { 03251 FM_COPY_INTERP_ALL_DOUBLE(double,uchar,FM_MULFN_DOUBLE,FM_CONVFN_DOUBLETOCHAR); 03252 } else { 03253 if (bigmatrix) { 03254 FM_COPY_ALL_DOUBLE(double,uchar,FM_CONVFN_DOUBLETOCHAR); 03255 } else { 03256 FM_COPY_ALL_FIXED(double,uchar,FM_CONVFN_DOUBLETOCHAR); 03257 } 03258 } 03259 } 03260 } 03261 03262 void jit_matrix_frommatrix_2d_long(t_matrix_conv_info *mcinfo, t_jit_matrix_info *dst_minfo, char *dst_bp, 03263 t_jit_matrix_info *src_minfo, char *src_bp) 03264 { 03265 FM_PREAMBLE(); 03266 03267 if (src_minfo->type==_jit_sym_char) { 03268 if (unity) { 03269 FM_COPY_UNITY_ALL(uchar,long,FM_CONVFN_LONG); 03270 } else if (interp) { 03271 if (bigmatrix) { 03272 FM_COPY_INTERP_ALL_DOUBLE(uchar,long,FM_MULFN_DOUBLE,FM_CONVFN_LONG); 03273 } else { 03274 FM_COPY_INTERP_ALL_FIXED(uchar,long,FM_MULFN_LONG,FM_CONVFN_CHARFIXTOLONG); 03275 } 03276 } else { 03277 if (bigmatrix) { 03278 FM_COPY_ALL_DOUBLE(uchar,long,FM_CONVFN_LONG); 03279 } else { 03280 FM_COPY_ALL_FIXED(uchar,long,FM_CONVFN_LONG); 03281 } 03282 } 03283 } else if (src_minfo->type==_jit_sym_long) { 03284 if (unity) { 03285 FM_COPY_UNITY_ALL(long,long,FM_CONVFN_LONG); 03286 } else if (interp) { 03287 FM_COPY_INTERP_ALL_DOUBLE(long,long,FM_MULFN_DOUBLE,FM_CONVFN_LONG); 03288 } else { 03289 if (bigmatrix) { 03290 FM_COPY_ALL_DOUBLE(long,long,FM_CONVFN_LONG); 03291 } else { 03292 FM_COPY_ALL_FIXED(long,long,FM_CONVFN_LONG); 03293 } 03294 } 03295 } else if (src_minfo->type==_jit_sym_float32) { 03296 if (unity) { 03297 FM_COPY_UNITY_ALL(float,long,FM_CONVFN_LONG); 03298 } else if (interp) { 03299 FM_COPY_INTERP_ALL_DOUBLE(float,long,FM_MULFN_DOUBLE,FM_CONVFN_LONG); 03300 } else { 03301 if (bigmatrix) { 03302 FM_COPY_ALL_DOUBLE(float,long,FM_CONVFN_LONG); 03303 } else { 03304 FM_COPY_ALL_FIXED(float,long,FM_CONVFN_LONG); 03305 } 03306 } 03307 } else if (src_minfo->type==_jit_sym_float64) { 03308 if (unity) { 03309 FM_COPY_UNITY_ALL(double,long,FM_CONVFN_LONG); 03310 } else if (interp) { 03311 FM_COPY_INTERP_ALL_DOUBLE(double,long,FM_MULFN_DOUBLE,FM_CONVFN_LONG); 03312 } else { 03313 if (bigmatrix) { 03314 FM_COPY_ALL_DOUBLE(double,long,FM_CONVFN_LONG); 03315 } else { 03316 FM_COPY_ALL_FIXED(double,long,FM_CONVFN_LONG); 03317 } 03318 } 03319 } 03320 } 03321 03322 void jit_matrix_frommatrix_2d_float32(t_matrix_conv_info *mcinfo, t_jit_matrix_info *dst_minfo, char *dst_bp, 03323 t_jit_matrix_info *src_minfo, char *src_bp) 03324 { 03325 FM_PREAMBLE(); 03326 03327 if (src_minfo->type==_jit_sym_char) { 03328 if (unity) { 03329 FM_COPY_UNITY_ALL(uchar,float,FM_CONVFN_CHARTOFLOAT); 03330 } else if (interp) { 03331 if (bigmatrix) { 03332 FM_COPY_INTERP_ALL_DOUBLE(uchar,float,FM_MULFN_DOUBLE,(double)FM_CONVFN_CHARTOFLOAT); 03333 } else { 03334 FM_COPY_INTERP_ALL_FIXED(uchar,float,FM_MULFN_LONG,FM_CONVFN_CHARFIXTOFLOAT); 03335 } 03336 } else { 03337 if (bigmatrix) { 03338 FM_COPY_ALL_DOUBLE(uchar,float,FM_CONVFN_CHARTOFLOAT); 03339 } else { 03340 FM_COPY_ALL_FIXED(uchar,float,FM_CONVFN_CHARTOFLOAT); 03341 } 03342 } 03343 } else if (src_minfo->type==_jit_sym_long) { 03344 if (unity) { 03345 FM_COPY_UNITY_ALL(long,float,FM_CONVFN_FLOAT); 03346 } else if (interp) { 03347 FM_COPY_INTERP_ALL_DOUBLE(long,float,FM_MULFN_DOUBLE,FM_CONVFN_FLOAT); 03348 } else { 03349 if (bigmatrix) { 03350 FM_COPY_ALL_DOUBLE(long,float,FM_CONVFN_FLOAT); 03351 } else { 03352 FM_COPY_ALL_FIXED(long,float,FM_CONVFN_FLOAT); 03353 } 03354 } 03355 } else if (src_minfo->type==_jit_sym_float32) { 03356 if (unity) { 03357 FM_COPY_UNITY_ALL(float,float,FM_CONVFN_FLOAT); 03358 } else if (interp) { 03359 FM_COPY_INTERP_ALL_DOUBLE(float,float,FM_MULFN_DOUBLE,FM_CONVFN_FLOAT); 03360 } else { 03361 if (bigmatrix) { 03362 FM_COPY_ALL_DOUBLE(float,float,FM_CONVFN_FLOAT); 03363 } else { 03364 FM_COPY_ALL_FIXED(float,float,FM_CONVFN_FLOAT); 03365 } 03366 } 03367 } else if (src_minfo->type==_jit_sym_float64) { 03368 if (unity) { 03369 FM_COPY_UNITY_ALL(double,float,FM_CONVFN_FLOAT); 03370 } else if (interp) { 03371 FM_COPY_INTERP_ALL_DOUBLE(double,float,FM_MULFN_DOUBLE,FM_CONVFN_FLOAT); 03372 } else { 03373 if (bigmatrix) { 03374 FM_COPY_ALL_DOUBLE(double,float,FM_CONVFN_FLOAT); 03375 } else { 03376 FM_COPY_ALL_FIXED(double,float,FM_CONVFN_FLOAT); 03377 } 03378 } 03379 } 03380 } 03381 03382 void jit_matrix_frommatrix_2d_float64(t_matrix_conv_info *mcinfo, t_jit_matrix_info *dst_minfo, char *dst_bp, 03383 t_jit_matrix_info *src_minfo, char *src_bp) 03384 { 03385 FM_PREAMBLE(); 03386 03387 if (src_minfo->type==_jit_sym_char) { 03388 if (unity) { 03389 FM_COPY_UNITY_ALL(uchar,double,FM_CONVFN_CHARTODOUBLE); 03390 } else if (interp) { 03391 if (bigmatrix) { 03392 FM_COPY_INTERP_ALL_DOUBLE(uchar,double,FM_MULFN_DOUBLE,FM_CONVFN_CHARTODOUBLE); 03393 } else { 03394 FM_COPY_INTERP_ALL_FIXED(uchar,double,FM_MULFN_LONG,FM_CONVFN_CHARFIXTODOUBLE); 03395 } 03396 } else { 03397 if (bigmatrix) { 03398 FM_COPY_ALL_DOUBLE(uchar,double,FM_CONVFN_CHARTODOUBLE); 03399 } else { 03400 FM_COPY_ALL_FIXED(uchar,double,FM_CONVFN_CHARTODOUBLE); 03401 } 03402 } 03403 } else if (src_minfo->type==_jit_sym_long) { 03404 if (unity) { 03405 FM_COPY_UNITY_ALL(long,double,FM_CONVFN_DOUBLE); 03406 } else if (interp) { 03407 FM_COPY_INTERP_ALL_DOUBLE(long,double,FM_MULFN_DOUBLE,FM_CONVFN_DOUBLE); 03408 } else { 03409 if (bigmatrix) { 03410 FM_COPY_ALL_DOUBLE(long,double,FM_CONVFN_DOUBLE); 03411 } else { 03412 FM_COPY_ALL_FIXED(long,double,FM_CONVFN_DOUBLE); 03413 } 03414 } 03415 } else if (src_minfo->type==_jit_sym_float32) { 03416 if (unity) { 03417 FM_COPY_UNITY_ALL(float,double,FM_CONVFN_DOUBLE); 03418 } else if (interp) { 03419 FM_COPY_INTERP_ALL_DOUBLE(float,double,FM_MULFN_DOUBLE,FM_CONVFN_DOUBLE); 03420 } else { 03421 if (bigmatrix) { 03422 FM_COPY_ALL_DOUBLE(float,double,FM_CONVFN_DOUBLE); 03423 } else { 03424 FM_COPY_ALL_FIXED(float,double,FM_CONVFN_DOUBLE); 03425 } 03426 } 03427 } else if (src_minfo->type==_jit_sym_float64) { 03428 if (unity) { 03429 FM_COPY_UNITY_ALL(double,double,FM_CONVFN_DOUBLE); 03430 } else if (interp) { 03431 FM_COPY_INTERP_ALL_DOUBLE(double,double,FM_MULFN_DOUBLE,FM_CONVFN_DOUBLE); 03432 } else { 03433 if (bigmatrix) { 03434 FM_COPY_ALL_DOUBLE(double,double,FM_CONVFN_DOUBLE); 03435 } else { 03436 FM_COPY_ALL_FIXED(double,double,FM_CONVFN_DOUBLE); 03437 } 03438 } 03439 } 03440 } 03441 03442 long jit_matrix_canfastcopy(t_matrix_conv_info *mcinfo, t_jit_matrix_info *dst_minfo, t_jit_matrix_info *src_minfo) 03443 { 03444 long i; 03445 //should also check word/vector alignment 03446 03447 if (dst_minfo->size!=src_minfo->size) return FALSE; 03448 if (dst_minfo->type!=src_minfo->type) return FALSE; 03449 if (dst_minfo->planecount!=src_minfo->planecount) return FALSE; 03450 if (dst_minfo->dimcount!=src_minfo->dimcount) return FALSE; 03451 for (i=0;i<dst_minfo->dimcount;i++) { 03452 if (dst_minfo->dim[i]!=src_minfo->dim[i]) return FALSE; 03453 if (dst_minfo->dimstride[i]!=src_minfo->dimstride[i]) return FALSE; 03454 } 03455 if (mcinfo) { 03456 if (mcinfo->flags&JIT_MATRIX_CONVERT_SRCDIM) { 03457 for (i=0;i<src_minfo->dimcount;i++) { 03458 if (mcinfo->srcdimstart[i]!=0) return FALSE; 03459 if (mcinfo->srcdimend[i]!=src_minfo->dim[i]) return FALSE; 03460 } 03461 } 03462 if (mcinfo->flags&JIT_MATRIX_CONVERT_DSTDIM) { 03463 for (i=0;i<dst_minfo->dimcount;i++) { 03464 if (mcinfo->dstdimstart[i]!=0) return FALSE; 03465 if (mcinfo->dstdimend[i]!=dst_minfo->dim[i]) return FALSE; 03466 } 03467 } 03468 for (i=0;i<dst_minfo->planecount;i++) { 03469 if (mcinfo->planemap[i]!=i) return FALSE; 03470 } 03471 } 03472 return TRUE; 03473 } 03474 03475 //this could be a problem for sub matrices of larger matrices...beware. 03476 t_jit_err jit_matrix_fastcopy(long size, void *dst, void *src) 03477 { 03478 if (dst==src) return JIT_ERR_NONE; //same pointer 03479 BlockMoveData(src,dst,size); //BlockMoveData appears to be ~15% faster than my code 03480 return JIT_ERR_NONE; 03481 /* 03482 long n; 03483 double *dst_lp,*src_lp; 03484 char *dst_cp,*src_cp; 03485 03486 if (dst==src) return JIT_ERR_NONE; //same pointer 03487 03488 if (_jit_altivec&&(!(((long)dst)%16))&&(!(((long)src)%16))&&(size>=256)) { 03489 jit_matrix_fastcopy_altivec(size, dst, src); 03490 } else { 03491 if (dst&&src) { 03492 n = (size/32)+1; 03493 dst_lp = (double *)(dst); 03494 src_lp = (double *)(src); 03495 while (--n) { 03496 dst_lp[0]=src_lp[0]; 03497 dst_lp[1]=src_lp[1]; 03498 dst_lp[2]=src_lp[2]; 03499 dst_lp[3]=src_lp[3]; 03500 dst_lp+=4;src_lp+=4; 03501 } 03502 n = (size%32)+1; 03503 dst_cp = ((char *)dst_lp)-1; 03504 src_cp = ((char *)src_lp)-1; 03505 while (--n) *++dst_cp=*++src_cp; 03506 03507 return JIT_ERR_NONE; 03508 } else { 03509 return JIT_ERR_INVALID_PTR; 03510 } 03511 } 03512 */ 03513 } 03514 03515 #if JIT_CAN_ALTIVEC 03516 //only call with vector aligned memory 03517 t_jit_err jit_matrix_fastcopy_altivec(long size, void *dst, void *src) 03518 { 03519 long m,n; 03520 vector unsigned char *dst_lp; 03521 vector unsigned char *src_lp; 03522 char *dst_cp,*src_cp; 03523 03524 if (dst&&src) { 03525 m = (((long)dst)%64)/16; //ensure that we only call __dcbz() on 64 byte boundaries 03526 size -= m*16; 03527 n = (size/64)+1; 03528 dst_lp = (vector unsigned char *)(dst); 03529 src_lp = (vector unsigned char *)(src); 03530 while (m--) { 03531 dst_lp[0]=src_lp[0]; 03532 dst_lp++;src_lp++; 03533 } 03534 while (--n) { 03535 __dcbz( dst_lp, 0 ); 03536 __dcbz( dst_lp, 32 ); 03537 03538 dst_lp[0]=src_lp[0]; 03539 dst_lp[1]=src_lp[1]; 03540 dst_lp[2]=src_lp[2]; 03541 dst_lp[3]=src_lp[3]; 03542 dst_lp+=4;src_lp+=4; 03543 } 03544 n = (size%64)+1; 03545 dst_cp = ((char *)dst_lp)-1; 03546 src_cp = ((char *)src_lp)-1; 03547 while (--n) *++dst_cp=*++src_cp; 03548 03549 return JIT_ERR_NONE; 03550 } else { 03551 return JIT_ERR_INVALID_PTR; 03552 } 03553 } 03554 #endif // JIT_CAN_ALTIVEC 03555 03556 long jit_matrix_lock(t_jit_matrix *x, long lock) 03557 { 03558 long rv=0; 03559 03560 if (x) { 03561 if (x->info.flags&JIT_MATRIX_DATA_HANDLE) { 03562 rv = jit_handle_lock(x->hdata,lock); 03563 if (lock) x->data = *(x->hdata); 03564 else x->data = NULL; 03565 } 03566 } 03567 return rv; 03568 } 03569 03570 // with 1 arguments <op> 03571 // with 2 arguments <op> <matrix/val(list)> 03572 // with 3 arguments <op> <matrix> <matrix/val(list)> 03573 03574 /** 03575 * Applies unary or binary operator to matrix 03576 * See Jitter user documentation for more information. 03577 * 03578 * @ingroup matrixmod 03579 * 03580 * @param x t_jit_matrix object pointer 03581 * @param s message symbol pointer 03582 * @param argc argument count 03583 * @param argv argument vector 03584 * 03585 * @return t_jit_err error code 03586 * 03587 * @warning This function is not exported, but is provided 03588 * for reference when calling via jit_object_method 03589 * on an intance of t_jit_matrix. 03590 */ 03591 t_jit_err jit_matrix_op(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv) 03592 { 03593 t_jit_err err=JIT_ERR_GENERIC; 03594 t_symbol *opsym=_jit_sym_nothing; 03595 t_jit_object *o; 03596 t_jit_linklist *list; 03597 t_jit_matrix *m1=NULL,*m2=NULL; 03598 t_jit_matrix_info info; 03599 long useval=0,i; 03600 t_jit_op_fn_object *fnobj; 03601 long unary=0; 03602 03603 opsym=jit_atom_getsym(argv); 03604 o = (t_jit_object *)jit_object_new(ps_jit_op); 03605 list = jit_linklist_new(); 03606 if (o&&list) { 03607 jit_attr_setsym(o,ps_op,opsym); 03608 if (fnobj=jit_op_fn_lookup(opsym)) { 03609 unary = (fnobj->argcount==1); 03610 } else { 03611 jit_object_error((t_object *)x,"jit_op: no operator %s",opsym->s_name); 03612 } 03613 03614 // determine behavior based on arguments 03615 if (argc==1) { 03616 // no args, use target as both operands and output 03617 m1 = x; 03618 m2 = x; 03619 } else { 03620 // look for numerical "value" args and create a temproary matrix for if present 03621 for (i=1;i<argc;i++) { 03622 if ((argv[i].a_type==A_FLOAT)||(argv[i].a_type==A_LONG)) { 03623 useval = i; 03624 break; 03625 } 03626 } 03627 if (useval&&useval<=2) { // values are always righthand operand 03628 if (useval==2) { 03629 // extra matrix arg, use as one operand 03630 if (argv[1].a_type==A_SYM) { 03631 m1 = jit_object_findregistered(jit_atom_getsym(argv+1)); 03632 } else if (argv[1].a_type==A_OBJ) { 03633 m1 = (t_jit_matrix *)argv[1].a_w.w_obj; 03634 } 03635 } 03636 if (unary) { 03637 jit_matrix_getinfo(x,&info); 03638 m1 = jit_matrix_new(&info); 03639 jit_matrix_setall(m1,NULL,argc-useval,argv+useval); 03640 m2 = x; 03641 } else { 03642 if (!m1) { 03643 // no extra matrix arg, use target as one operand and output 03644 m1 = x; 03645 } 03646 jit_matrix_getinfo(m1,&info); 03647 m2 = jit_matrix_new(&info); 03648 jit_matrix_setall(m2,NULL,argc-useval,argv+useval); 03649 } 03650 } else { 03651 useval = 0; 03652 if (argc==2) { 03653 // one extra matrix arg use target as one operand and output 03654 m1 = x; 03655 if (argv[1].a_type==A_SYM) { 03656 m2 = jit_object_findregistered(jit_atom_getsym(argv+1)); 03657 } else if (argv[1].a_type==A_OBJ) { 03658 m2 = (t_jit_matrix *)argv[1].a_w.w_obj; 03659 } 03660 if (unary) { 03661 m1 = m2; 03662 m2 = x; 03663 } 03664 } 03665 if (argc>=3) { 03666 // two extra matrix args, use each arg as one operand and target as output 03667 if (argv[1].a_type==A_SYM) { 03668 m1 = jit_object_findregistered(jit_atom_getsym(argv+1)); 03669 } else if (argv[1].a_type==A_OBJ) { 03670 m1 = (t_jit_matrix *)argv[1].a_w.w_obj; 03671 } 03672 if (argv[2].a_type==A_SYM) { 03673 m2 = jit_object_findregistered(jit_atom_getsym(argv+2)); 03674 } else if (argv[2].a_type==A_OBJ) { 03675 m2 = (t_jit_matrix *)argv[2].a_w.w_obj; 03676 } 03677 } 03678 } 03679 // avoid errors if NULL object passed in (instead use zero matrix?) 03680 if (m1==NULL) 03681 m1 = x; 03682 if (m2==NULL) 03683 m2 = x; 03684 } 03685 if (m1&&m2&&jit_object_method(m1,_jit_sym_class_jit_matrix)&& 03686 jit_object_method(m2,_jit_sym_class_jit_matrix)) 03687 { 03688 // do we want to deal with resampling/type conversion somehow? 03689 //could use additional temproary matrices if desired 03690 jit_linklist_append(list,m1); 03691 jit_linklist_append(list,m2); 03692 err = (t_jit_err)jit_object_method(o,_jit_sym_matrix_calc,list,x); 03693 } 03694 jit_object_free(o); 03695 jit_linklist_chuck(list); 03696 if (useval) { 03697 if (unary) 03698 jit_object_free(m1); 03699 else 03700 jit_object_free(m2); 03701 } 03702 //if (m3&&(m3!=x)) 03703 // jit_object_free(m3); 03704 } 03705 return err; 03706 } 03707 03708 /** 03709 * Fills cells according to the jit.expr expression provided. 03710 * See Jitter user documentation for more information. 03711 * 03712 * @ingroup matrixmod 03713 * 03714 * @param x t_jit_matrix object pointer 03715 * @param s message symbol pointer 03716 * @param argc argument count 03717 * @param argv argument vector 03718 * 03719 * @return t_jit_err error code 03720 * 03721 * @warning This function is not exported, but is provided 03722 * for reference when calling via jit_object_method 03723 * on an intance of t_jit_matrix. 03724 */ 03725 t_jit_err jit_matrix_exprfill(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv) 03726 { 03727 t_jit_err err=JIT_ERR_GENERIC; 03728 t_symbol *exprsym=_jit_sym_nothing; 03729 t_jit_object *o; 03730 t_jit_matrix *m=NULL; 03731 t_jit_matrix_info info; 03732 t_matrix_conv_info convinfo; 03733 long i,plane; 03734 03735 if (!argc||!argv) 03736 return JIT_ERR_GENERIC; 03737 03738 convinfo.flags = 0; 03739 if (argv->a_type!=A_SYM) { 03740 plane = jit_atom_getlong(argv); 03741 for (i=0;i<JIT_MATRIX_MAX_PLANECOUNT;i++) 03742 convinfo.planemap[i]= plane==i?0:-1; 03743 argv++;argc--; 03744 } else { 03745 for (i=0;i<JIT_MATRIX_MAX_PLANECOUNT;i++) 03746 convinfo.planemap[i]=0; 03747 } 03748 if ((argc>0)&&argv) { 03749 exprsym=jit_atom_getsym(argv); 03750 o = (t_jit_object *)jit_object_new(ps_jit_expr); 03751 if (o) { 03752 jit_attr_setsym(o,ps_expr,exprsym); 03753 jit_matrix_getinfo(x,&info); 03754 info.type = _jit_sym_float32; 03755 info.planecount = 1; 03756 m = jit_matrix_new(&info); 03757 if (m) { 03758 err = (t_jit_err)jit_object_method(o,_jit_sym_matrix_calc,x,m); 03759 jit_object_method(x,_jit_sym_frommatrix,m,&convinfo); 03760 jit_object_free(m); 03761 } 03762 jit_object_free(o); 03763 } 03764 } 03765 return err; 03766 } 03767 03768 /** 03769 * Copies texture information to matrix. 03770 * See Jitter user documentation for more information. 03771 * 03772 * @ingroup matrixmod 03773 * 03774 * @param x t_jit_matrix object pointer 03775 * @param s message symbol pointer 03776 * @param argc argument count 03777 * @param argv argument vector 03778 * 03779 * @return t_jit_err error code 03780 * 03781 * @warning This function is not exported, but is provided 03782 * for reference when calling via jit_object_method 03783 * on an intance of t_jit_matrix. 03784 */ 03785 t_jit_err jit_matrix_jit_gl_texture(t_jit_matrix *x, t_symbol *s, long argc, t_atom *argv) 03786 { 03787 t_jit_err err=JIT_ERR_GENERIC; 03788 t_symbol *texturesym=_jit_sym_nothing; 03789 t_jit_object *o; 03790 t_atom a; 03791 03792 if (!argc||!argv) 03793 return JIT_ERR_GENERIC; 03794 03795 texturesym=jit_atom_getsym(argv); 03796 if(o=jit_object_findregistered(texturesym)) 03797 { 03798 jit_atom_setobj(&a,x); 03799 err = (t_jit_err)jit_object_method(o,ps_tomatrix,ps_tomatrix,1,&a); 03800 } 03801 03802 return err; 03803 }
Copyright © 2008, Cycling '74