| 
									
										
										
										
											2011-02-23 10:52:22 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  |  * $Id$ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** BEGIN GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							| 
									
										
										
										
											2010-02-12 13:34:04 +00:00
										 |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Contributor(s):  | 
					
						
							|  |  |  |  * - Blender Foundation, 2003-2009 | 
					
						
							|  |  |  |  * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-27 20:40:57 +00:00
										 |  |  | /** \file blender/blenkernel/intern/seqeffects.c
 | 
					
						
							|  |  |  |  *  \ingroup bke | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <math.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | #include "PIL_dynlib.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-21 15:59:08 +00:00
										 |  |  | #include "BLI_math.h" /* windows needs for M_PI */
 | 
					
						
							| 
									
										
										
										
											2011-01-07 18:36:47 +00:00
										 |  |  | #include "BLI_utildefines.h"
 | 
					
						
							| 
									
										
										
										
											2010-03-21 15:59:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | #include "DNA_scene_types.h"
 | 
					
						
							|  |  |  | #include "DNA_sequence_types.h"
 | 
					
						
							| 
									
										
										
										
											2009-11-14 14:58:19 +00:00
										 |  |  | #include "DNA_anim_types.h"
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-14 14:58:19 +00:00
										 |  |  | #include "BKE_fcurve.h"
 | 
					
						
							| 
									
										
										
										
											2010-08-13 14:23:44 +00:00
										 |  |  | #include "BKE_main.h"
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | #include "BKE_plugin_types.h"
 | 
					
						
							| 
									
										
										
										
											2009-12-13 14:56:45 +00:00
										 |  |  | #include "BKE_sequencer.h"
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | #include "BKE_texture.h"
 | 
					
						
							|  |  |  | #include "BKE_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "IMB_imbuf_types.h"
 | 
					
						
							|  |  |  | #include "IMB_imbuf.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-14 14:58:19 +00:00
										 |  |  | #include "RNA_access.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | /* **** XXX **** */ | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static void error(const char *UNUSED(error), ...) {} | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define INT	96
 | 
					
						
							|  |  |  | #define FLO	128
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* **** XXX **** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Glow effect */ | 
					
						
							|  |  |  | enum { | 
					
						
							|  |  |  | 	GlowR=0, | 
					
						
							|  |  |  | 	GlowG=1, | 
					
						
							|  |  |  | 	GlowB=2, | 
					
						
							|  |  |  | 	GlowA=3 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | static struct ImBuf * prepare_effect_imbufs( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	SeqRenderData context, | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	struct ImBuf *ibuf1, struct ImBuf *ibuf2, | 
					
						
							|  |  |  | 	struct ImBuf *ibuf3) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ImBuf * out; | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	int x = context.rectx; | 
					
						
							|  |  |  | 	int y = context.recty; | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!ibuf1 && !ibuf2 && !ibuf3) { | 
					
						
							|  |  |  | 		/* hmmm, global float option ? */ | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | 		out = IMB_allocImBuf((short)x, (short)y, 32, IB_rect); | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	} else if ((ibuf1 && ibuf1->rect_float) ||  | 
					
						
							|  |  |  | 		   (ibuf2 && ibuf2->rect_float) ||  | 
					
						
							|  |  |  | 		   (ibuf3 && ibuf3->rect_float)) { | 
					
						
							|  |  |  | 		/* if any inputs are rectfloat, output is float too */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | 		out = IMB_allocImBuf((short)x, (short)y, 32, IB_rectfloat); | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | 		out = IMB_allocImBuf((short)x, (short)y, 32, IB_rect); | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (ibuf1 && !ibuf1->rect_float && out->rect_float) { | 
					
						
							|  |  |  | 		IMB_float_from_rect_simple(ibuf1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (ibuf2 && !ibuf2->rect_float && out->rect_float) { | 
					
						
							|  |  |  | 		IMB_float_from_rect_simple(ibuf2); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (ibuf3 && !ibuf3->rect_float && out->rect_float) { | 
					
						
							|  |  |  | 		IMB_float_from_rect_simple(ibuf3); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (ibuf1 && !ibuf1->rect && !out->rect_float) { | 
					
						
							|  |  |  | 		IMB_rect_from_float(ibuf1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (ibuf2 && !ibuf2->rect && !out->rect_float) { | 
					
						
							|  |  |  | 		IMB_rect_from_float(ibuf2); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (ibuf3 && !ibuf3->rect && !out->rect_float) { | 
					
						
							|  |  |  | 		IMB_rect_from_float(ibuf3); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 	return out; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* **********************************************************************
 | 
					
						
							|  |  |  |    PLUGINS | 
					
						
							|  |  |  |    ********************************************************************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void open_plugin_seq(PluginSeq *pis, const char *seqname) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-03 12:30:59 +00:00
										 |  |  | 	int (*version)(void); | 
					
						
							|  |  |  | 	void* (*alloc_private)(void); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	char *cp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* to be sure: (is tested for) */ | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 	pis->doit= NULL; | 
					
						
							|  |  |  | 	pis->pname= NULL; | 
					
						
							|  |  |  | 	pis->varstr= NULL; | 
					
						
							|  |  |  | 	pis->cfra= NULL; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	pis->version= 0; | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 	pis->instance_private_data = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* clear the error list */ | 
					
						
							|  |  |  | 	PIL_dynlib_get_error_as_string(NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* if(pis->handle) PIL_dynlib_close(pis->handle); */ | 
					
						
							|  |  |  | 	/* pis->handle= 0; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* open the needed object */ | 
					
						
							|  |  |  | 	pis->handle= PIL_dynlib_open(pis->name); | 
					
						
							|  |  |  | 	if(test_dlerr(pis->name, pis->name)) return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 	if (pis->handle != NULL) { | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 		/* find the address of the version function */ | 
					
						
							| 
									
										
										
										
											2010-12-03 12:30:59 +00:00
										 |  |  | 		version= (int (*)(void))PIL_dynlib_find_symbol(pis->handle, "plugin_seq_getversion"); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 		if (test_dlerr(pis->name, "plugin_seq_getversion")) return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 		if (version != NULL) { | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			pis->version= version(); | 
					
						
							|  |  |  | 			if (pis->version >= 2 && pis->version <= 6) { | 
					
						
							|  |  |  | 				int (*info_func)(PluginInfo *); | 
					
						
							|  |  |  | 				PluginInfo *info= (PluginInfo*) MEM_mallocN(sizeof(PluginInfo), "plugin_info"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				info_func= (int (*)(PluginInfo *))PIL_dynlib_find_symbol(pis->handle, "plugin_getinfo"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if(info_func == NULL) error("No info func"); | 
					
						
							|  |  |  | 				else { | 
					
						
							|  |  |  | 					info_func(info); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					pis->pname= info->name; | 
					
						
							|  |  |  | 					pis->vars= info->nvars; | 
					
						
							|  |  |  | 					pis->cfra= info->cfra; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					pis->varstr= info->varstr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					pis->doit= (void(*)(void))info->seq_doit; | 
					
						
							|  |  |  | 					if (info->init) | 
					
						
							|  |  |  | 						info->init(); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				MEM_freeN(info); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				cp= PIL_dynlib_find_symbol(pis->handle, "seqname"); | 
					
						
							|  |  |  | 				if(cp) strncpy(cp, seqname, 21); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				printf ("Plugin returned unrecognized version number\n"); | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-12-03 12:30:59 +00:00
										 |  |  | 		alloc_private = (void* (*)(void))PIL_dynlib_find_symbol( | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			pis->handle, "plugin_seq_alloc_private_data"); | 
					
						
							|  |  |  | 		if (alloc_private) { | 
					
						
							|  |  |  | 			pis->instance_private_data = alloc_private(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		pis->current_private_data = (void**)  | 
					
						
							|  |  |  | 			PIL_dynlib_find_symbol( | 
					
						
							|  |  |  | 				pis->handle, "plugin_private_data"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PluginSeq *add_plugin_seq(const char *str, const char *seqname) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PluginSeq *pis; | 
					
						
							|  |  |  | 	VarStruct *varstr; | 
					
						
							|  |  |  | 	int a; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pis= MEM_callocN(sizeof(PluginSeq), "PluginSeq"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	strncpy(pis->name, str, FILE_MAXDIR+FILE_MAXFILE); | 
					
						
							|  |  |  | 	open_plugin_seq(pis, seqname); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 	if(pis->doit==NULL) { | 
					
						
							|  |  |  | 		if(pis->handle==NULL) error("no plugin: %s", str); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 		else error("in plugin: %s", str); | 
					
						
							|  |  |  | 		MEM_freeN(pis); | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* default values */ | 
					
						
							|  |  |  | 	varstr= pis->varstr; | 
					
						
							|  |  |  | 	for(a=0; a<pis->vars; a++, varstr++) { | 
					
						
							|  |  |  | 		if( (varstr->type & FLO)==FLO) | 
					
						
							|  |  |  | 			pis->data[a]= varstr->def; | 
					
						
							|  |  |  | 		else if( (varstr->type & INT)==INT) | 
					
						
							|  |  |  | 			*((int *)(pis->data+a))= (int) varstr->def; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return pis; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void free_plugin_seq(PluginSeq *pis) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 	if(pis==NULL) return; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* no PIL_dynlib_close: same plugin can be opened multiple times with 1 handle */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (pis->instance_private_data) { | 
					
						
							|  |  |  | 		void (*free_private)(void *); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		free_private = (void (*)(void *))PIL_dynlib_find_symbol( | 
					
						
							|  |  |  | 			pis->handle, "plugin_seq_free_private_data"); | 
					
						
							|  |  |  | 		if (free_private) { | 
					
						
							|  |  |  | 			free_private(pis->instance_private_data); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	MEM_freeN(pis); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void init_plugin(Sequence * seq, const char * fname) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	seq->plugin= (PluginSeq *)add_plugin_seq(fname, seq->name+2); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* 
 | 
					
						
							|  |  |  |  * FIXME: should query plugin! Could be generator, that needs zero inputs... | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-12-03 12:30:59 +00:00
										 |  |  | static int num_inputs_plugin(void) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void load_plugin(Sequence * seq) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (seq) { | 
					
						
							|  |  |  | 		open_plugin_seq(seq->plugin, seq->name+2); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void copy_plugin(Sequence * dst, Sequence * src) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if(src->plugin) { | 
					
						
							|  |  |  | 		dst->plugin= MEM_dupallocN(src->plugin); | 
					
						
							|  |  |  | 		open_plugin_seq(dst->plugin, dst->name+2); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static ImBuf * IMB_cast_away_list(ImBuf * i) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!i) { | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return (ImBuf*) (((void**) i) + 2); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | static struct ImBuf * do_plugin_effect( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	SeqRenderData context, Sequence *seq, float cfra, | 
					
						
							|  |  |  | 	float facf0, float facf1, | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	struct ImBuf *ibuf1, struct ImBuf *ibuf2,  | 
					
						
							|  |  |  | 	struct ImBuf *ibuf3) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	char *cp; | 
					
						
							|  |  |  | 	int float_rendering; | 
					
						
							|  |  |  | 	int use_temp_bufs = 0; /* Are needed since blur.c (and maybe some other
 | 
					
						
							|  |  |  | 				  old plugins) do very bad stuff | 
					
						
							|  |  |  | 				  with imbuf-internals */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	struct ImBuf * out = prepare_effect_imbufs(context,ibuf1, ibuf2, ibuf3); | 
					
						
							|  |  |  | 	int x = context.rectx; | 
					
						
							|  |  |  | 	int y = context.recty; | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	if(seq->plugin && seq->plugin->doit) { | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if(seq->plugin->cfra)  | 
					
						
							|  |  |  | 			*(seq->plugin->cfra)= cfra; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		cp = PIL_dynlib_find_symbol( | 
					
						
							|  |  |  | 			seq->plugin->handle, "seqname"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(cp) strncpy(cp, seq->name+2, 22); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (seq->plugin->current_private_data) { | 
					
						
							|  |  |  | 			*seq->plugin->current_private_data  | 
					
						
							|  |  |  | 				= seq->plugin->instance_private_data; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		float_rendering = (out->rect_float != NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (seq->plugin->version<=3 && float_rendering) { | 
					
						
							|  |  |  | 			use_temp_bufs = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (ibuf1) { | 
					
						
							|  |  |  | 				ibuf1 = IMB_dupImBuf(ibuf1); | 
					
						
							|  |  |  | 				IMB_rect_from_float(ibuf1); | 
					
						
							|  |  |  | 				imb_freerectfloatImBuf(ibuf1); | 
					
						
							|  |  |  | 				ibuf1->flags &= ~IB_rectfloat; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (ibuf2) { | 
					
						
							|  |  |  | 				ibuf2 = IMB_dupImBuf(ibuf2); | 
					
						
							|  |  |  | 				IMB_rect_from_float(ibuf2); | 
					
						
							|  |  |  | 				imb_freerectfloatImBuf(ibuf2); | 
					
						
							|  |  |  | 				ibuf2->flags &= ~IB_rectfloat; | 
					
						
							|  |  |  | 			}  | 
					
						
							|  |  |  | 			if (ibuf3) { | 
					
						
							|  |  |  | 				ibuf3 = IMB_dupImBuf(ibuf3); | 
					
						
							|  |  |  | 				IMB_rect_from_float(ibuf3); | 
					
						
							|  |  |  | 				imb_freerectfloatImBuf(ibuf3); | 
					
						
							|  |  |  | 				ibuf3->flags &= ~IB_rectfloat; | 
					
						
							|  |  |  | 			}  | 
					
						
							|  |  |  | 			if (!out->rect) imb_addrectImBuf(out); | 
					
						
							|  |  |  | 			imb_freerectfloatImBuf(out); | 
					
						
							|  |  |  | 			out->flags &= ~IB_rectfloat; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (seq->plugin->version<=2) { | 
					
						
							|  |  |  | 			if(ibuf1) IMB_convert_rgba_to_abgr(ibuf1); | 
					
						
							|  |  |  | 			if(ibuf2) IMB_convert_rgba_to_abgr(ibuf2); | 
					
						
							|  |  |  | 			if(ibuf3) IMB_convert_rgba_to_abgr(ibuf3); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (seq->plugin->version<=4) { | 
					
						
							|  |  |  | 			((SeqDoit)seq->plugin->doit)( | 
					
						
							|  |  |  | 				seq->plugin->data, facf0, facf1, x, y, | 
					
						
							|  |  |  | 				IMB_cast_away_list(ibuf1),  | 
					
						
							|  |  |  | 				IMB_cast_away_list(ibuf2),  | 
					
						
							|  |  |  | 				IMB_cast_away_list(out),  | 
					
						
							|  |  |  | 				IMB_cast_away_list(ibuf3)); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			((SeqDoit)seq->plugin->doit)( | 
					
						
							|  |  |  | 				seq->plugin->data, facf0, facf1, x, y, | 
					
						
							|  |  |  | 				ibuf1, ibuf2, out, ibuf3); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (seq->plugin->version<=2) { | 
					
						
							|  |  |  | 			if (!use_temp_bufs) { | 
					
						
							|  |  |  | 				if(ibuf1) IMB_convert_rgba_to_abgr(ibuf1); | 
					
						
							|  |  |  | 				if(ibuf2) IMB_convert_rgba_to_abgr(ibuf2); | 
					
						
							|  |  |  | 				if(ibuf3) IMB_convert_rgba_to_abgr(ibuf3); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			IMB_convert_rgba_to_abgr(out); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (seq->plugin->version<=3 && float_rendering) { | 
					
						
							| 
									
										
										
										
											2010-07-12 14:57:24 +00:00
										 |  |  | 			IMB_float_from_rect_simple(out); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (use_temp_bufs) { | 
					
						
							|  |  |  | 			if (ibuf1) IMB_freeImBuf(ibuf1); | 
					
						
							|  |  |  | 			if (ibuf2) IMB_freeImBuf(ibuf2); | 
					
						
							|  |  |  | 			if (ibuf3) IMB_freeImBuf(ibuf3); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	return out; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static int do_plugin_early_out(struct Sequence *UNUSED(seq), | 
					
						
							|  |  |  | 				   float UNUSED(facf0), float UNUSED(facf1)) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void free_plugin(struct Sequence * seq) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	free_plugin_seq(seq->plugin); | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 	seq->plugin = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* **********************************************************************
 | 
					
						
							|  |  |  |    ALPHA OVER | 
					
						
							|  |  |  |    ********************************************************************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void init_alpha_over_or_under(Sequence * seq) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Sequence * seq1 = seq->seq1; | 
					
						
							|  |  |  | 	Sequence * seq2 = seq->seq2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	seq->seq2= seq1; | 
					
						
							|  |  |  | 	seq->seq1= seq2; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y,  | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 					 char * rect1, char *rect2, char *out) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int fac2, mfac, fac, fac4; | 
					
						
							|  |  |  | 	int xo, tempc; | 
					
						
							|  |  |  | 	char *rt1, *rt2, *rt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	xo= x; | 
					
						
							|  |  |  | 	rt1= (char *)rect1; | 
					
						
							|  |  |  | 	rt2= (char *)rect2; | 
					
						
							|  |  |  | 	rt= (char *)out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fac2= (int)(256.0*facf0); | 
					
						
							|  |  |  | 	fac4= (int)(256.0*facf1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(y--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* rt = rt1 over rt2  (alpha from rt1) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			fac= fac2; | 
					
						
							|  |  |  | 			mfac= 256 - ( (fac2*rt1[3])>>8 ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2); | 
					
						
							|  |  |  | 			else if(mfac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt1); | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				tempc= ( fac*rt1[0] + mfac*rt2[0])>>8; | 
					
						
							|  |  |  | 				if(tempc>255) rt[0]= 255; else rt[0]= tempc; | 
					
						
							|  |  |  | 				tempc= ( fac*rt1[1] + mfac*rt2[1])>>8; | 
					
						
							|  |  |  | 				if(tempc>255) rt[1]= 255; else rt[1]= tempc; | 
					
						
							|  |  |  | 				tempc= ( fac*rt1[2] + mfac*rt2[2])>>8; | 
					
						
							|  |  |  | 				if(tempc>255) rt[2]= 255; else rt[2]= tempc; | 
					
						
							|  |  |  | 				tempc= ( fac*rt1[3] + mfac*rt2[3])>>8; | 
					
						
							|  |  |  | 				if(tempc>255) rt[3]= 255; else rt[3]= tempc; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(y==0) break; | 
					
						
							|  |  |  | 		y--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			fac= fac4; | 
					
						
							|  |  |  | 			mfac= 256 - ( (fac4*rt1[3])>>8 ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2); | 
					
						
							|  |  |  | 			else if(mfac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt1); | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				tempc= ( fac*rt1[0] + mfac*rt2[0])>>8; | 
					
						
							|  |  |  | 				if(tempc>255) rt[0]= 255; else rt[0]= tempc; | 
					
						
							|  |  |  | 				tempc= ( fac*rt1[1] + mfac*rt2[1])>>8; | 
					
						
							|  |  |  | 				if(tempc>255) rt[1]= 255; else rt[1]= tempc; | 
					
						
							|  |  |  | 				tempc= ( fac*rt1[2] + mfac*rt2[2])>>8; | 
					
						
							|  |  |  | 				if(tempc>255) rt[2]= 255; else rt[2]= tempc; | 
					
						
							|  |  |  | 				tempc= ( fac*rt1[3] + mfac*rt2[3])>>8; | 
					
						
							|  |  |  | 				if(tempc>255) rt[3]= 255; else rt[3]= tempc; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void do_alphaover_effect_float(float facf0, float facf1, int x, int y,  | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 					  float * rect1, float *rect2, float *out) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float fac2, mfac, fac, fac4; | 
					
						
							|  |  |  | 	int xo; | 
					
						
							|  |  |  | 	float *rt1, *rt2, *rt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	xo= x; | 
					
						
							|  |  |  | 	rt1= rect1; | 
					
						
							|  |  |  | 	rt2= rect2; | 
					
						
							|  |  |  | 	rt= out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fac2= facf0; | 
					
						
							|  |  |  | 	fac4= facf1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(y--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* rt = rt1 over rt2  (alpha from rt1) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			fac= fac2; | 
					
						
							|  |  |  | 			mfac= 1.0 - (fac2*rt1[3]) ; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(fac <= 0.0) { | 
					
						
							|  |  |  | 				memcpy(rt, rt2, 4 * sizeof(float)); | 
					
						
							|  |  |  | 			} else if(mfac <=0) { | 
					
						
							|  |  |  | 				memcpy(rt, rt1, 4 * sizeof(float)); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				rt[0] = fac*rt1[0] + mfac*rt2[0]; | 
					
						
							|  |  |  | 				rt[1] = fac*rt1[1] + mfac*rt2[1]; | 
					
						
							|  |  |  | 				rt[2] = fac*rt1[2] + mfac*rt2[2]; | 
					
						
							|  |  |  | 				rt[3] = fac*rt1[3] + mfac*rt2[3]; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(y==0) break; | 
					
						
							|  |  |  | 		y--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			fac= fac4; | 
					
						
							|  |  |  | 			mfac= 1.0 - (fac4*rt1[3]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(fac <= 0.0) { | 
					
						
							|  |  |  | 				memcpy(rt, rt2, 4 * sizeof(float)); | 
					
						
							|  |  |  | 			} else if(mfac <= 0.0) { | 
					
						
							|  |  |  | 				memcpy(rt, rt1, 4 * sizeof(float)); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				rt[0] = fac*rt1[0] + mfac*rt2[0]; | 
					
						
							|  |  |  | 				rt[1] = fac*rt1[1] + mfac*rt2[1]; | 
					
						
							|  |  |  | 				rt[2] = fac*rt1[2] + mfac*rt2[2]; | 
					
						
							|  |  |  | 				rt[3] = fac*rt1[3] + mfac*rt2[3]; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | static struct ImBuf * do_alphaover_effect( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra), | 
					
						
							|  |  |  | 	float facf0, float facf1,  | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	struct ImBuf *ibuf1, struct ImBuf *ibuf2,  | 
					
						
							|  |  |  | 	struct ImBuf *ibuf3) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	struct ImBuf * out = prepare_effect_imbufs(context,ibuf1, ibuf2, ibuf3); | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	if (out->rect_float) { | 
					
						
							|  |  |  | 		do_alphaover_effect_float( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 			facf0, facf1, context.rectx, context.recty, | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			ibuf1->rect_float, ibuf2->rect_float, | 
					
						
							|  |  |  | 			out->rect_float); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		do_alphaover_effect_byte( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 			facf0, facf1, context.rectx, context.recty, | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			(char*) ibuf1->rect, (char*) ibuf2->rect, | 
					
						
							|  |  |  | 			(char*) out->rect); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	return out; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* **********************************************************************
 | 
					
						
							|  |  |  |    ALPHA UNDER | 
					
						
							|  |  |  |    ********************************************************************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | static void do_alphaunder_effect_byte( | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	float facf0, float facf1, int x, int y, char *rect1,  | 
					
						
							|  |  |  | 	char *rect2, char *out) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int fac2, mfac, fac, fac4; | 
					
						
							|  |  |  | 	int xo; | 
					
						
							|  |  |  | 	char *rt1, *rt2, *rt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	xo= x; | 
					
						
							|  |  |  | 	rt1= rect1; | 
					
						
							|  |  |  | 	rt2= rect2; | 
					
						
							|  |  |  | 	rt= out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fac2= (int)(256.0*facf0); | 
					
						
							|  |  |  | 	fac4= (int)(256.0*facf1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(y--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* rt = rt1 under rt2  (alpha from rt2) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* this complex optimalisation is because the
 | 
					
						
							|  |  |  | 			 * 'skybuf' can be crossed in | 
					
						
							|  |  |  | 			 */ | 
					
						
							|  |  |  | 			if(rt2[3]==0 && fac2==256) *( (unsigned int *)rt) = *( (unsigned int *)rt1); | 
					
						
							|  |  |  | 			else if(rt2[3]==255) *( (unsigned int *)rt) = *( (unsigned int *)rt2); | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				mfac= rt2[3]; | 
					
						
							|  |  |  | 				fac= (fac2*(256-mfac))>>8; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2); | 
					
						
							|  |  |  | 				else { | 
					
						
							|  |  |  | 					rt[0]= ( fac*rt1[0] + mfac*rt2[0])>>8; | 
					
						
							|  |  |  | 					rt[1]= ( fac*rt1[1] + mfac*rt2[1])>>8; | 
					
						
							|  |  |  | 					rt[2]= ( fac*rt1[2] + mfac*rt2[2])>>8; | 
					
						
							|  |  |  | 					rt[3]= ( fac*rt1[3] + mfac*rt2[3])>>8; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(y==0) break; | 
					
						
							|  |  |  | 		y--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(rt2[3]==0 && fac4==256) *( (unsigned int *)rt) = *( (unsigned int *)rt1); | 
					
						
							|  |  |  | 			else if(rt2[3]==255) *( (unsigned int *)rt) = *( (unsigned int *)rt2); | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				mfac= rt2[3]; | 
					
						
							|  |  |  | 				fac= (fac4*(256-mfac))>>8; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2); | 
					
						
							|  |  |  | 				else { | 
					
						
							|  |  |  | 					rt[0]= ( fac*rt1[0] + mfac*rt2[0])>>8; | 
					
						
							|  |  |  | 					rt[1]= ( fac*rt1[1] + mfac*rt2[1])>>8; | 
					
						
							|  |  |  | 					rt[2]= ( fac*rt1[2] + mfac*rt2[2])>>8; | 
					
						
							|  |  |  | 					rt[3]= ( fac*rt1[3] + mfac*rt2[3])>>8; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void do_alphaunder_effect_float(float facf0, float facf1, int x, int y,  | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 					   float *rect1, float *rect2,  | 
					
						
							|  |  |  | 					   float *out) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float fac2, mfac, fac, fac4; | 
					
						
							|  |  |  | 	int xo; | 
					
						
							|  |  |  | 	float *rt1, *rt2, *rt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	xo= x; | 
					
						
							|  |  |  | 	rt1= rect1; | 
					
						
							|  |  |  | 	rt2= rect2; | 
					
						
							|  |  |  | 	rt= out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fac2= facf0; | 
					
						
							|  |  |  | 	fac4= facf1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(y--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* rt = rt1 under rt2  (alpha from rt2) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* this complex optimalisation is because the
 | 
					
						
							|  |  |  | 			 * 'skybuf' can be crossed in | 
					
						
							|  |  |  | 			 */ | 
					
						
							|  |  |  | 			if( rt2[3]<=0 && fac2>=1.0) { | 
					
						
							|  |  |  | 				memcpy(rt, rt1, 4 * sizeof(float)); | 
					
						
							|  |  |  | 			} else if(rt2[3]>=1.0) { | 
					
						
							|  |  |  | 				memcpy(rt, rt2, 4 * sizeof(float)); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				mfac = rt2[3]; | 
					
						
							|  |  |  | 				fac = fac2 * (1.0 - mfac); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if(fac == 0) { | 
					
						
							|  |  |  | 					memcpy(rt, rt2, 4 * sizeof(float)); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					rt[0]= fac*rt1[0] + mfac*rt2[0]; | 
					
						
							|  |  |  | 					rt[1]= fac*rt1[1] + mfac*rt2[1]; | 
					
						
							|  |  |  | 					rt[2]= fac*rt1[2] + mfac*rt2[2]; | 
					
						
							|  |  |  | 					rt[3]= fac*rt1[3] + mfac*rt2[3]; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(y==0) break; | 
					
						
							|  |  |  | 		y--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(rt2[3]<=0 && fac4 >= 1.0) { | 
					
						
							|  |  |  | 				memcpy(rt, rt1, 4 * sizeof(float)); | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | 			} else if(rt2[3]>=1.0) { | 
					
						
							|  |  |  | 				memcpy(rt, rt2, 4 * sizeof(float)); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				mfac= rt2[3]; | 
					
						
							|  |  |  | 				fac= fac4*(1.0-mfac); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if(fac == 0) { | 
					
						
							|  |  |  | 					memcpy(rt, rt2, 4 * sizeof(float)); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					rt[0]= fac * rt1[0] + mfac * rt2[0]; | 
					
						
							|  |  |  | 					rt[1]= fac * rt1[1] + mfac * rt2[1]; | 
					
						
							|  |  |  | 					rt[2]= fac * rt1[2] + mfac * rt2[2]; | 
					
						
							|  |  |  | 					rt[3]= fac * rt1[3] + mfac * rt2[3]; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | static struct ImBuf* do_alphaunder_effect( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra), | 
					
						
							|  |  |  | 	float facf0, float facf1,  | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	struct ImBuf *ibuf1, struct ImBuf *ibuf2,  | 
					
						
							|  |  |  | 	struct ImBuf *ibuf3) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	struct ImBuf * out = prepare_effect_imbufs( | 
					
						
							|  |  |  | 		context, ibuf1, ibuf2, ibuf3); | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	if (out->rect_float) { | 
					
						
							|  |  |  | 		do_alphaunder_effect_float( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 			facf0, facf1, context.rectx, context.recty, | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			ibuf1->rect_float, ibuf2->rect_float, | 
					
						
							|  |  |  | 			out->rect_float); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		do_alphaunder_effect_byte( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 			facf0, facf1, context.rectx, context.recty, | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			(char*) ibuf1->rect, (char*) ibuf2->rect, | 
					
						
							|  |  |  | 			(char*) out->rect); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	return out; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* **********************************************************************
 | 
					
						
							|  |  |  |    CROSS | 
					
						
							|  |  |  |    ********************************************************************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | static void do_cross_effect_byte(float facf0, float facf1, int x, int y,  | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			  char *rect1, char *rect2,  | 
					
						
							|  |  |  | 			  char *out) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int fac1, fac2, fac3, fac4; | 
					
						
							|  |  |  | 	int xo; | 
					
						
							|  |  |  | 	char *rt1, *rt2, *rt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	xo= x; | 
					
						
							|  |  |  | 	rt1= rect1; | 
					
						
							|  |  |  | 	rt2= rect2; | 
					
						
							|  |  |  | 	rt= out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fac2= (int)(256.0*facf0); | 
					
						
							|  |  |  | 	fac1= 256-fac2; | 
					
						
							|  |  |  | 	fac4= (int)(256.0*facf1); | 
					
						
							|  |  |  | 	fac3= 256-fac4; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(y--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt[0]= (fac1*rt1[0] + fac2*rt2[0])>>8; | 
					
						
							|  |  |  | 			rt[1]= (fac1*rt1[1] + fac2*rt2[1])>>8; | 
					
						
							|  |  |  | 			rt[2]= (fac1*rt1[2] + fac2*rt2[2])>>8; | 
					
						
							|  |  |  | 			rt[3]= (fac1*rt1[3] + fac2*rt2[3])>>8; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(y==0) break; | 
					
						
							|  |  |  | 		y--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt[0]= (fac3*rt1[0] + fac4*rt2[0])>>8; | 
					
						
							|  |  |  | 			rt[1]= (fac3*rt1[1] + fac4*rt2[1])>>8; | 
					
						
							|  |  |  | 			rt[2]= (fac3*rt1[2] + fac4*rt2[2])>>8; | 
					
						
							|  |  |  | 			rt[3]= (fac3*rt1[3] + fac4*rt2[3])>>8; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | static void do_cross_effect_float(float facf0, float facf1, int x, int y,  | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			   float *rect1, float *rect2, float *out) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float fac1, fac2, fac3, fac4; | 
					
						
							|  |  |  | 	int xo; | 
					
						
							|  |  |  | 	float *rt1, *rt2, *rt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	xo= x; | 
					
						
							|  |  |  | 	rt1= rect1; | 
					
						
							|  |  |  | 	rt2= rect2; | 
					
						
							|  |  |  | 	rt= out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fac2= facf0; | 
					
						
							|  |  |  | 	fac1= 1.0 - fac2; | 
					
						
							|  |  |  | 	fac4= facf1; | 
					
						
							|  |  |  | 	fac3= 1.0 - fac4; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(y--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt[0]= fac1*rt1[0] + fac2*rt2[0]; | 
					
						
							|  |  |  | 			rt[1]= fac1*rt1[1] + fac2*rt2[1]; | 
					
						
							|  |  |  | 			rt[2]= fac1*rt1[2] + fac2*rt2[2]; | 
					
						
							|  |  |  | 			rt[3]= fac1*rt1[3] + fac2*rt2[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(y==0) break; | 
					
						
							|  |  |  | 		y--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt[0]= fac3*rt1[0] + fac4*rt2[0]; | 
					
						
							|  |  |  | 			rt[1]= fac3*rt1[1] + fac4*rt2[1]; | 
					
						
							|  |  |  | 			rt[2]= fac3*rt1[2] + fac4*rt2[2]; | 
					
						
							|  |  |  | 			rt[3]= fac3*rt1[3] + fac4*rt2[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* carefull: also used by speed effect! */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | static struct ImBuf* do_cross_effect( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra), | 
					
						
							|  |  |  | 	float facf0, float facf1,  | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	struct ImBuf *ibuf1, struct ImBuf *ibuf2,  | 
					
						
							|  |  |  | 	struct ImBuf *ibuf3) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	struct ImBuf * out = prepare_effect_imbufs( | 
					
						
							|  |  |  | 		context, ibuf1, ibuf2, ibuf3); | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	if (out->rect_float) { | 
					
						
							|  |  |  | 		do_cross_effect_float( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 			facf0, facf1, context.rectx, context.recty, | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			ibuf1->rect_float, ibuf2->rect_float, | 
					
						
							|  |  |  | 			out->rect_float); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		do_cross_effect_byte( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 			facf0, facf1, context.rectx, context.recty, | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			(char*) ibuf1->rect, (char*) ibuf2->rect, | 
					
						
							|  |  |  | 			(char*) out->rect); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	return out; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* **********************************************************************
 | 
					
						
							|  |  |  |    GAMMA CROSS | 
					
						
							|  |  |  |    ********************************************************************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* copied code from initrender.c */ | 
					
						
							|  |  |  | static unsigned short gamtab[65536]; | 
					
						
							|  |  |  | static unsigned short igamtab1[256]; | 
					
						
							|  |  |  | static int gamma_tabs_init = FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define RE_GAMMA_TABLE_SIZE 400
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static float gamma_range_table[RE_GAMMA_TABLE_SIZE + 1]; | 
					
						
							|  |  |  | static float gamfactor_table[RE_GAMMA_TABLE_SIZE]; | 
					
						
							|  |  |  | static float inv_gamma_range_table[RE_GAMMA_TABLE_SIZE + 1]; | 
					
						
							|  |  |  | static float inv_gamfactor_table[RE_GAMMA_TABLE_SIZE]; | 
					
						
							|  |  |  | static float color_domain_table[RE_GAMMA_TABLE_SIZE + 1];  | 
					
						
							|  |  |  | static float color_step; | 
					
						
							|  |  |  | static float inv_color_step; | 
					
						
							|  |  |  | static float valid_gamma; | 
					
						
							|  |  |  | static float valid_inv_gamma; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void makeGammaTables(float gamma) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* we need two tables: one forward, one backward */ | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	valid_gamma        = gamma; | 
					
						
							|  |  |  | 	valid_inv_gamma    = 1.0 / gamma; | 
					
						
							|  |  |  | 	color_step        = 1.0 / RE_GAMMA_TABLE_SIZE; | 
					
						
							|  |  |  | 	inv_color_step    = (float) RE_GAMMA_TABLE_SIZE;  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* We could squeeze out the two range tables to gain some memory.        */	 | 
					
						
							|  |  |  | 	for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++) { | 
					
						
							|  |  |  | 		color_domain_table[i]   = i * color_step; | 
					
						
							|  |  |  | 		gamma_range_table[i]     = pow(color_domain_table[i], | 
					
						
							|  |  |  | 										valid_gamma); | 
					
						
							|  |  |  | 		inv_gamma_range_table[i] = pow(color_domain_table[i], | 
					
						
							|  |  |  | 										valid_inv_gamma); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* The end of the table should match 1.0 carefully. In order to avoid    */ | 
					
						
							|  |  |  | 	/* rounding errors, we just set this explicitly. The last segment may    */ | 
					
						
							| 
									
										
										
										
											2010-07-25 01:45:53 +00:00
										 |  |  | 	/* have a different length than the other segments, but our              */ | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	/* interpolation is insensitive to that.                                 */ | 
					
						
							|  |  |  | 	color_domain_table[RE_GAMMA_TABLE_SIZE]   = 1.0; | 
					
						
							|  |  |  | 	gamma_range_table[RE_GAMMA_TABLE_SIZE]     = 1.0; | 
					
						
							|  |  |  | 	inv_gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* To speed up calculations, we make these calc factor tables. They are  */ | 
					
						
							|  |  |  | 	/* multiplication factors used in scaling the interpolation.             */ | 
					
						
							|  |  |  | 	for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++ ) { | 
					
						
							|  |  |  | 		gamfactor_table[i] = inv_color_step | 
					
						
							|  |  |  | 			* (gamma_range_table[i + 1] - gamma_range_table[i]) ; | 
					
						
							|  |  |  | 		inv_gamfactor_table[i] = inv_color_step | 
					
						
							|  |  |  | 			* (inv_gamma_range_table[i + 1] - inv_gamma_range_table[i]) ; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } /* end of void makeGammaTables(float gamma) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static float gammaCorrect(float c) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	float res = 0.0; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	i = floor(c * inv_color_step); | 
					
						
							|  |  |  | 	/* Clip to range [0,1]: outside, just do the complete calculation.       */ | 
					
						
							|  |  |  | 	/* We may have some performance problems here. Stretching up the LUT     */ | 
					
						
							|  |  |  | 	/* may help solve that, by exchanging LUT size for the interpolation.    */ | 
					
						
							|  |  |  | 	/* Negative colors are explicitly handled.                              */ | 
					
						
							|  |  |  | 	if (i < 0) res = -pow(abs(c), valid_gamma); | 
					
						
							|  |  |  | 	else if (i >= RE_GAMMA_TABLE_SIZE ) res = pow(c, valid_gamma); | 
					
						
							|  |  |  | 	else res = gamma_range_table[i] +  | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 			   ( (c - color_domain_table[i]) * gamfactor_table[i]);  | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	return res; | 
					
						
							|  |  |  | } /* end of float gammaCorrect(float col) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ------------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static float invGammaCorrect(float col) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	float res = 0.0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	i = floor(col*inv_color_step); | 
					
						
							|  |  |  | 	/* Negative colors are explicitly handled.                              */ | 
					
						
							|  |  |  | 	if (i < 0) res = -pow(abs(col), valid_inv_gamma); | 
					
						
							|  |  |  | 	else if (i >= RE_GAMMA_TABLE_SIZE) res = pow(col, valid_inv_gamma); | 
					
						
							|  |  |  | 	else res = inv_gamma_range_table[i] +  | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 			   ( (col - color_domain_table[i]) * inv_gamfactor_table[i]); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  |   | 
					
						
							|  |  |  | 	return res; | 
					
						
							|  |  |  | } /* end of float invGammaCorrect(float col) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void gamtabs(float gamma) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float val, igamma= 1.0f/gamma; | 
					
						
							|  |  |  | 	int a; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* gamtab: in short, out short */ | 
					
						
							|  |  |  | 	for(a=0; a<65536; a++) { | 
					
						
							|  |  |  | 		val= a; | 
					
						
							|  |  |  | 		val/= 65535.0; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if(gamma==2.0) val= sqrt(val); | 
					
						
							|  |  |  | 		else if(gamma!=1.0) val= pow(val, igamma); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		gamtab[a]= (65535.99*val); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* inverse gamtab1 : in byte, out short */ | 
					
						
							|  |  |  | 	for(a=1; a<=256; a++) { | 
					
						
							|  |  |  | 		if(gamma==2.0) igamtab1[a-1]= a*a-1; | 
					
						
							|  |  |  | 		else if(gamma==1.0) igamtab1[a-1]= 256*a-1; | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			val= a/256.0; | 
					
						
							|  |  |  | 			igamtab1[a-1]= (65535.0*pow(val, gamma)) -1 ; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-03 12:30:59 +00:00
										 |  |  | static void build_gammatabs(void) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (gamma_tabs_init == FALSE) { | 
					
						
							|  |  |  | 		gamtabs(2.0f); | 
					
						
							|  |  |  | 		makeGammaTables(2.0f); | 
					
						
							|  |  |  | 		gamma_tabs_init = TRUE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static void init_gammacross(Sequence * UNUSED(seq)) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static void load_gammacross(Sequence * UNUSED(seq)) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static void free_gammacross(Sequence * UNUSED(seq)) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static void do_gammacross_effect_byte(float facf0, float UNUSED(facf1),  | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 					  int x, int y,  | 
					
						
							|  |  |  | 					  unsigned char *rect1,  | 
					
						
							|  |  |  | 					  unsigned char *rect2,  | 
					
						
							|  |  |  | 					  unsigned char *out) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int fac1, fac2, col; | 
					
						
							|  |  |  | 	int xo; | 
					
						
							| 
									
										
										
										
											2009-02-08 19:28:12 +00:00
										 |  |  | 	unsigned char *rt1, *rt2, *rt; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	xo= x; | 
					
						
							| 
									
										
										
										
											2009-02-08 19:28:12 +00:00
										 |  |  | 	rt1= (unsigned char *)rect1; | 
					
						
							|  |  |  | 	rt2= (unsigned char *)rect2; | 
					
						
							|  |  |  | 	rt= (unsigned char *)out; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	fac2= (int)(256.0*facf0); | 
					
						
							|  |  |  | 	fac1= 256-fac2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(y--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			col= (fac1*igamtab1[rt1[0]] + fac2*igamtab1[rt2[0]])>>8; | 
					
						
							|  |  |  | 			if(col>65535) rt[0]= 255; else rt[0]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; | 
					
						
							|  |  |  | 			col=(fac1*igamtab1[rt1[1]] + fac2*igamtab1[rt2[1]])>>8; | 
					
						
							|  |  |  | 			if(col>65535) rt[1]= 255; else rt[1]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; | 
					
						
							|  |  |  | 			col= (fac1*igamtab1[rt1[2]] + fac2*igamtab1[rt2[2]])>>8; | 
					
						
							|  |  |  | 			if(col>65535) rt[2]= 255; else rt[2]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; | 
					
						
							|  |  |  | 			col= (fac1*igamtab1[rt1[3]] + fac2*igamtab1[rt2[3]])>>8; | 
					
						
							|  |  |  | 			if(col>65535) rt[3]= 255; else rt[3]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(y==0) break; | 
					
						
							|  |  |  | 		y--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			col= (fac1*igamtab1[rt1[0]] + fac2*igamtab1[rt2[0]])>>8; | 
					
						
							|  |  |  | 			if(col>65535) rt[0]= 255; else rt[0]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; | 
					
						
							|  |  |  | 			col= (fac1*igamtab1[rt1[1]] + fac2*igamtab1[rt2[1]])>>8; | 
					
						
							|  |  |  | 			if(col>65535) rt[1]= 255; else rt[1]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; | 
					
						
							|  |  |  | 			col= (fac1*igamtab1[rt1[2]] + fac2*igamtab1[rt2[2]])>>8; | 
					
						
							|  |  |  | 			if(col>65535) rt[2]= 255; else rt[2]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; | 
					
						
							|  |  |  | 			col= (fac1*igamtab1[rt1[3]] + fac2*igamtab1[rt2[3]])>>8; | 
					
						
							|  |  |  | 			if(col>65535) rt[3]= 255; else rt[3]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static void do_gammacross_effect_float(float facf0, float UNUSED(facf1),  | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 					   int x, int y,  | 
					
						
							|  |  |  | 					   float *rect1, float *rect2,  | 
					
						
							|  |  |  | 					   float *out) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float fac1, fac2; | 
					
						
							|  |  |  | 	int xo; | 
					
						
							|  |  |  | 	float *rt1, *rt2, *rt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	xo= x; | 
					
						
							|  |  |  | 	rt1= rect1; | 
					
						
							|  |  |  | 	rt2= rect2; | 
					
						
							|  |  |  | 	rt= out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fac2= facf0; | 
					
						
							|  |  |  | 	fac1= 1.0 - fac2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(y--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo * 4; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			*rt= gammaCorrect( | 
					
						
							|  |  |  | 				fac1 * invGammaCorrect(*rt1)  | 
					
						
							|  |  |  | 				+ fac2 * invGammaCorrect(*rt2)); | 
					
						
							|  |  |  | 			rt1++; rt2++; rt++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(y==0) break; | 
					
						
							|  |  |  | 		y--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo * 4; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			*rt= gammaCorrect( | 
					
						
							|  |  |  | 				fac1*invGammaCorrect(*rt1)  | 
					
						
							|  |  |  | 				+ fac2*invGammaCorrect(*rt2)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt1++; rt2++; rt++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | static struct ImBuf * do_gammacross_effect( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	SeqRenderData context, | 
					
						
							|  |  |  | 	Sequence *UNUSED(seq), float UNUSED(cfra), | 
					
						
							|  |  |  | 	float facf0, float facf1,  | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	struct ImBuf *ibuf1, struct ImBuf *ibuf2,  | 
					
						
							|  |  |  | 	struct ImBuf *ibuf3) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	struct ImBuf * out = prepare_effect_imbufs(context,ibuf1, ibuf2, ibuf3); | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	build_gammatabs(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (out->rect_float) { | 
					
						
							|  |  |  | 		do_gammacross_effect_float( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 			facf0, facf1, context.rectx, context.recty, | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			ibuf1->rect_float, ibuf2->rect_float, | 
					
						
							|  |  |  | 			out->rect_float); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		do_gammacross_effect_byte( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 			facf0, facf1, context.rectx, context.recty, | 
					
						
							| 
									
										
										
										
											2009-03-17 22:27:15 +00:00
										 |  |  | 			(unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect, | 
					
						
							|  |  |  | 			(unsigned char*) out->rect); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	return out; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* **********************************************************************
 | 
					
						
							|  |  |  |    ADD | 
					
						
							|  |  |  |    ********************************************************************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void do_add_effect_byte(float facf0, float facf1, int x, int y,  | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 				   unsigned char *rect1, unsigned char *rect2,  | 
					
						
							|  |  |  | 				   unsigned char *out) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int col, xo, fac1, fac3; | 
					
						
							|  |  |  | 	char *rt1, *rt2, *rt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	xo= x; | 
					
						
							|  |  |  | 	rt1= (char *)rect1; | 
					
						
							|  |  |  | 	rt2= (char *)rect2; | 
					
						
							|  |  |  | 	rt= (char *)out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fac1= (int)(256.0*facf0); | 
					
						
							|  |  |  | 	fac3= (int)(256.0*facf1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(y--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			col= rt1[0]+ ((fac1*rt2[0])>>8); | 
					
						
							|  |  |  | 			if(col>255) rt[0]= 255; else rt[0]= col; | 
					
						
							|  |  |  | 			col= rt1[1]+ ((fac1*rt2[1])>>8); | 
					
						
							|  |  |  | 			if(col>255) rt[1]= 255; else rt[1]= col; | 
					
						
							|  |  |  | 			col= rt1[2]+ ((fac1*rt2[2])>>8); | 
					
						
							|  |  |  | 			if(col>255) rt[2]= 255; else rt[2]= col; | 
					
						
							|  |  |  | 			col= rt1[3]+ ((fac1*rt2[3])>>8); | 
					
						
							|  |  |  | 			if(col>255) rt[3]= 255; else rt[3]= col; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(y==0) break; | 
					
						
							|  |  |  | 		y--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			col= rt1[0]+ ((fac3*rt2[0])>>8); | 
					
						
							|  |  |  | 			if(col>255) rt[0]= 255; else rt[0]= col; | 
					
						
							|  |  |  | 			col= rt1[1]+ ((fac3*rt2[1])>>8); | 
					
						
							|  |  |  | 			if(col>255) rt[1]= 255; else rt[1]= col; | 
					
						
							|  |  |  | 			col= rt1[2]+ ((fac3*rt2[2])>>8); | 
					
						
							|  |  |  | 			if(col>255) rt[2]= 255; else rt[2]= col; | 
					
						
							|  |  |  | 			col= rt1[3]+ ((fac3*rt2[3])>>8); | 
					
						
							|  |  |  | 			if(col>255) rt[3]= 255; else rt[3]= col; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void do_add_effect_float(float facf0, float facf1, int x, int y,  | 
					
						
							|  |  |  | 				float *rect1, float *rect2,  | 
					
						
							|  |  |  | 				float *out) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int xo; | 
					
						
							|  |  |  | 	float fac1, fac3; | 
					
						
							|  |  |  | 	float *rt1, *rt2, *rt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	xo= x; | 
					
						
							|  |  |  | 	rt1= rect1; | 
					
						
							|  |  |  | 	rt2= rect2; | 
					
						
							|  |  |  | 	rt= out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fac1= facf0; | 
					
						
							|  |  |  | 	fac3= facf1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(y--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo * 4; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 			*rt = *rt1 + fac1 * (*rt2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt1++; rt2++; rt++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(y==0) break; | 
					
						
							|  |  |  | 		y--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo * 4; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 			*rt = *rt1 + fac3 * (*rt2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt1++; rt2++; rt++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | static struct ImBuf * do_add_effect(SeqRenderData context,  | 
					
						
							|  |  |  | 				    Sequence *UNUSED(seq), float UNUSED(cfra), | 
					
						
							|  |  |  | 				    float facf0, float facf1, | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 				    struct ImBuf *ibuf1, struct ImBuf *ibuf2,  | 
					
						
							|  |  |  | 				    struct ImBuf *ibuf3) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	struct ImBuf * out = prepare_effect_imbufs(context,ibuf1, ibuf2, ibuf3); | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	if (out->rect_float) { | 
					
						
							|  |  |  | 		do_add_effect_float( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 			facf0, facf1, context.rectx, context.recty, | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			ibuf1->rect_float, ibuf2->rect_float, | 
					
						
							|  |  |  | 			out->rect_float); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		do_add_effect_byte( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 			facf0, facf1, context.rectx, context.recty, | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			(unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect, | 
					
						
							|  |  |  | 			(unsigned char*) out->rect); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	return out; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* **********************************************************************
 | 
					
						
							|  |  |  |    SUB | 
					
						
							|  |  |  |    ********************************************************************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void do_sub_effect_byte(float facf0, float facf1,  | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 				   int x, int y,  | 
					
						
							|  |  |  | 				   char *rect1, char *rect2, char *out) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int col, xo, fac1, fac3; | 
					
						
							|  |  |  | 	char *rt1, *rt2, *rt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	xo= x; | 
					
						
							|  |  |  | 	rt1= (char *)rect1; | 
					
						
							|  |  |  | 	rt2= (char *)rect2; | 
					
						
							|  |  |  | 	rt= (char *)out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fac1= (int)(256.0*facf0); | 
					
						
							|  |  |  | 	fac3= (int)(256.0*facf1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(y--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			col= rt1[0]- ((fac1*rt2[0])>>8); | 
					
						
							|  |  |  | 			if(col<0) rt[0]= 0; else rt[0]= col; | 
					
						
							|  |  |  | 			col= rt1[1]- ((fac1*rt2[1])>>8); | 
					
						
							|  |  |  | 			if(col<0) rt[1]= 0; else rt[1]= col; | 
					
						
							|  |  |  | 			col= rt1[2]- ((fac1*rt2[2])>>8); | 
					
						
							|  |  |  | 			if(col<0) rt[2]= 0; else rt[2]= col; | 
					
						
							|  |  |  | 			col= rt1[3]- ((fac1*rt2[3])>>8); | 
					
						
							|  |  |  | 			if(col<0) rt[3]= 0; else rt[3]= col; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(y==0) break; | 
					
						
							|  |  |  | 		y--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			col= rt1[0]- ((fac3*rt2[0])>>8); | 
					
						
							|  |  |  | 			if(col<0) rt[0]= 0; else rt[0]= col; | 
					
						
							|  |  |  | 			col= rt1[1]- ((fac3*rt2[1])>>8); | 
					
						
							|  |  |  | 			if(col<0) rt[1]= 0; else rt[1]= col; | 
					
						
							|  |  |  | 			col= rt1[2]- ((fac3*rt2[2])>>8); | 
					
						
							|  |  |  | 			if(col<0) rt[2]= 0; else rt[2]= col; | 
					
						
							|  |  |  | 			col= rt1[3]- ((fac3*rt2[3])>>8); | 
					
						
							|  |  |  | 			if(col<0) rt[3]= 0; else rt[3]= col; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void do_sub_effect_float(float facf0, float facf1, int x, int y,  | 
					
						
							|  |  |  | 				float *rect1, float *rect2,  | 
					
						
							|  |  |  | 				float *out) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int xo; | 
					
						
							|  |  |  | 	float fac1, fac3; | 
					
						
							|  |  |  | 	float *rt1, *rt2, *rt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	xo= x; | 
					
						
							|  |  |  | 	rt1= rect1; | 
					
						
							|  |  |  | 	rt2= rect2; | 
					
						
							|  |  |  | 	rt= out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fac1= facf0; | 
					
						
							|  |  |  | 	fac3= facf1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(y--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo * 4; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 			*rt = *rt1 - fac1 * (*rt2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt1++; rt2++; rt++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(y==0) break; | 
					
						
							|  |  |  | 		y--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo * 4; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 			*rt = *rt1 - fac3 * (*rt2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt1++; rt2++; rt++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | static struct ImBuf * do_sub_effect( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra), | 
					
						
							|  |  |  | 	float facf0, float facf1,  | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	struct ImBuf *ibuf1, struct ImBuf *ibuf2,  | 
					
						
							|  |  |  | 	struct ImBuf *ibuf3) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	struct ImBuf * out = prepare_effect_imbufs(context,ibuf1, ibuf2, ibuf3); | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	if (out->rect_float) { | 
					
						
							|  |  |  | 		do_sub_effect_float( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 			facf0, facf1, context.rectx, context.recty, | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			ibuf1->rect_float, ibuf2->rect_float, | 
					
						
							|  |  |  | 			out->rect_float); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		do_sub_effect_byte( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 			facf0, facf1, context.rectx, context.recty, | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			(char*) ibuf1->rect, (char*) ibuf2->rect, | 
					
						
							|  |  |  | 			(char*) out->rect); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	return out; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* **********************************************************************
 | 
					
						
							|  |  |  |    DROP | 
					
						
							|  |  |  |    ********************************************************************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Must be > 0 or add precopy, etc to the function */ | 
					
						
							|  |  |  | #define XOFF	8
 | 
					
						
							|  |  |  | #define YOFF	8
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void do_drop_effect_byte(float facf0, float facf1, int x, int y,  | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 				char *rect2i, char *rect1i,  | 
					
						
							|  |  |  | 				char *outi) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int height, width, temp, fac, fac1, fac2; | 
					
						
							|  |  |  | 	char *rt1, *rt2, *out; | 
					
						
							|  |  |  | 	int field= 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	width= x; | 
					
						
							|  |  |  | 	height= y; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fac1= (int)(70.0*facf0); | 
					
						
							|  |  |  | 	fac2= (int)(70.0*facf1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rt2= (char*) (rect2i + YOFF*width); | 
					
						
							|  |  |  | 	rt1= (char*) rect1i; | 
					
						
							|  |  |  | 	out= (char*) outi; | 
					
						
							|  |  |  | 	for (y=0; y<height-YOFF; y++) { | 
					
						
							|  |  |  | 		if(field) fac= fac1; | 
					
						
							|  |  |  | 		else fac= fac2; | 
					
						
							|  |  |  | 		field= !field; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		memcpy(out, rt1, sizeof(int)*XOFF); | 
					
						
							|  |  |  | 		rt1+= XOFF*4; | 
					
						
							|  |  |  | 		out+= XOFF*4; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (x=XOFF; x<width; x++) { | 
					
						
							|  |  |  | 			temp= ((fac*rt2[3])>>8); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			*(out++)= MAX2(0, *rt1 - temp); rt1++; | 
					
						
							|  |  |  | 			*(out++)= MAX2(0, *rt1 - temp); rt1++; | 
					
						
							|  |  |  | 			*(out++)= MAX2(0, *rt1 - temp); rt1++; | 
					
						
							|  |  |  | 			*(out++)= MAX2(0, *rt1 - temp); rt1++; | 
					
						
							|  |  |  | 			rt2+=4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		rt2+=XOFF*4; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	memcpy(out, rt1, sizeof(int)*YOFF*width); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void do_drop_effect_float(float facf0, float facf1, int x, int y,  | 
					
						
							|  |  |  | 				 float *rect2i, float *rect1i,  | 
					
						
							|  |  |  | 				 float *outi) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int height, width; | 
					
						
							|  |  |  | 	float temp, fac, fac1, fac2; | 
					
						
							|  |  |  | 	float *rt1, *rt2, *out; | 
					
						
							|  |  |  | 	int field= 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	width= x; | 
					
						
							|  |  |  | 	height= y; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fac1= 70.0*facf0; | 
					
						
							|  |  |  | 	fac2= 70.0*facf1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rt2=  (rect2i + YOFF*width); | 
					
						
							|  |  |  | 	rt1=  rect1i; | 
					
						
							|  |  |  | 	out=  outi; | 
					
						
							|  |  |  | 	for (y=0; y<height-YOFF; y++) { | 
					
						
							|  |  |  | 		if(field) fac= fac1; | 
					
						
							|  |  |  | 		else fac= fac2; | 
					
						
							|  |  |  | 		field= !field; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		memcpy(out, rt1, 4 * sizeof(float)*XOFF); | 
					
						
							|  |  |  | 		rt1+= XOFF*4; | 
					
						
							|  |  |  | 		out+= XOFF*4; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (x=XOFF; x<width; x++) { | 
					
						
							|  |  |  | 			temp= fac * rt2[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			*(out++)= MAX2(0.0, *rt1 - temp); rt1++; | 
					
						
							|  |  |  | 			*(out++)= MAX2(0.0, *rt1 - temp); rt1++; | 
					
						
							|  |  |  | 			*(out++)= MAX2(0.0, *rt1 - temp); rt1++; | 
					
						
							|  |  |  | 			*(out++)= MAX2(0.0, *rt1 - temp); rt1++; | 
					
						
							|  |  |  | 			rt2+=4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		rt2+=XOFF*4; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	memcpy(out, rt1, 4 * sizeof(float)*YOFF*width); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* **********************************************************************
 | 
					
						
							|  |  |  |    MUL | 
					
						
							|  |  |  |    ********************************************************************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void do_mul_effect_byte(float facf0, float facf1, int x, int y,  | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 				   unsigned char *rect1, unsigned char *rect2,  | 
					
						
							|  |  |  | 				   unsigned char *out) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int xo, fac1, fac3; | 
					
						
							|  |  |  | 	char *rt1, *rt2, *rt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	xo= x; | 
					
						
							|  |  |  | 	rt1= (char *)rect1; | 
					
						
							|  |  |  | 	rt2= (char *)rect2; | 
					
						
							|  |  |  | 	rt= (char *)out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fac1= (int)(256.0*facf0); | 
					
						
							|  |  |  | 	fac3= (int)(256.0*facf1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* formula:
 | 
					
						
							|  |  |  | 	 *		fac*(a*b) + (1-fac)*a  => fac*a*(b-1)+axaux= c*px + py*s ;//+centx
 | 
					
						
							|  |  |  | 			yaux= -s*px + c*py;//+centy
 | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(y--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt[0]= rt1[0] + ((fac1*rt1[0]*(rt2[0]-256))>>16); | 
					
						
							|  |  |  | 			rt[1]= rt1[1] + ((fac1*rt1[1]*(rt2[1]-256))>>16); | 
					
						
							|  |  |  | 			rt[2]= rt1[2] + ((fac1*rt1[2]*(rt2[2]-256))>>16); | 
					
						
							|  |  |  | 			rt[3]= rt1[3] + ((fac1*rt1[3]*(rt2[3]-256))>>16); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(y==0) break; | 
					
						
							|  |  |  | 		y--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt[0]= rt1[0] + ((fac3*rt1[0]*(rt2[0]-256))>>16); | 
					
						
							|  |  |  | 			rt[1]= rt1[1] + ((fac3*rt1[1]*(rt2[1]-256))>>16); | 
					
						
							|  |  |  | 			rt[2]= rt1[2] + ((fac3*rt1[2]*(rt2[2]-256))>>16); | 
					
						
							|  |  |  | 			rt[3]= rt1[3] + ((fac3*rt1[3]*(rt2[3]-256))>>16); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void do_mul_effect_float(float facf0, float facf1, int x, int y,  | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 					float *rect1, float *rect2,  | 
					
						
							|  |  |  | 					float *out) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int xo; | 
					
						
							|  |  |  | 	float fac1, fac3; | 
					
						
							|  |  |  | 	float *rt1, *rt2, *rt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	xo= x; | 
					
						
							|  |  |  | 	rt1= rect1; | 
					
						
							|  |  |  | 	rt2= rect2; | 
					
						
							|  |  |  | 	rt= out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fac1= facf0; | 
					
						
							|  |  |  | 	fac3= facf1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* formula:
 | 
					
						
							|  |  |  | 	 *		fac*(a*b) + (1-fac)*a  => fac*a*(b-1)+a | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(y--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt[0]= rt1[0] + fac1*rt1[0]*(rt2[0]-1.0); | 
					
						
							|  |  |  | 			rt[1]= rt1[1] + fac1*rt1[1]*(rt2[1]-1.0); | 
					
						
							|  |  |  | 			rt[2]= rt1[2] + fac1*rt1[2]*(rt2[2]-1.0); | 
					
						
							|  |  |  | 			rt[3]= rt1[3] + fac1*rt1[3]*(rt2[3]-1.0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(y==0) break; | 
					
						
							|  |  |  | 		y--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		x= xo; | 
					
						
							|  |  |  | 		while(x--) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt[0]= rt1[0] + fac3*rt1[0]*(rt2[0]-1.0); | 
					
						
							|  |  |  | 			rt[1]= rt1[1] + fac3*rt1[1]*(rt2[1]-1.0); | 
					
						
							|  |  |  | 			rt[2]= rt1[2] + fac3*rt1[2]*(rt2[2]-1.0); | 
					
						
							|  |  |  | 			rt[3]= rt1[3] + fac3*rt1[3]*(rt2[3]-1.0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt1+= 4; rt2+= 4; rt+= 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | static struct ImBuf * do_mul_effect( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra), | 
					
						
							|  |  |  | 	float facf0, float facf1,  | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	struct ImBuf *ibuf1, struct ImBuf *ibuf2,  | 
					
						
							|  |  |  | 	struct ImBuf *ibuf3) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	struct ImBuf * out = prepare_effect_imbufs(context,ibuf1, ibuf2, ibuf3); | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	if (out->rect_float) { | 
					
						
							|  |  |  | 		do_mul_effect_float( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 			facf0, facf1, context.rectx, context.recty, | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			ibuf1->rect_float, ibuf2->rect_float, | 
					
						
							|  |  |  | 			out->rect_float); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		do_mul_effect_byte( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 			facf0, facf1, context.rectx, context.recty, | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			(unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect, | 
					
						
							|  |  |  | 			(unsigned char*) out->rect); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return out; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* **********************************************************************
 | 
					
						
							|  |  |  |    WIPE | 
					
						
							|  |  |  |    ********************************************************************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct WipeZone { | 
					
						
							|  |  |  | 	float angle; | 
					
						
							|  |  |  | 	int flip; | 
					
						
							|  |  |  | 	int xo, yo; | 
					
						
							|  |  |  | 	int width; | 
					
						
							|  |  |  | 	float invwidth; | 
					
						
							|  |  |  | 	float pythangle; | 
					
						
							|  |  |  | } WipeZone; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void precalc_wipe_zone(WipeZone *wipezone, WipeVars *wipe, int xo, int yo) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	wipezone->flip = (wipe->angle < 0); | 
					
						
							|  |  |  | 	wipezone->angle = pow(fabs(wipe->angle)/45.0f, log(xo)/log(2.0f)); | 
					
						
							|  |  |  | 	wipezone->xo = xo; | 
					
						
							|  |  |  | 	wipezone->yo = yo; | 
					
						
							|  |  |  | 	wipezone->width = (int)(wipe->edgeWidth*((xo+yo)/2.0f)); | 
					
						
							|  |  |  | 	wipezone->pythangle = 1.0f/sqrt(wipe->angle*wipe->angle + 1.0f); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(wipe->wipetype == DO_SINGLE_WIPE) | 
					
						
							|  |  |  | 		wipezone->invwidth = 1.0f/wipezone->width; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		wipezone->invwidth = 1.0f/(0.5f*wipezone->width); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // This function calculates the blur band for the wipe effects
 | 
					
						
							|  |  |  | static float in_band(WipeZone *wipezone,float width,float dist,float perc,int side,int dir) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-01-08 12:43:44 +00:00
										 |  |  | 	float t1,t2,alpha; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(width == 0) | 
					
						
							|  |  |  | 		return (float)side; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if(width < dist) | 
					
						
							|  |  |  | 		return side; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	t1 = dist * wipezone->invwidth;  //percentange of width that is
 | 
					
						
							|  |  |  | 	t2 = wipezone->invwidth;  //amount of alpha per % point
 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if(side == 1) | 
					
						
							|  |  |  | 		alpha = (t1*t2*100) + (1-perc); // add point's alpha contrib to current position in wipe
 | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		alpha = (1-perc) - (t1*t2*100); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if(dir == 0) | 
					
						
							|  |  |  | 		alpha = 1-alpha; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return alpha; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static float check_zone(WipeZone *wipezone, int x, int y, | 
					
						
							|  |  |  | 	Sequence *seq, float facf0)  | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float posx, posy,hyp,hyp2,angle,hwidth,b1,b2,b3,pointdist; | 
					
						
							|  |  |  | /*some future stuff
 | 
					
						
							|  |  |  | float hyp3,hyp4,b4,b5	    | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 	float temp1,temp2,temp3,temp4; //some placeholder variables
 | 
					
						
							|  |  |  | 	int xo = wipezone->xo; | 
					
						
							|  |  |  | 	int yo = wipezone->yo; | 
					
						
							|  |  |  | 	float halfx = xo*0.5f; | 
					
						
							|  |  |  | 	float halfy = yo*0.5f; | 
					
						
							|  |  |  | 	float widthf,output=0; | 
					
						
							|  |  |  | 	WipeVars *wipe = (WipeVars *)seq->effectdata; | 
					
						
							|  |  |  | 	int width; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(wipezone->flip) x = xo - x; | 
					
						
							|  |  |  | 	angle = wipezone->angle; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	posy = facf0 * yo; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(wipe->forward){ | 
					
						
							|  |  |  | 		posx = facf0 * xo; | 
					
						
							|  |  |  | 		posy = facf0 * yo; | 
					
						
							|  |  |  | 	} else{ | 
					
						
							|  |  |  | 		posx = xo - facf0 * xo; | 
					
						
							|  |  |  | 		posy = yo - facf0 * yo; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (wipe->wipetype) { | 
					
						
							|  |  |  | 		case DO_SINGLE_WIPE: | 
					
						
							|  |  |  | 			width = wipezone->width; | 
					
						
							|  |  |  | 			hwidth = width*0.5f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(angle == 0.0f) { | 
					
						
							|  |  |  | 				b1 = posy; | 
					
						
							|  |  |  | 				b2 = y; | 
					
						
							|  |  |  | 				hyp = fabs(y - posy); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				b1 = posy - (-angle)*posx; | 
					
						
							|  |  |  | 				b2 = y - (-angle)*x; | 
					
						
							|  |  |  | 				hyp = fabs(angle*x+y+(-posy-angle*posx))*wipezone->pythangle; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(angle < 0) { | 
					
						
							|  |  |  | 				temp1 = b1; | 
					
						
							|  |  |  | 				b1 = b2; | 
					
						
							|  |  |  | 				b2 = temp1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(wipe->forward) { | 
					
						
							|  |  |  | 				if(b1 < b2) | 
					
						
							|  |  |  | 					output = in_band(wipezone,width,hyp,facf0,1,1); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					output = in_band(wipezone,width,hyp,facf0,0,1); | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 			 } | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			else { | 
					
						
							|  |  |  | 				if(b1 < b2) | 
					
						
							|  |  |  | 					output = in_band(wipezone,width,hyp,facf0,0,1); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					output = in_band(wipezone,width,hyp,facf0,1,1); | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 			 } | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	  | 
					
						
							|  |  |  | 		case DO_DOUBLE_WIPE: | 
					
						
							|  |  |  | 			if(!wipe->forward) | 
					
						
							|  |  |  | 				facf0 = 1.0f-facf0;   // Go the other direction
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			width = wipezone->width;  // calculate the blur width
 | 
					
						
							|  |  |  | 			hwidth = width*0.5f; | 
					
						
							|  |  |  | 			if (angle == 0) { | 
					
						
							|  |  |  | 				b1 = posy*0.5f; | 
					
						
							|  |  |  | 				b3 = yo-posy*0.5f; | 
					
						
							|  |  |  | 				b2 = y; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				hyp = abs(y - posy*0.5f); | 
					
						
							|  |  |  | 				hyp2 = abs(y - (yo-posy*0.5f)); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				b1 = posy*0.5f - (-angle)*posx*0.5f; | 
					
						
							|  |  |  | 				b3 = (yo-posy*0.5f) - (-angle)*(xo-posx*0.5f); | 
					
						
							|  |  |  | 				b2 = y - (-angle)*x; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				hyp = abs(angle*x+y+(-posy*0.5f-angle*posx*0.5f))*wipezone->pythangle; | 
					
						
							|  |  |  | 				hyp2 = abs(angle*x+y+(-(yo-posy*0.5f)-angle*(xo-posx*0.5f)))*wipezone->pythangle; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			temp1 = xo*(1-facf0*0.5f)-xo*facf0*0.5f; | 
					
						
							|  |  |  | 			temp2 = yo*(1-facf0*0.5f)-yo*facf0*0.5f; | 
					
						
							|  |  |  | 			pointdist = sqrt(temp1*temp1 + temp2*temp2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(b2 < b1 && b2 < b3 ){ | 
					
						
							|  |  |  | 				if(hwidth < pointdist) | 
					
						
							|  |  |  | 					output = in_band(wipezone,hwidth,hyp,facf0,0,1); | 
					
						
							|  |  |  | 			} else if(b2 > b1 && b2 > b3 ){ | 
					
						
							|  |  |  | 				if(hwidth < pointdist) | 
					
						
							|  |  |  | 					output = in_band(wipezone,hwidth,hyp2,facf0,0,1);	 | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				if(  hyp < hwidth && hyp2 > hwidth ) | 
					
						
							|  |  |  | 					output = in_band(wipezone,hwidth,hyp,facf0,1,1); | 
					
						
							|  |  |  | 				else if( hyp > hwidth && hyp2 < hwidth ) | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 					  output = in_band(wipezone,hwidth,hyp2,facf0,1,1); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 				else | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 					  output = in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			if(!wipe->forward)output = 1-output; | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 		 break; | 
					
						
							|  |  |  | 		 case DO_CLOCK_WIPE: | 
					
						
							|  |  |  | 			  /*
 | 
					
						
							|  |  |  | 				  temp1: angle of effect center in rads | 
					
						
							|  |  |  | 				  temp2: angle of line through (halfx,halfy) and (x,y) in rads | 
					
						
							|  |  |  | 				  temp3: angle of low side of blur | 
					
						
							|  |  |  | 				  temp4: angle of high side of blur | 
					
						
							|  |  |  | 			  */ | 
					
						
							|  |  |  | 			 output = 1.0f - facf0; | 
					
						
							|  |  |  | 			 widthf = wipe->edgeWidth*2.0f*(float)M_PI; | 
					
						
							|  |  |  | 			  temp1 = 2.0f * (float)M_PI * facf0; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	 	 	 | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 			 if(wipe->forward){ | 
					
						
							|  |  |  | 				 temp1 = 2.0f*(float)M_PI - temp1; | 
					
						
							|  |  |  | 			 } | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  |  	 		 | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 			  x = x - halfx; | 
					
						
							|  |  |  | 			  y = y - halfy; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			  temp2 = asin(abs(y)/sqrt(x*x + y*y)); | 
					
						
							|  |  |  | 			  if(x <= 0 && y >= 0) temp2 = (float)M_PI - temp2; | 
					
						
							|  |  |  | 			  else if(x<=0 && y <= 0) temp2 += (float)M_PI; | 
					
						
							|  |  |  | 			  else if(x >= 0 && y <= 0) temp2 = 2.0f*(float)M_PI - temp2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			  if(wipe->forward){ | 
					
						
							|  |  |  | 				  temp3 = temp1-(widthf*0.5f)*facf0; | 
					
						
							|  |  |  | 				  temp4 = temp1+(widthf*0.5f)*(1-facf0); | 
					
						
							|  |  |  | 			  } else{ | 
					
						
							|  |  |  | 				  temp3 = temp1-(widthf*0.5f)*(1-facf0); | 
					
						
							|  |  |  | 				  temp4 = temp1+(widthf*0.5f)*facf0; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 			  if (temp3 < 0) temp3 = 0; | 
					
						
							|  |  |  | 			  if (temp4 > 2.0f*(float)M_PI) temp4 = 2.0f*(float)M_PI; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  |  	 		 | 
					
						
							|  |  |  |  	 		 | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 			  if(temp2 < temp3) output = 0; | 
					
						
							|  |  |  | 			  else if (temp2 > temp4) output = 1; | 
					
						
							|  |  |  | 			  else output = (temp2-temp3)/(temp4-temp3); | 
					
						
							|  |  |  | 			  if(x == 0 && y == 0) output = 1; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			if(output != output) output = 1; | 
					
						
							|  |  |  | 			if(wipe->forward) output = 1 - output; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	/* BOX WIPE IS NOT WORKING YET */ | 
					
						
							|  |  |  | 	/* case DO_CROSS_WIPE: */ | 
					
						
							|  |  |  | 	/* BOX WIPE IS NOT WORKING YET */ | 
					
						
							|  |  |  | 	/* 
 | 
					
						
							|  |  |  | 		case DO_BOX_WIPE:  | 
					
						
							|  |  |  | 			if(invert)facf0 = 1-facf0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			width = (int)(wipe->edgeWidth*((xo+yo)/2.0)); | 
					
						
							|  |  |  | 			hwidth = (float)width/2.0; | 
					
						
							|  |  |  | 			if (angle == 0)angle = 0.000001; | 
					
						
							|  |  |  | 			b1 = posy/2 - (-angle)*posx/2; | 
					
						
							|  |  |  | 			b3 = (yo-posy/2) - (-angle)*(xo-posx/2); | 
					
						
							|  |  |  | 			b2 = y - (-angle)*x; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			hyp = abs(angle*x+y+(-posy/2-angle*posx/2))*wipezone->pythangle; | 
					
						
							|  |  |  | 			hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))*wipezone->pythangle; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			temp1 = xo*(1-facf0/2)-xo*facf0/2; | 
					
						
							|  |  |  | 			temp2 = yo*(1-facf0/2)-yo*facf0/2; | 
					
						
							|  |  |  | 			pointdist = sqrt(temp1*temp1 + temp2*temp2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(b2 < b1 && b2 < b3 ){ | 
					
						
							|  |  |  | 				if(hwidth < pointdist) | 
					
						
							|  |  |  | 					output = in_band(wipezone,hwidth,hyp,facf0,0,1); | 
					
						
							|  |  |  | 			} else if(b2 > b1 && b2 > b3 ){ | 
					
						
							|  |  |  | 				if(hwidth < pointdist) | 
					
						
							|  |  |  | 					output = in_band(wipezone,hwidth,hyp2,facf0,0,1);	 | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				if( hyp < hwidth && hyp2 > hwidth ) | 
					
						
							|  |  |  | 					output = in_band(wipezone,hwidth,hyp,facf0,1,1); | 
					
						
							|  |  |  | 				else if( hyp > hwidth && hyp2 < hwidth ) | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 					 output = in_band(wipezone,hwidth,hyp2,facf0,1,1); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 				else | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 					 output = in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(invert)facf0 = 1-facf0; | 
					
						
							|  |  |  | 			angle = -1/angle; | 
					
						
							|  |  |  | 			b1 = posy/2 - (-angle)*posx/2; | 
					
						
							|  |  |  | 			b3 = (yo-posy/2) - (-angle)*(xo-posx/2); | 
					
						
							|  |  |  | 			b2 = y - (-angle)*x; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			hyp = abs(angle*x+y+(-posy/2-angle*posx/2))*wipezone->pythangle; | 
					
						
							|  |  |  | 			hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))*wipezone->pythangle; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(b2 < b1 && b2 < b3 ){ | 
					
						
							|  |  |  | 				if(hwidth < pointdist) | 
					
						
							|  |  |  | 					output *= in_band(wipezone,hwidth,hyp,facf0,0,1); | 
					
						
							|  |  |  | 			} else if(b2 > b1 && b2 > b3 ){ | 
					
						
							|  |  |  | 				if(hwidth < pointdist) | 
					
						
							|  |  |  | 					output *= in_band(wipezone,hwidth,hyp2,facf0,0,1);	 | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				if( hyp < hwidth && hyp2 > hwidth ) | 
					
						
							|  |  |  | 					output *= in_band(wipezone,hwidth,hyp,facf0,1,1); | 
					
						
							|  |  |  | 				else if( hyp > hwidth && hyp2 < hwidth ) | 
					
						
							|  |  |  | 					output *= in_band(wipezone,hwidth,hyp2,facf0,1,1); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					output *= in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 		case DO_IRIS_WIPE: | 
					
						
							|  |  |  | 			if(xo > yo) yo = xo; | 
					
						
							|  |  |  | 			else xo = yo; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(!wipe->forward) facf0 = 1-facf0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			width = wipezone->width; | 
					
						
							|  |  |  | 			hwidth = width*0.5f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			temp1 = (halfx-(halfx)*facf0); | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 			 pointdist = sqrt(temp1*temp1 + temp1*temp1); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 		  | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 			 temp2 = sqrt((halfx-x)*(halfx-x) + (halfy-y)*(halfy-y)); | 
					
						
							|  |  |  | 			 if(temp2 > pointdist) output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,0,1); | 
					
						
							|  |  |  | 			 else output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,1,1); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 		  | 
					
						
							|  |  |  | 			if(!wipe->forward) output = 1-output; | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (output < 0) output = 0; | 
					
						
							|  |  |  | 	else if(output > 1) output = 1; | 
					
						
							|  |  |  | 	return output; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void init_wipe_effect(Sequence *seq) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if(seq->effectdata)MEM_freeN(seq->effectdata); | 
					
						
							|  |  |  | 	seq->effectdata = MEM_callocN(sizeof(struct WipeVars), "wipevars"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-03 12:30:59 +00:00
										 |  |  | static int num_inputs_wipe(void) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void free_wipe_effect(Sequence *seq) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if(seq->effectdata)MEM_freeN(seq->effectdata); | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 	seq->effectdata = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void copy_wipe_effect(Sequence *dst, Sequence *src) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	dst->effectdata = MEM_dupallocN(src->effectdata); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static void do_wipe_effect_byte(Sequence *seq, float facf0, float UNUSED(facf1),  | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 				int x, int y,  | 
					
						
							|  |  |  | 				unsigned char *rect1,  | 
					
						
							|  |  |  | 				unsigned char *rect2, unsigned char *out) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	WipeZone wipezone; | 
					
						
							|  |  |  | 	WipeVars *wipe = (WipeVars *)seq->effectdata; | 
					
						
							|  |  |  | 	int xo, yo; | 
					
						
							|  |  |  | 	char *rt1, *rt2, *rt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	precalc_wipe_zone(&wipezone, wipe, x, y); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rt1 = (char *)rect1; | 
					
						
							|  |  |  | 	rt2 = (char *)rect2; | 
					
						
							|  |  |  | 	rt = (char *)out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	xo = x; | 
					
						
							|  |  |  | 	yo = y; | 
					
						
							|  |  |  | 	for(y=0;y<yo;y++) { | 
					
						
							|  |  |  | 		for(x=0;x<xo;x++) { | 
					
						
							|  |  |  | 			float check = check_zone(&wipezone,x,y,seq,facf0); | 
					
						
							|  |  |  | 			if (check) { | 
					
						
							|  |  |  | 				if (rt1) { | 
					
						
							|  |  |  | 					rt[0] = (int)(rt1[0]*check)+ (int)(rt2[0]*(1-check)); | 
					
						
							|  |  |  | 					rt[1] = (int)(rt1[1]*check)+ (int)(rt2[1]*(1-check)); | 
					
						
							|  |  |  | 					rt[2] = (int)(rt1[2]*check)+ (int)(rt2[2]*(1-check)); | 
					
						
							|  |  |  | 					rt[3] = (int)(rt1[3]*check)+ (int)(rt2[3]*(1-check)); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					rt[0] = 0; | 
					
						
							|  |  |  | 					rt[1] = 0; | 
					
						
							|  |  |  | 					rt[2] = 0; | 
					
						
							|  |  |  | 					rt[3] = 255; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				if (rt2) { | 
					
						
							|  |  |  | 					rt[0] = rt2[0]; | 
					
						
							|  |  |  | 					rt[1] = rt2[1]; | 
					
						
							|  |  |  | 					rt[2] = rt2[2]; | 
					
						
							|  |  |  | 					rt[3] = rt2[3]; | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					rt[0] = 0; | 
					
						
							|  |  |  | 					rt[1] = 0; | 
					
						
							|  |  |  | 					rt[2] = 0; | 
					
						
							|  |  |  | 					rt[3] = 255; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt+=4; | 
					
						
							|  |  |  | 			if(rt1 !=NULL){ | 
					
						
							|  |  |  | 				rt1+=4; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if(rt2 !=NULL){ | 
					
						
							|  |  |  | 				rt2+=4; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static void do_wipe_effect_float(Sequence *seq, float facf0, float UNUSED(facf1),  | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 				 int x, int y,  | 
					
						
							|  |  |  | 				 float *rect1,  | 
					
						
							|  |  |  | 				 float *rect2, float *out) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	WipeZone wipezone; | 
					
						
							|  |  |  | 	WipeVars *wipe = (WipeVars *)seq->effectdata; | 
					
						
							|  |  |  | 	int xo, yo; | 
					
						
							|  |  |  | 	float *rt1, *rt2, *rt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	precalc_wipe_zone(&wipezone, wipe, x, y); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rt1 = rect1; | 
					
						
							|  |  |  | 	rt2 = rect2; | 
					
						
							|  |  |  | 	rt = out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	xo = x; | 
					
						
							|  |  |  | 	yo = y; | 
					
						
							|  |  |  | 	for(y=0;y<yo;y++) { | 
					
						
							|  |  |  | 		for(x=0;x<xo;x++) { | 
					
						
							|  |  |  | 			float check = check_zone(&wipezone,x,y,seq,facf0); | 
					
						
							|  |  |  | 			if (check) { | 
					
						
							|  |  |  | 				if (rt1) { | 
					
						
							|  |  |  | 					rt[0] = rt1[0]*check+ rt2[0]*(1-check); | 
					
						
							|  |  |  | 					rt[1] = rt1[1]*check+ rt2[1]*(1-check); | 
					
						
							|  |  |  | 					rt[2] = rt1[2]*check+ rt2[2]*(1-check); | 
					
						
							|  |  |  | 					rt[3] = rt1[3]*check+ rt2[3]*(1-check); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					rt[0] = 0; | 
					
						
							|  |  |  | 					rt[1] = 0; | 
					
						
							|  |  |  | 					rt[2] = 0; | 
					
						
							|  |  |  | 					rt[3] = 1.0; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				if (rt2) { | 
					
						
							|  |  |  | 					rt[0] = rt2[0]; | 
					
						
							|  |  |  | 					rt[1] = rt2[1]; | 
					
						
							|  |  |  | 					rt[2] = rt2[2]; | 
					
						
							|  |  |  | 					rt[3] = rt2[3]; | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					rt[0] = 0; | 
					
						
							|  |  |  | 					rt[1] = 0; | 
					
						
							|  |  |  | 					rt[2] = 0; | 
					
						
							|  |  |  | 					rt[3] = 1.0; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			rt+=4; | 
					
						
							|  |  |  | 			if(rt1 !=NULL){ | 
					
						
							|  |  |  | 				rt1+=4; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if(rt2 !=NULL){ | 
					
						
							|  |  |  | 				rt2+=4; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | static struct ImBuf * do_wipe_effect( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	SeqRenderData context, Sequence *seq, float UNUSED(cfra), | 
					
						
							|  |  |  | 	float facf0, float facf1,  | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	struct ImBuf *ibuf1, struct ImBuf *ibuf2,  | 
					
						
							|  |  |  | 	struct ImBuf *ibuf3) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	struct ImBuf * out = prepare_effect_imbufs(context,ibuf1, ibuf2, ibuf3); | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	if (out->rect_float) { | 
					
						
							|  |  |  | 		do_wipe_effect_float(seq, | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 				     facf0, facf1, context.rectx, context.recty, | 
					
						
							|  |  |  | 				     ibuf1->rect_float, ibuf2->rect_float, | 
					
						
							|  |  |  | 				     out->rect_float); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		do_wipe_effect_byte(seq, | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 				    facf0, facf1, context.rectx, context.recty, | 
					
						
							|  |  |  | 				    (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect, | 
					
						
							|  |  |  | 				    (unsigned char*) out->rect); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return out; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | /* **********************************************************************
 | 
					
						
							|  |  |  |    TRANSFORM | 
					
						
							|  |  |  |    ********************************************************************** */ | 
					
						
							|  |  |  | static void init_transform_effect(Sequence *seq) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-11 22:51:53 +00:00
										 |  |  | 	TransformVars *transform; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(seq->effectdata)MEM_freeN(seq->effectdata); | 
					
						
							|  |  |  | 	seq->effectdata = MEM_callocN(sizeof(struct TransformVars), "transformvars"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-11 22:51:53 +00:00
										 |  |  | 	transform = (TransformVars *)seq->effectdata; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	transform->ScalexIni = 1.0f; | 
					
						
							|  |  |  | 	transform->ScaleyIni = 1.0f; | 
					
						
							|  |  |  | 	transform->ScalexFin = 1.0f; | 
					
						
							|  |  |  | 	transform->ScalexFin = 1.0f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	transform->xIni=0.0f; | 
					
						
							|  |  |  | 	transform->xFin=0.0f; | 
					
						
							|  |  |  | 	transform->yIni=0.0f; | 
					
						
							|  |  |  | 	transform->yFin=0.0f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	transform->rotIni=0.0f; | 
					
						
							|  |  |  | 	transform->rotFin=0.0f; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-12-11 22:51:53 +00:00
										 |  |  | 	transform->interpolation=1; | 
					
						
							|  |  |  | 	transform->percent=1; | 
					
						
							|  |  |  | 	transform->uniform_scale=0; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-03 12:30:59 +00:00
										 |  |  | static int num_inputs_transform(void) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void free_transform_effect(Sequence *seq) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if(seq->effectdata)MEM_freeN(seq->effectdata); | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 	seq->effectdata = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void copy_transform_effect(Sequence *dst, Sequence *src) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	dst->effectdata = MEM_dupallocN(src->effectdata); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-11 22:51:53 +00:00
										 |  |  | static void transform_image(int x, int y, struct ImBuf *ibuf1, struct ImBuf *out,  | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 			    float scale_x, float scale_y, float translate_x, float translate_y,  | 
					
						
							|  |  |  | 			    float rotate, int interpolation) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int xo, yo, xi, yi; | 
					
						
							| 
									
										
										
										
											2009-12-11 22:51:53 +00:00
										 |  |  | 	float xt, yt, xr, yr; | 
					
						
							|  |  |  | 	float s,c; | 
					
						
							| 
									
										
										
										
											2009-02-08 19:28:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	xo = x; | 
					
						
							|  |  |  | 	yo = y; | 
					
						
							| 
									
										
										
										
											2009-12-11 22:51:53 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	// Rotate
 | 
					
						
							|  |  |  | 	s= sin(rotate); | 
					
						
							|  |  |  | 	c= cos(rotate); | 
					
						
							| 
									
										
										
										
											2009-02-08 19:28:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	for (yi = 0; yi < yo; yi++) { | 
					
						
							|  |  |  | 		for (xi = 0; xi < xo; xi++) { | 
					
						
							| 
									
										
										
										
											2009-12-11 22:51:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			//translate point
 | 
					
						
							|  |  |  | 			xt = xi-translate_x; | 
					
						
							|  |  |  | 			yt = yi-translate_y; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			//rotate point with center ref
 | 
					
						
							| 
									
										
										
										
											2009-12-11 22:51:53 +00:00
										 |  |  | 			xr =  c*xt + s*yt; | 
					
						
							|  |  |  | 			yr = -s*xt + c*yt; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			//scale point with center ref
 | 
					
						
							| 
									
										
										
										
											2009-12-11 22:51:53 +00:00
										 |  |  | 			xt = xr / scale_x; | 
					
						
							|  |  |  | 			yt = yr / scale_y; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			//undo reference center point 
 | 
					
						
							| 
									
										
										
										
											2009-12-11 22:51:53 +00:00
										 |  |  | 			xt += (xo / 2.0f); | 
					
						
							|  |  |  | 			yt += (yo / 2.0f); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			//interpolate
 | 
					
						
							| 
									
										
										
										
											2009-12-11 22:51:53 +00:00
										 |  |  | 			switch(interpolation) { | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			case 0: | 
					
						
							| 
									
										
										
										
											2009-12-11 22:51:53 +00:00
										 |  |  | 				neareast_interpolation(ibuf1,out, xt,yt,xi,yi); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			case 1: | 
					
						
							| 
									
										
										
										
											2009-12-11 22:51:53 +00:00
										 |  |  | 				bilinear_interpolation(ibuf1,out, xt,yt,xi,yi); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			case 2: | 
					
						
							| 
									
										
										
										
											2009-12-11 22:51:53 +00:00
										 |  |  | 				bicubic_interpolation(ibuf1,out, xt,yt,xi,yi); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-12-11 22:51:53 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static void do_transform(Scene *scene, Sequence *seq, float UNUSED(facf0), int x, int y,  | 
					
						
							| 
									
										
										
										
											2009-12-11 22:51:53 +00:00
										 |  |  | 			  struct ImBuf *ibuf1,struct ImBuf *out) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	TransformVars *transform = (TransformVars *)seq->effectdata; | 
					
						
							|  |  |  | 	float scale_x, scale_y, translate_x, translate_y, rotate_radians; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	// Scale
 | 
					
						
							|  |  |  | 	if (transform->uniform_scale) { | 
					
						
							|  |  |  | 		scale_x = scale_y = transform->ScalexIni; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		scale_x = transform->ScalexIni; | 
					
						
							|  |  |  | 		scale_y = transform->ScaleyIni; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Translate
 | 
					
						
							|  |  |  | 	if(!transform->percent){ | 
					
						
							|  |  |  | 		float rd_s = (scene->r.size/100.0f); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-11 22:51:53 +00:00
										 |  |  | 		translate_x = transform->xIni*rd_s+(x/2.0f); | 
					
						
							|  |  |  | 		translate_y = transform->yIni*rd_s+(y/2.0f); | 
					
						
							|  |  |  | 	}else{ | 
					
						
							|  |  |  | 		translate_x = x*(transform->xIni/100.0f)+(x/2.0f); | 
					
						
							|  |  |  | 		translate_y = y*(transform->yIni/100.0f)+(y/2.0f); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	// Rotate
 | 
					
						
							|  |  |  | 	rotate_radians = (M_PI*transform->rotIni)/180.0f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	transform_image(x,y, ibuf1, out, scale_x, scale_y, translate_x, translate_y, rotate_radians, transform->interpolation); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-12-11 22:51:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | static struct ImBuf * do_transform_effect( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	SeqRenderData context, Sequence *seq,float UNUSED(cfra), | 
					
						
							|  |  |  | 	float facf0, float UNUSED(facf1),  | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	struct ImBuf *ibuf1, struct ImBuf *ibuf2,  | 
					
						
							|  |  |  | 	struct ImBuf *ibuf3) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	struct ImBuf * out = prepare_effect_imbufs(context,ibuf1, ibuf2, ibuf3); | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	do_transform(context.scene, seq, facf0,  | 
					
						
							|  |  |  | 		     context.rectx, context.recty, ibuf1, out); | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return out; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* **********************************************************************
 | 
					
						
							|  |  |  |    GLOW | 
					
						
							|  |  |  |    ********************************************************************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void RVBlurBitmap2_byte ( unsigned char* map, int width,int height, | 
					
						
							|  |  |  | 				 float blur, | 
					
						
							|  |  |  | 				 int quality) | 
					
						
							|  |  |  | /*	MUUUCCH better than the previous blur. */ | 
					
						
							|  |  |  | /*	We do the blurring in two passes which is a whole lot faster. */ | 
					
						
							|  |  |  | /*	I changed the math arount to implement an actual Gaussian */ | 
					
						
							|  |  |  | /*	distribution. */ | 
					
						
							|  |  |  | /* */ | 
					
						
							|  |  |  | /*	Watch out though, it tends to misbehaven with large blur values on */ | 
					
						
							|  |  |  | /*	a small bitmap.  Avoid avoid avoid. */ | 
					
						
							|  |  |  | /*=============================== */ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned char*	temp=NULL,*swap; | 
					
						
							|  |  |  | 	float	*filter=NULL; | 
					
						
							|  |  |  | 	int	x,y,i,fx,fy; | 
					
						
							|  |  |  | 	int	index, ix, halfWidth; | 
					
						
							|  |  |  | 	float	fval, k, curColor[3], curColor2[3], weight=0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*	If we're not really blurring, bail out */ | 
					
						
							|  |  |  | 	if (blur<=0) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*	Allocate memory for the tempmap and the blur filter matrix */ | 
					
						
							|  |  |  | 	temp= MEM_mallocN( (width*height*4), "blurbitmaptemp"); | 
					
						
							|  |  |  | 	if (!temp) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*	Allocate memory for the filter elements */ | 
					
						
							|  |  |  | 	halfWidth = ((quality+1)*blur); | 
					
						
							|  |  |  | 	filter = (float *)MEM_mallocN(sizeof(float)*halfWidth*2, "blurbitmapfilter"); | 
					
						
							|  |  |  | 	if (!filter){ | 
					
						
							|  |  |  | 		MEM_freeN (temp); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*	Apparently we're calculating a bell curve */ | 
					
						
							|  |  |  | 	/*	based on the standard deviation (or radius) */ | 
					
						
							|  |  |  | 	/*	This code is based on an example */ | 
					
						
							|  |  |  | 	/*	posted to comp.graphics.algorithms by */ | 
					
						
							|  |  |  | 	/*	Blancmange (bmange@airdmhor.gen.nz) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	k = -1.0/(2.0*3.14159*blur*blur); | 
					
						
							|  |  |  | 	for (ix = 0;ix< halfWidth;ix++){ | 
					
						
							|  |  |  | 		weight = (float)exp(k*(ix*ix)); | 
					
						
							|  |  |  | 		filter[halfWidth - ix] = weight; | 
					
						
							|  |  |  | 		filter[halfWidth + ix] = weight; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	filter[0] = weight; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*	Normalize the array */ | 
					
						
							|  |  |  | 	fval=0; | 
					
						
							|  |  |  | 	for (ix = 0;ix< halfWidth*2;ix++) | 
					
						
							|  |  |  | 		fval+=filter[ix]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (ix = 0;ix< halfWidth*2;ix++) | 
					
						
							|  |  |  | 		filter[ix]/=fval; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*	Blur the rows */ | 
					
						
							|  |  |  | 	for (y=0;y<height;y++){ | 
					
						
							|  |  |  | 		/*	Do the left & right strips */ | 
					
						
							|  |  |  | 		for (x=0;x<halfWidth;x++){ | 
					
						
							|  |  |  | 			index=(x+y*width)*4; | 
					
						
							|  |  |  | 			fx=0; | 
					
						
							|  |  |  | 			curColor[0]=curColor[1]=curColor[2]=0; | 
					
						
							|  |  |  | 			curColor2[0]=curColor2[1]=curColor2[2]=0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for (i=x-halfWidth;i<x+halfWidth;i++){ | 
					
						
							|  |  |  | 				if ((i>=0)&&(i<width)){ | 
					
						
							|  |  |  | 					curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx]; | 
					
						
							|  |  |  | 					curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx]; | 
					
						
							|  |  |  | 					curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					curColor2[0]+=map[(width-1-i+y*width)*4+GlowR] * | 
					
						
							|  |  |  | 						filter[fx]; | 
					
						
							|  |  |  | 					curColor2[1]+=map[(width-1-i+y*width)*4+GlowG] * | 
					
						
							|  |  |  | 						filter[fx]; | 
					
						
							|  |  |  | 					curColor2[2]+=map[(width-1-i+y*width)*4+GlowB] * | 
					
						
							|  |  |  | 						filter[fx]; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				fx++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			temp[index+GlowR]=curColor[0]; | 
					
						
							|  |  |  | 			temp[index+GlowG]=curColor[1]; | 
					
						
							|  |  |  | 			temp[index+GlowB]=curColor[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			temp[((width-1-x+y*width)*4)+GlowR]=curColor2[0]; | 
					
						
							|  |  |  | 			temp[((width-1-x+y*width)*4)+GlowG]=curColor2[1]; | 
					
						
							|  |  |  | 			temp[((width-1-x+y*width)*4)+GlowB]=curColor2[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		/*	Do the main body */ | 
					
						
							|  |  |  | 		for (x=halfWidth;x<width-halfWidth;x++){ | 
					
						
							|  |  |  | 			index=(x+y*width)*4; | 
					
						
							|  |  |  | 			fx=0; | 
					
						
							|  |  |  | 			curColor[0]=curColor[1]=curColor[2]=0; | 
					
						
							|  |  |  | 			for (i=x-halfWidth;i<x+halfWidth;i++){ | 
					
						
							|  |  |  | 				curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx]; | 
					
						
							|  |  |  | 				curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx]; | 
					
						
							|  |  |  | 				curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx]; | 
					
						
							|  |  |  | 				fx++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			temp[index+GlowR]=curColor[0]; | 
					
						
							|  |  |  | 			temp[index+GlowG]=curColor[1]; | 
					
						
							|  |  |  | 			temp[index+GlowB]=curColor[2]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*	Swap buffers */ | 
					
						
							|  |  |  | 	swap=temp;temp=map;map=swap; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*	Blur the columns */ | 
					
						
							|  |  |  | 	for (x=0;x<width;x++){ | 
					
						
							|  |  |  | 		/*	Do the top & bottom strips */ | 
					
						
							|  |  |  | 		for (y=0;y<halfWidth;y++){ | 
					
						
							|  |  |  | 			index=(x+y*width)*4; | 
					
						
							|  |  |  | 			fy=0; | 
					
						
							|  |  |  | 			curColor[0]=curColor[1]=curColor[2]=0; | 
					
						
							|  |  |  | 			curColor2[0]=curColor2[1]=curColor2[2]=0; | 
					
						
							|  |  |  | 			for (i=y-halfWidth;i<y+halfWidth;i++){ | 
					
						
							|  |  |  | 				if ((i>=0)&&(i<height)){ | 
					
						
							|  |  |  | 					/*	Bottom */ | 
					
						
							|  |  |  | 					curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy]; | 
					
						
							|  |  |  | 					curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy]; | 
					
						
							|  |  |  | 					curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					/*	Top */ | 
					
						
							|  |  |  | 					curColor2[0]+=map[(x+(height-1-i)*width) * | 
					
						
							|  |  |  | 						4+GlowR]*filter[fy]; | 
					
						
							|  |  |  | 					curColor2[1]+=map[(x+(height-1-i)*width) * | 
					
						
							|  |  |  | 						4+GlowG]*filter[fy]; | 
					
						
							|  |  |  | 					curColor2[2]+=map[(x+(height-1-i)*width) * | 
					
						
							|  |  |  | 						4+GlowB]*filter[fy]; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				fy++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			temp[index+GlowR]=curColor[0]; | 
					
						
							|  |  |  | 			temp[index+GlowG]=curColor[1]; | 
					
						
							|  |  |  | 			temp[index+GlowB]=curColor[2]; | 
					
						
							|  |  |  | 			temp[((x+(height-1-y)*width)*4)+GlowR]=curColor2[0]; | 
					
						
							|  |  |  | 			temp[((x+(height-1-y)*width)*4)+GlowG]=curColor2[1]; | 
					
						
							|  |  |  | 			temp[((x+(height-1-y)*width)*4)+GlowB]=curColor2[2]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		/*	Do the main body */ | 
					
						
							|  |  |  | 		for (y=halfWidth;y<height-halfWidth;y++){ | 
					
						
							|  |  |  | 			index=(x+y*width)*4; | 
					
						
							|  |  |  | 			fy=0; | 
					
						
							|  |  |  | 			curColor[0]=curColor[1]=curColor[2]=0; | 
					
						
							|  |  |  | 			for (i=y-halfWidth;i<y+halfWidth;i++){ | 
					
						
							|  |  |  | 				curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy]; | 
					
						
							|  |  |  | 				curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy]; | 
					
						
							|  |  |  | 				curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy]; | 
					
						
							|  |  |  | 				fy++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			temp[index+GlowR]=curColor[0]; | 
					
						
							|  |  |  | 			temp[index+GlowG]=curColor[1]; | 
					
						
							|  |  |  | 			temp[index+GlowB]=curColor[2]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*	Swap buffers */ | 
					
						
							|  |  |  | 	swap=temp;temp=map;map=swap; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*	Tidy up	 */ | 
					
						
							|  |  |  | 	MEM_freeN (filter); | 
					
						
							|  |  |  | 	MEM_freeN (temp); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void RVBlurBitmap2_float ( float* map, int width,int height, | 
					
						
							|  |  |  | 				  float blur, | 
					
						
							|  |  |  | 				  int quality) | 
					
						
							|  |  |  | /*	MUUUCCH better than the previous blur. */ | 
					
						
							|  |  |  | /*	We do the blurring in two passes which is a whole lot faster. */ | 
					
						
							|  |  |  | /*	I changed the math arount to implement an actual Gaussian */ | 
					
						
							|  |  |  | /*	distribution. */ | 
					
						
							|  |  |  | /* */ | 
					
						
							|  |  |  | /*	Watch out though, it tends to misbehaven with large blur values on */ | 
					
						
							|  |  |  | /*	a small bitmap.  Avoid avoid avoid. */ | 
					
						
							|  |  |  | /*=============================== */ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float*	temp=NULL,*swap; | 
					
						
							|  |  |  | 	float	*filter=NULL; | 
					
						
							|  |  |  | 	int	x,y,i,fx,fy; | 
					
						
							|  |  |  | 	int	index, ix, halfWidth; | 
					
						
							|  |  |  | 	float	fval, k, curColor[3], curColor2[3], weight=0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*	If we're not really blurring, bail out */ | 
					
						
							|  |  |  | 	if (blur<=0) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*	Allocate memory for the tempmap and the blur filter matrix */ | 
					
						
							|  |  |  | 	temp= MEM_mallocN( (width*height*4*sizeof(float)), "blurbitmaptemp"); | 
					
						
							|  |  |  | 	if (!temp) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*	Allocate memory for the filter elements */ | 
					
						
							|  |  |  | 	halfWidth = ((quality+1)*blur); | 
					
						
							|  |  |  | 	filter = (float *)MEM_mallocN(sizeof(float)*halfWidth*2, "blurbitmapfilter"); | 
					
						
							|  |  |  | 	if (!filter){ | 
					
						
							|  |  |  | 		MEM_freeN (temp); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*	Apparently we're calculating a bell curve */ | 
					
						
							|  |  |  | 	/*	based on the standard deviation (or radius) */ | 
					
						
							|  |  |  | 	/*	This code is based on an example */ | 
					
						
							|  |  |  | 	/*	posted to comp.graphics.algorithms by */ | 
					
						
							|  |  |  | 	/*	Blancmange (bmange@airdmhor.gen.nz) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	k = -1.0/(2.0*3.14159*blur*blur); | 
					
						
							|  |  |  | 	fval=0; | 
					
						
							|  |  |  | 	for (ix = 0;ix< halfWidth;ix++){ | 
					
						
							|  |  |  | 		weight = (float)exp(k*(ix*ix)); | 
					
						
							|  |  |  | 		filter[halfWidth - ix] = weight; | 
					
						
							|  |  |  | 		filter[halfWidth + ix] = weight; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	filter[0] = weight; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*	Normalize the array */ | 
					
						
							|  |  |  | 	fval=0; | 
					
						
							|  |  |  | 	for (ix = 0;ix< halfWidth*2;ix++) | 
					
						
							|  |  |  | 		fval+=filter[ix]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (ix = 0;ix< halfWidth*2;ix++) | 
					
						
							|  |  |  | 		filter[ix]/=fval; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*	Blur the rows */ | 
					
						
							|  |  |  | 	for (y=0;y<height;y++){ | 
					
						
							|  |  |  | 		/*	Do the left & right strips */ | 
					
						
							|  |  |  | 		for (x=0;x<halfWidth;x++){ | 
					
						
							|  |  |  | 			index=(x+y*width)*4; | 
					
						
							|  |  |  | 			fx=0; | 
					
						
							|  |  |  | 			curColor[0]=curColor[1]=curColor[2]=0.0f; | 
					
						
							|  |  |  | 			curColor2[0]=curColor2[1]=curColor2[2]=0.0f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for (i=x-halfWidth;i<x+halfWidth;i++){ | 
					
						
							|  |  |  | 				if ((i>=0)&&(i<width)){ | 
					
						
							|  |  |  | 					curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx]; | 
					
						
							|  |  |  | 					curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx]; | 
					
						
							|  |  |  | 					curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					curColor2[0]+=map[(width-1-i+y*width)*4+GlowR] * | 
					
						
							|  |  |  | 						filter[fx]; | 
					
						
							|  |  |  | 					curColor2[1]+=map[(width-1-i+y*width)*4+GlowG] * | 
					
						
							|  |  |  | 						filter[fx]; | 
					
						
							|  |  |  | 					curColor2[2]+=map[(width-1-i+y*width)*4+GlowB] * | 
					
						
							|  |  |  | 						filter[fx]; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				fx++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			temp[index+GlowR]=curColor[0]; | 
					
						
							|  |  |  | 			temp[index+GlowG]=curColor[1]; | 
					
						
							|  |  |  | 			temp[index+GlowB]=curColor[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			temp[((width-1-x+y*width)*4)+GlowR]=curColor2[0]; | 
					
						
							|  |  |  | 			temp[((width-1-x+y*width)*4)+GlowG]=curColor2[1]; | 
					
						
							|  |  |  | 			temp[((width-1-x+y*width)*4)+GlowB]=curColor2[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		/*	Do the main body */ | 
					
						
							|  |  |  | 		for (x=halfWidth;x<width-halfWidth;x++){ | 
					
						
							|  |  |  | 			index=(x+y*width)*4; | 
					
						
							|  |  |  | 			fx=0; | 
					
						
							|  |  |  | 			curColor[0]=curColor[1]=curColor[2]=0; | 
					
						
							|  |  |  | 			for (i=x-halfWidth;i<x+halfWidth;i++){ | 
					
						
							|  |  |  | 				curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx]; | 
					
						
							|  |  |  | 				curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx]; | 
					
						
							|  |  |  | 				curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx]; | 
					
						
							|  |  |  | 				fx++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			temp[index+GlowR]=curColor[0]; | 
					
						
							|  |  |  | 			temp[index+GlowG]=curColor[1]; | 
					
						
							|  |  |  | 			temp[index+GlowB]=curColor[2]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*	Swap buffers */ | 
					
						
							|  |  |  | 	swap=temp;temp=map;map=swap; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*	Blur the columns */ | 
					
						
							|  |  |  | 	for (x=0;x<width;x++){ | 
					
						
							|  |  |  | 		/*	Do the top & bottom strips */ | 
					
						
							|  |  |  | 		for (y=0;y<halfWidth;y++){ | 
					
						
							|  |  |  | 			index=(x+y*width)*4; | 
					
						
							|  |  |  | 			fy=0; | 
					
						
							|  |  |  | 			curColor[0]=curColor[1]=curColor[2]=0; | 
					
						
							|  |  |  | 			curColor2[0]=curColor2[1]=curColor2[2]=0; | 
					
						
							|  |  |  | 			for (i=y-halfWidth;i<y+halfWidth;i++){ | 
					
						
							|  |  |  | 				if ((i>=0)&&(i<height)){ | 
					
						
							|  |  |  | 					/*	Bottom */ | 
					
						
							|  |  |  | 					curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy]; | 
					
						
							|  |  |  | 					curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy]; | 
					
						
							|  |  |  | 					curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					/*	Top */ | 
					
						
							|  |  |  | 					curColor2[0]+=map[(x+(height-1-i)*width) * | 
					
						
							|  |  |  | 						4+GlowR]*filter[fy]; | 
					
						
							|  |  |  | 					curColor2[1]+=map[(x+(height-1-i)*width) * | 
					
						
							|  |  |  | 						4+GlowG]*filter[fy]; | 
					
						
							|  |  |  | 					curColor2[2]+=map[(x+(height-1-i)*width) * | 
					
						
							|  |  |  | 						4+GlowB]*filter[fy]; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				fy++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			temp[index+GlowR]=curColor[0]; | 
					
						
							|  |  |  | 			temp[index+GlowG]=curColor[1]; | 
					
						
							|  |  |  | 			temp[index+GlowB]=curColor[2]; | 
					
						
							|  |  |  | 			temp[((x+(height-1-y)*width)*4)+GlowR]=curColor2[0]; | 
					
						
							|  |  |  | 			temp[((x+(height-1-y)*width)*4)+GlowG]=curColor2[1]; | 
					
						
							|  |  |  | 			temp[((x+(height-1-y)*width)*4)+GlowB]=curColor2[2]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		/*	Do the main body */ | 
					
						
							|  |  |  | 		for (y=halfWidth;y<height-halfWidth;y++){ | 
					
						
							|  |  |  | 			index=(x+y*width)*4; | 
					
						
							|  |  |  | 			fy=0; | 
					
						
							|  |  |  | 			curColor[0]=curColor[1]=curColor[2]=0; | 
					
						
							|  |  |  | 			for (i=y-halfWidth;i<y+halfWidth;i++){ | 
					
						
							|  |  |  | 				curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy]; | 
					
						
							|  |  |  | 				curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy]; | 
					
						
							|  |  |  | 				curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy]; | 
					
						
							|  |  |  | 				fy++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			temp[index+GlowR]=curColor[0]; | 
					
						
							|  |  |  | 			temp[index+GlowG]=curColor[1]; | 
					
						
							|  |  |  | 			temp[index+GlowB]=curColor[2]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*	Swap buffers */ | 
					
						
							|  |  |  | 	swap=temp;temp=map;map=swap; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*	Tidy up	 */ | 
					
						
							|  |  |  | 	MEM_freeN (filter); | 
					
						
							|  |  |  | 	MEM_freeN (temp); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*	Adds two bitmaps and puts the results into a third map. */ | 
					
						
							|  |  |  | /*	C must have been previously allocated but it may be A or B. */ | 
					
						
							|  |  |  | /*	We clamp values to 255 to prevent weirdness */ | 
					
						
							|  |  |  | /*=============================== */ | 
					
						
							|  |  |  | static void RVAddBitmaps_byte (unsigned char* a, unsigned char* b, unsigned char* c, int width, int height) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int	x,y,index; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (y=0;y<height;y++){ | 
					
						
							|  |  |  | 		for (x=0;x<width;x++){ | 
					
						
							|  |  |  | 			index=(x+y*width)*4; | 
					
						
							|  |  |  | 			c[index+GlowR]=MIN2(255,a[index+GlowR]+b[index+GlowR]); | 
					
						
							|  |  |  | 			c[index+GlowG]=MIN2(255,a[index+GlowG]+b[index+GlowG]); | 
					
						
							|  |  |  | 			c[index+GlowB]=MIN2(255,a[index+GlowB]+b[index+GlowB]); | 
					
						
							|  |  |  | 			c[index+GlowA]=MIN2(255,a[index+GlowA]+b[index+GlowA]); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void RVAddBitmaps_float (float* a, float* b, float* c,  | 
					
						
							|  |  |  | 				int width, int height) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int	x,y,index; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (y=0;y<height;y++){ | 
					
						
							|  |  |  | 		for (x=0;x<width;x++){ | 
					
						
							|  |  |  | 			index=(x+y*width)*4; | 
					
						
							|  |  |  | 			c[index+GlowR]=MIN2(1.0,a[index+GlowR]+b[index+GlowR]); | 
					
						
							|  |  |  | 			c[index+GlowG]=MIN2(1.0,a[index+GlowG]+b[index+GlowG]); | 
					
						
							|  |  |  | 			c[index+GlowB]=MIN2(1.0,a[index+GlowB]+b[index+GlowB]); | 
					
						
							|  |  |  | 			c[index+GlowA]=MIN2(1.0,a[index+GlowA]+b[index+GlowA]); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*	For each pixel whose total luminance exceeds the threshold, */ | 
					
						
							|  |  |  | /*	Multiply it's value by BOOST and add it to the output map */ | 
					
						
							|  |  |  | static void RVIsolateHighlights_byte (unsigned char* in, unsigned char* out,  | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 					  int width, int height, int threshold,  | 
					
						
							|  |  |  | 					  float boost, float clamp) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int x,y,index; | 
					
						
							|  |  |  | 	int	intensity; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for(y=0;y< height;y++) { | 
					
						
							|  |  |  | 		for (x=0;x< width;x++) { | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 			 index= (x+y*width)*4; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/*	Isolate the intensity */ | 
					
						
							|  |  |  | 			intensity=(in[index+GlowR]+in[index+GlowG]+in[index+GlowB]-threshold); | 
					
						
							|  |  |  | 			if (intensity>0){ | 
					
						
							|  |  |  | 				out[index+GlowR]=MIN2(255*clamp, (in[index+GlowR]*boost*intensity)/255); | 
					
						
							|  |  |  | 				out[index+GlowG]=MIN2(255*clamp, (in[index+GlowG]*boost*intensity)/255); | 
					
						
							|  |  |  | 				out[index+GlowB]=MIN2(255*clamp, (in[index+GlowB]*boost*intensity)/255); | 
					
						
							|  |  |  | 				out[index+GlowA]=MIN2(255*clamp, (in[index+GlowA]*boost*intensity)/255); | 
					
						
							|  |  |  | 			} else{ | 
					
						
							|  |  |  | 				out[index+GlowR]=0; | 
					
						
							|  |  |  | 				out[index+GlowG]=0; | 
					
						
							|  |  |  | 				out[index+GlowB]=0; | 
					
						
							|  |  |  | 				out[index+GlowA]=0; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void RVIsolateHighlights_float (float* in, float* out,  | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 					  int width, int height, float threshold,  | 
					
						
							|  |  |  | 					  float boost, float clamp) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int x,y,index; | 
					
						
							|  |  |  | 	float	intensity; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for(y=0;y< height;y++) { | 
					
						
							|  |  |  | 		for (x=0;x< width;x++) { | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 			 index= (x+y*width)*4; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/*	Isolate the intensity */ | 
					
						
							|  |  |  | 			intensity=(in[index+GlowR]+in[index+GlowG]+in[index+GlowB]-threshold); | 
					
						
							|  |  |  | 			if (intensity>0){ | 
					
						
							|  |  |  | 				out[index+GlowR]=MIN2(clamp, (in[index+GlowR]*boost*intensity)); | 
					
						
							|  |  |  | 				out[index+GlowG]=MIN2(clamp, (in[index+GlowG]*boost*intensity)); | 
					
						
							|  |  |  | 				out[index+GlowB]=MIN2(clamp, (in[index+GlowB]*boost*intensity)); | 
					
						
							|  |  |  | 				out[index+GlowA]=MIN2(clamp, (in[index+GlowA]*boost*intensity)); | 
					
						
							|  |  |  | 			} else{ | 
					
						
							|  |  |  | 				out[index+GlowR]=0; | 
					
						
							|  |  |  | 				out[index+GlowG]=0; | 
					
						
							|  |  |  | 				out[index+GlowB]=0; | 
					
						
							|  |  |  | 				out[index+GlowA]=0; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void init_glow_effect(Sequence *seq) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	GlowVars *glow; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(seq->effectdata)MEM_freeN(seq->effectdata); | 
					
						
							|  |  |  | 	seq->effectdata = MEM_callocN(sizeof(struct GlowVars), "glowvars"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	glow = (GlowVars *)seq->effectdata; | 
					
						
							|  |  |  | 	glow->fMini = 0.25; | 
					
						
							|  |  |  | 	glow->fClamp = 1.0; | 
					
						
							|  |  |  | 	glow->fBoost = 0.5; | 
					
						
							|  |  |  | 	glow->dDist = 3.0; | 
					
						
							|  |  |  | 	glow->dQuality = 3; | 
					
						
							|  |  |  | 	glow->bNoComp = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-03 12:30:59 +00:00
										 |  |  | static int num_inputs_glow(void) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void free_glow_effect(Sequence *seq) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if(seq->effectdata)MEM_freeN(seq->effectdata); | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 	seq->effectdata = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void copy_glow_effect(Sequence *dst, Sequence *src) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	dst->effectdata = MEM_dupallocN(src->effectdata); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //void do_glow_effect(Cast *cast, float facf0, float facf1, int xo, int yo, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *outbuf, ImBuf *use)
 | 
					
						
							| 
									
										
										
										
											2010-10-30 15:20:48 +00:00
										 |  |  | static void do_glow_effect_byte(Sequence *seq, int render_size, float facf0, float UNUSED(facf1),  | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 				int x, int y, char *rect1,  | 
					
						
							| 
									
										
										
										
											2010-10-17 06:38:56 +00:00
										 |  |  | 				char *UNUSED(rect2), char *out) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	unsigned char *outbuf=(unsigned char *)out; | 
					
						
							|  |  |  | 	unsigned char *inbuf=(unsigned char *)rect1; | 
					
						
							|  |  |  | 	GlowVars *glow = (GlowVars *)seq->effectdata; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	RVIsolateHighlights_byte(inbuf, outbuf , x, y, glow->fMini*765, glow->fBoost * facf0, glow->fClamp); | 
					
						
							| 
									
										
										
										
											2010-10-30 15:20:48 +00:00
										 |  |  | 	RVBlurBitmap2_byte (outbuf, x, y, glow->dDist * (render_size / 100.0f),glow->dQuality); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	if (!glow->bNoComp) | 
					
						
							|  |  |  | 		RVAddBitmaps_byte (inbuf , outbuf, outbuf, x, y); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-30 15:20:48 +00:00
										 |  |  | static void do_glow_effect_float(Sequence *seq, int render_size, float facf0, float UNUSED(facf1),  | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 				 int x, int y,  | 
					
						
							| 
									
										
										
										
											2010-10-17 06:38:56 +00:00
										 |  |  | 				 float *rect1, float *UNUSED(rect2), float *out) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float *outbuf = out; | 
					
						
							|  |  |  | 	float *inbuf = rect1; | 
					
						
							|  |  |  | 	GlowVars *glow = (GlowVars *)seq->effectdata; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	RVIsolateHighlights_float(inbuf, outbuf , x, y, glow->fMini*3.0f, glow->fBoost * facf0, glow->fClamp); | 
					
						
							| 
									
										
										
										
											2010-10-30 15:20:48 +00:00
										 |  |  | 	RVBlurBitmap2_float (outbuf, x, y, glow->dDist * (render_size / 100.0f),glow->dQuality); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	if (!glow->bNoComp) | 
					
						
							|  |  |  | 		RVAddBitmaps_float (inbuf , outbuf, outbuf, x, y); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | static struct ImBuf * do_glow_effect( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	SeqRenderData context, Sequence *seq, float UNUSED(cfra), | 
					
						
							|  |  |  | 	float facf0, float facf1,  | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	struct ImBuf *ibuf1, struct ImBuf *ibuf2,  | 
					
						
							|  |  |  | 	struct ImBuf *ibuf3) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	struct ImBuf * out = prepare_effect_imbufs(context,ibuf1, ibuf2, ibuf3); | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	int render_size = 100*context.rectx/context.scene->r.xsch; | 
					
						
							| 
									
										
										
										
											2010-11-01 18:55:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	if (out->rect_float) { | 
					
						
							| 
									
										
										
										
											2010-10-30 15:20:48 +00:00
										 |  |  | 		do_glow_effect_float(seq, render_size, | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 				     facf0, facf1,  | 
					
						
							|  |  |  | 				     context.rectx, context.recty, | 
					
						
							|  |  |  | 				     ibuf1->rect_float, ibuf2->rect_float, | 
					
						
							|  |  |  | 				     out->rect_float); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2010-10-30 15:20:48 +00:00
										 |  |  | 		do_glow_effect_byte(seq, render_size, | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 				    facf0, facf1,  | 
					
						
							|  |  |  | 				    context.rectx, context.recty, | 
					
						
							|  |  |  | 				    (char*) ibuf1->rect, (char*) ibuf2->rect, | 
					
						
							|  |  |  | 				    (char*) out->rect); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return out; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* **********************************************************************
 | 
					
						
							|  |  |  |    SOLID COLOR | 
					
						
							|  |  |  |    ********************************************************************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void init_solid_color(Sequence *seq) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	SolidColorVars *cv; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if(seq->effectdata)MEM_freeN(seq->effectdata); | 
					
						
							|  |  |  | 	seq->effectdata = MEM_callocN(sizeof(struct SolidColorVars), "solidcolor"); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	cv = (SolidColorVars *)seq->effectdata; | 
					
						
							|  |  |  | 	cv->col[0] = cv->col[1] = cv->col[2] = 0.5; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-03 12:30:59 +00:00
										 |  |  | static int num_inputs_color(void) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void free_solid_color(Sequence *seq) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if(seq->effectdata)MEM_freeN(seq->effectdata); | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 	seq->effectdata = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void copy_solid_color(Sequence *dst, Sequence *src) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	dst->effectdata = MEM_dupallocN(src->effectdata); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static int early_out_color(struct Sequence *UNUSED(seq), | 
					
						
							|  |  |  | 			   float UNUSED(facf0), float UNUSED(facf1)) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | static struct ImBuf * do_solid_color( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	SeqRenderData context, Sequence *seq, float UNUSED(cfra), | 
					
						
							|  |  |  | 	float facf0, float facf1,  | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	struct ImBuf *ibuf1, struct ImBuf *ibuf2,  | 
					
						
							|  |  |  | 	struct ImBuf *ibuf3) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	struct ImBuf * out = prepare_effect_imbufs(context,ibuf1, ibuf2, ibuf3); | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	SolidColorVars *cv = (SolidColorVars *)seq->effectdata; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	unsigned char *rect; | 
					
						
							|  |  |  | 	float *rect_float; | 
					
						
							| 
									
										
										
										
											2011-01-14 21:45:49 +00:00
										 |  |  | 	int x; /*= context.rectx;*/ /*UNUSED*/ | 
					
						
							|  |  |  | 	int y; /*= context.recty;*/ /*UNUSED*/ | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (out->rect) { | 
					
						
							|  |  |  | 		unsigned char col0[3]; | 
					
						
							|  |  |  | 		unsigned char col1[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		col0[0] = facf0 * cv->col[0] * 255; | 
					
						
							|  |  |  | 		col0[1] = facf0 * cv->col[1] * 255; | 
					
						
							|  |  |  | 		col0[2] = facf0 * cv->col[2] * 255; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		col1[0] = facf1 * cv->col[0] * 255; | 
					
						
							|  |  |  | 		col1[1] = facf1 * cv->col[1] * 255; | 
					
						
							|  |  |  | 		col1[2] = facf1 * cv->col[2] * 255; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		rect = (unsigned char *)out->rect; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		for(y=0; y<out->y; y++) {	 | 
					
						
							|  |  |  | 			for(x=0; x<out->x; x++, rect+=4) { | 
					
						
							|  |  |  | 				rect[0]= col0[0]; | 
					
						
							|  |  |  | 				rect[1]= col0[1]; | 
					
						
							|  |  |  | 				rect[2]= col0[2]; | 
					
						
							|  |  |  | 				rect[3]= 255; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			y++; | 
					
						
							|  |  |  | 			if (y<out->y) { | 
					
						
							|  |  |  | 				for(x=0; x<out->x; x++, rect+=4) { | 
					
						
							|  |  |  | 					rect[0]= col1[0]; | 
					
						
							|  |  |  | 					rect[1]= col1[1]; | 
					
						
							|  |  |  | 					rect[2]= col1[2]; | 
					
						
							|  |  |  | 					rect[3]= 255; | 
					
						
							|  |  |  | 				}	 | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else if (out->rect_float) { | 
					
						
							|  |  |  | 		float col0[3]; | 
					
						
							|  |  |  | 		float col1[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		col0[0] = facf0 * cv->col[0]; | 
					
						
							|  |  |  | 		col0[1] = facf0 * cv->col[1]; | 
					
						
							|  |  |  | 		col0[2] = facf0 * cv->col[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		col1[0] = facf1 * cv->col[0]; | 
					
						
							|  |  |  | 		col1[1] = facf1 * cv->col[1]; | 
					
						
							|  |  |  | 		col1[2] = facf1 * cv->col[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		rect_float = out->rect_float; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		for(y=0; y<out->y; y++) {	 | 
					
						
							|  |  |  | 			for(x=0; x<out->x; x++, rect_float+=4) { | 
					
						
							|  |  |  | 				rect_float[0]= col0[0]; | 
					
						
							|  |  |  | 				rect_float[1]= col0[1]; | 
					
						
							|  |  |  | 				rect_float[2]= col0[2]; | 
					
						
							|  |  |  | 				rect_float[3]= 1.0; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			y++; | 
					
						
							|  |  |  | 			if (y<out->y) { | 
					
						
							|  |  |  | 				for(x=0; x<out->x; x++, rect_float+=4) { | 
					
						
							|  |  |  | 					rect_float[0]= col1[0]; | 
					
						
							|  |  |  | 					rect_float[1]= col1[1]; | 
					
						
							|  |  |  | 					rect_float[2]= col1[2]; | 
					
						
							|  |  |  | 					rect_float[3]= 1.0; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	return out; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												== Sequencer ==
This adds MULTICAM-editing support for blender. (Well, the beginning of.)
There is now a new effect track, named MULTICAM, which just selects
one of the lower tracks.
Doesn't sound that exciting, but if you combine this with A/B-Trim (moving
split points of two directly connected tracks around, while magically
resizing both strips, something to be added), you just do:
* add several tracks for your camera angles
* (optionally) sync those tracks
* add one multicam track on top
Use that multicam-track to edit your movie. (Either using fcurves on the
multicam source selector or using knife-tool and A/B-Trim.)
Compare that to:
* add several tracks
* add cross fades between them
* do some python scripting to add several fcurves to make that beast
  somewhat work.
* cry out loud, using it, if you have to move cut points around
Alternatively, even harder:
* just edit the old way and put strip after strip
You might think, that this isn't really helpfull for animators, but
consider using scene-strips (in OpenGL-mode) for input, that are set for
different camera angles and can now be intercut a lot more easily...
Also: small fix on the way: the speed effect can now be used in cascade.
(Don't know, if anyone used it that way, but now it works.)
											
										 
											2010-04-25 12:53:39 +00:00
										 |  |  | /* **********************************************************************
 | 
					
						
							|  |  |  |    MULTICAM | 
					
						
							|  |  |  |    ********************************************************************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* no effect inputs for multicam, we use give_ibuf_seq */ | 
					
						
							| 
									
										
										
										
											2010-12-03 12:30:59 +00:00
										 |  |  | static int num_inputs_multicam(void) | 
					
						
							| 
									
										
											  
											
												== Sequencer ==
This adds MULTICAM-editing support for blender. (Well, the beginning of.)
There is now a new effect track, named MULTICAM, which just selects
one of the lower tracks.
Doesn't sound that exciting, but if you combine this with A/B-Trim (moving
split points of two directly connected tracks around, while magically
resizing both strips, something to be added), you just do:
* add several tracks for your camera angles
* (optionally) sync those tracks
* add one multicam track on top
Use that multicam-track to edit your movie. (Either using fcurves on the
multicam source selector or using knife-tool and A/B-Trim.)
Compare that to:
* add several tracks
* add cross fades between them
* do some python scripting to add several fcurves to make that beast
  somewhat work.
* cry out loud, using it, if you have to move cut points around
Alternatively, even harder:
* just edit the old way and put strip after strip
You might think, that this isn't really helpfull for animators, but
consider using scene-strips (in OpenGL-mode) for input, that are set for
different camera angles and can now be intercut a lot more easily...
Also: small fix on the way: the speed effect can now be used in cascade.
(Don't know, if anyone used it that way, but now it works.)
											
										 
											2010-04-25 12:53:39 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static int early_out_multicam(struct Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1)) | 
					
						
							| 
									
										
											  
											
												== Sequencer ==
This adds MULTICAM-editing support for blender. (Well, the beginning of.)
There is now a new effect track, named MULTICAM, which just selects
one of the lower tracks.
Doesn't sound that exciting, but if you combine this with A/B-Trim (moving
split points of two directly connected tracks around, while magically
resizing both strips, something to be added), you just do:
* add several tracks for your camera angles
* (optionally) sync those tracks
* add one multicam track on top
Use that multicam-track to edit your movie. (Either using fcurves on the
multicam source selector or using knife-tool and A/B-Trim.)
Compare that to:
* add several tracks
* add cross fades between them
* do some python scripting to add several fcurves to make that beast
  somewhat work.
* cry out loud, using it, if you have to move cut points around
Alternatively, even harder:
* just edit the old way and put strip after strip
You might think, that this isn't really helpfull for animators, but
consider using scene-strips (in OpenGL-mode) for input, that are set for
different camera angles and can now be intercut a lot more easily...
Also: small fix on the way: the speed effect can now be used in cascade.
(Don't know, if anyone used it that way, but now it works.)
											
										 
											2010-04-25 12:53:39 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | static struct ImBuf * do_multicam( | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	SeqRenderData context, Sequence *seq, float cfra, | 
					
						
							|  |  |  | 	float UNUSED(facf0), float UNUSED(facf1), | 
					
						
							| 
									
										
										
										
											2010-10-17 06:38:56 +00:00
										 |  |  | 	struct ImBuf *UNUSED(ibuf1), struct ImBuf *UNUSED(ibuf2),  | 
					
						
							|  |  |  | 	struct ImBuf *UNUSED(ibuf3)) | 
					
						
							| 
									
										
											  
											
												== Sequencer ==
This adds MULTICAM-editing support for blender. (Well, the beginning of.)
There is now a new effect track, named MULTICAM, which just selects
one of the lower tracks.
Doesn't sound that exciting, but if you combine this with A/B-Trim (moving
split points of two directly connected tracks around, while magically
resizing both strips, something to be added), you just do:
* add several tracks for your camera angles
* (optionally) sync those tracks
* add one multicam track on top
Use that multicam-track to edit your movie. (Either using fcurves on the
multicam source selector or using knife-tool and A/B-Trim.)
Compare that to:
* add several tracks
* add cross fades between them
* do some python scripting to add several fcurves to make that beast
  somewhat work.
* cry out loud, using it, if you have to move cut points around
Alternatively, even harder:
* just edit the old way and put strip after strip
You might think, that this isn't really helpfull for animators, but
consider using scene-strips (in OpenGL-mode) for input, that are set for
different camera angles and can now be intercut a lot more easily...
Also: small fix on the way: the speed effect can now be used in cascade.
(Don't know, if anyone used it that way, but now it works.)
											
										 
											2010-04-25 12:53:39 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct ImBuf * i; | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	struct ImBuf * out; | 
					
						
							| 
									
										
											  
											
												== Sequencer ==
This adds MULTICAM-editing support for blender. (Well, the beginning of.)
There is now a new effect track, named MULTICAM, which just selects
one of the lower tracks.
Doesn't sound that exciting, but if you combine this with A/B-Trim (moving
split points of two directly connected tracks around, while magically
resizing both strips, something to be added), you just do:
* add several tracks for your camera angles
* (optionally) sync those tracks
* add one multicam track on top
Use that multicam-track to edit your movie. (Either using fcurves on the
multicam source selector or using knife-tool and A/B-Trim.)
Compare that to:
* add several tracks
* add cross fades between them
* do some python scripting to add several fcurves to make that beast
  somewhat work.
* cry out loud, using it, if you have to move cut points around
Alternatively, even harder:
* just edit the old way and put strip after strip
You might think, that this isn't really helpfull for animators, but
consider using scene-strips (in OpenGL-mode) for input, that are set for
different camera angles and can now be intercut a lot more easily...
Also: small fix on the way: the speed effect can now be used in cascade.
(Don't know, if anyone used it that way, but now it works.)
											
										 
											2010-04-25 12:53:39 +00:00
										 |  |  | 	Editing * ed; | 
					
						
							|  |  |  | 	ListBase * seqbasep; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (seq->multicam_source == 0 || seq->multicam_source >= seq->machine) { | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
											  
											
												== Sequencer ==
This adds MULTICAM-editing support for blender. (Well, the beginning of.)
There is now a new effect track, named MULTICAM, which just selects
one of the lower tracks.
Doesn't sound that exciting, but if you combine this with A/B-Trim (moving
split points of two directly connected tracks around, while magically
resizing both strips, something to be added), you just do:
* add several tracks for your camera angles
* (optionally) sync those tracks
* add one multicam track on top
Use that multicam-track to edit your movie. (Either using fcurves on the
multicam source selector or using knife-tool and A/B-Trim.)
Compare that to:
* add several tracks
* add cross fades between them
* do some python scripting to add several fcurves to make that beast
  somewhat work.
* cry out loud, using it, if you have to move cut points around
Alternatively, even harder:
* just edit the old way and put strip after strip
You might think, that this isn't really helpfull for animators, but
consider using scene-strips (in OpenGL-mode) for input, that are set for
different camera angles and can now be intercut a lot more easily...
Also: small fix on the way: the speed effect can now be used in cascade.
(Don't know, if anyone used it that way, but now it works.)
											
										 
											2010-04-25 12:53:39 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	ed = context.scene->ed; | 
					
						
							| 
									
										
											  
											
												== Sequencer ==
This adds MULTICAM-editing support for blender. (Well, the beginning of.)
There is now a new effect track, named MULTICAM, which just selects
one of the lower tracks.
Doesn't sound that exciting, but if you combine this with A/B-Trim (moving
split points of two directly connected tracks around, while magically
resizing both strips, something to be added), you just do:
* add several tracks for your camera angles
* (optionally) sync those tracks
* add one multicam track on top
Use that multicam-track to edit your movie. (Either using fcurves on the
multicam source selector or using knife-tool and A/B-Trim.)
Compare that to:
* add several tracks
* add cross fades between them
* do some python scripting to add several fcurves to make that beast
  somewhat work.
* cry out loud, using it, if you have to move cut points around
Alternatively, even harder:
* just edit the old way and put strip after strip
You might think, that this isn't really helpfull for animators, but
consider using scene-strips (in OpenGL-mode) for input, that are set for
different camera angles and can now be intercut a lot more easily...
Also: small fix on the way: the speed effect can now be used in cascade.
(Don't know, if anyone used it that way, but now it works.)
											
										 
											2010-04-25 12:53:39 +00:00
										 |  |  | 	if (!ed) { | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
											  
											
												== Sequencer ==
This adds MULTICAM-editing support for blender. (Well, the beginning of.)
There is now a new effect track, named MULTICAM, which just selects
one of the lower tracks.
Doesn't sound that exciting, but if you combine this with A/B-Trim (moving
split points of two directly connected tracks around, while magically
resizing both strips, something to be added), you just do:
* add several tracks for your camera angles
* (optionally) sync those tracks
* add one multicam track on top
Use that multicam-track to edit your movie. (Either using fcurves on the
multicam source selector or using knife-tool and A/B-Trim.)
Compare that to:
* add several tracks
* add cross fades between them
* do some python scripting to add several fcurves to make that beast
  somewhat work.
* cry out loud, using it, if you have to move cut points around
Alternatively, even harder:
* just edit the old way and put strip after strip
You might think, that this isn't really helpfull for animators, but
consider using scene-strips (in OpenGL-mode) for input, that are set for
different camera angles and can now be intercut a lot more easily...
Also: small fix on the way: the speed effect can now be used in cascade.
(Don't know, if anyone used it that way, but now it works.)
											
										 
											2010-04-25 12:53:39 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	seqbasep = seq_seqbase(&ed->seqbase, seq); | 
					
						
							|  |  |  | 	if (!seqbasep) { | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
											  
											
												== Sequencer ==
This adds MULTICAM-editing support for blender. (Well, the beginning of.)
There is now a new effect track, named MULTICAM, which just selects
one of the lower tracks.
Doesn't sound that exciting, but if you combine this with A/B-Trim (moving
split points of two directly connected tracks around, while magically
resizing both strips, something to be added), you just do:
* add several tracks for your camera angles
* (optionally) sync those tracks
* add one multicam track on top
Use that multicam-track to edit your movie. (Either using fcurves on the
multicam source selector or using knife-tool and A/B-Trim.)
Compare that to:
* add several tracks
* add cross fades between them
* do some python scripting to add several fcurves to make that beast
  somewhat work.
* cry out loud, using it, if you have to move cut points around
Alternatively, even harder:
* just edit the old way and put strip after strip
You might think, that this isn't really helpfull for animators, but
consider using scene-strips (in OpenGL-mode) for input, that are set for
different camera angles and can now be intercut a lot more easily...
Also: small fix on the way: the speed effect can now be used in cascade.
(Don't know, if anyone used it that way, but now it works.)
											
										 
											2010-04-25 12:53:39 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	i = give_ibuf_seqbase(context, cfra, seq->multicam_source, seqbasep); | 
					
						
							| 
									
										
											  
											
												== Sequencer ==
This adds MULTICAM-editing support for blender. (Well, the beginning of.)
There is now a new effect track, named MULTICAM, which just selects
one of the lower tracks.
Doesn't sound that exciting, but if you combine this with A/B-Trim (moving
split points of two directly connected tracks around, while magically
resizing both strips, something to be added), you just do:
* add several tracks for your camera angles
* (optionally) sync those tracks
* add one multicam track on top
Use that multicam-track to edit your movie. (Either using fcurves on the
multicam source selector or using knife-tool and A/B-Trim.)
Compare that to:
* add several tracks
* add cross fades between them
* do some python scripting to add several fcurves to make that beast
  somewhat work.
* cry out loud, using it, if you have to move cut points around
Alternatively, even harder:
* just edit the old way and put strip after strip
You might think, that this isn't really helpfull for animators, but
consider using scene-strips (in OpenGL-mode) for input, that are set for
different camera angles and can now be intercut a lot more easily...
Also: small fix on the way: the speed effect can now be used in cascade.
(Don't know, if anyone used it that way, but now it works.)
											
										 
											2010-04-25 12:53:39 +00:00
										 |  |  | 	if (!i) { | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
											  
											
												== Sequencer ==
This adds MULTICAM-editing support for blender. (Well, the beginning of.)
There is now a new effect track, named MULTICAM, which just selects
one of the lower tracks.
Doesn't sound that exciting, but if you combine this with A/B-Trim (moving
split points of two directly connected tracks around, while magically
resizing both strips, something to be added), you just do:
* add several tracks for your camera angles
* (optionally) sync those tracks
* add one multicam track on top
Use that multicam-track to edit your movie. (Either using fcurves on the
multicam source selector or using knife-tool and A/B-Trim.)
Compare that to:
* add several tracks
* add cross fades between them
* do some python scripting to add several fcurves to make that beast
  somewhat work.
* cry out loud, using it, if you have to move cut points around
Alternatively, even harder:
* just edit the old way and put strip after strip
You might think, that this isn't really helpfull for animators, but
consider using scene-strips (in OpenGL-mode) for input, that are set for
different camera angles and can now be intercut a lot more easily...
Also: small fix on the way: the speed effect can now be used in cascade.
(Don't know, if anyone used it that way, but now it works.)
											
										 
											2010-04-25 12:53:39 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	if (input_have_to_preprocess(context, seq, cfra)) { | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 		out = IMB_dupImBuf(i); | 
					
						
							|  |  |  | 		IMB_freeImBuf(i); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		out = i; | 
					
						
							| 
									
										
											  
											
												== Sequencer ==
This adds MULTICAM-editing support for blender. (Well, the beginning of.)
There is now a new effect track, named MULTICAM, which just selects
one of the lower tracks.
Doesn't sound that exciting, but if you combine this with A/B-Trim (moving
split points of two directly connected tracks around, while magically
resizing both strips, something to be added), you just do:
* add several tracks for your camera angles
* (optionally) sync those tracks
* add one multicam track on top
Use that multicam-track to edit your movie. (Either using fcurves on the
multicam source selector or using knife-tool and A/B-Trim.)
Compare that to:
* add several tracks
* add cross fades between them
* do some python scripting to add several fcurves to make that beast
  somewhat work.
* cry out loud, using it, if you have to move cut points around
Alternatively, even harder:
* just edit the old way and put strip after strip
You might think, that this isn't really helpfull for animators, but
consider using scene-strips (in OpenGL-mode) for input, that are set for
different camera angles and can now be intercut a lot more easily...
Also: small fix on the way: the speed effect can now be used in cascade.
(Don't know, if anyone used it that way, but now it works.)
											
										 
											2010-04-25 12:53:39 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	return out; | 
					
						
							| 
									
										
											  
											
												== Sequencer ==
This adds MULTICAM-editing support for blender. (Well, the beginning of.)
There is now a new effect track, named MULTICAM, which just selects
one of the lower tracks.
Doesn't sound that exciting, but if you combine this with A/B-Trim (moving
split points of two directly connected tracks around, while magically
resizing both strips, something to be added), you just do:
* add several tracks for your camera angles
* (optionally) sync those tracks
* add one multicam track on top
Use that multicam-track to edit your movie. (Either using fcurves on the
multicam source selector or using knife-tool and A/B-Trim.)
Compare that to:
* add several tracks
* add cross fades between them
* do some python scripting to add several fcurves to make that beast
  somewhat work.
* cry out loud, using it, if you have to move cut points around
Alternatively, even harder:
* just edit the old way and put strip after strip
You might think, that this isn't really helpfull for animators, but
consider using scene-strips (in OpenGL-mode) for input, that are set for
different camera angles and can now be intercut a lot more easily...
Also: small fix on the way: the speed effect can now be used in cascade.
(Don't know, if anyone used it that way, but now it works.)
											
										 
											2010-04-25 12:53:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | /* **********************************************************************
 | 
					
						
							|  |  |  |    SPEED | 
					
						
							|  |  |  |    ********************************************************************** */ | 
					
						
							|  |  |  | static void init_speed_effect(Sequence *seq) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	SpeedControlVars * v; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(seq->effectdata) MEM_freeN(seq->effectdata); | 
					
						
							|  |  |  | 	seq->effectdata = MEM_callocN(sizeof(struct SpeedControlVars),  | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 					  "speedcontrolvars"); | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	v = (SpeedControlVars *)seq->effectdata; | 
					
						
							|  |  |  | 	v->globalSpeed = 1.0; | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 	v->frameMap = NULL; | 
					
						
							| 
									
										
										
										
											2010-09-29 13:38:43 +00:00
										 |  |  | 	v->flags |= SEQ_SPEED_INTEGRATE; /* should be default behavior */ | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	v->length = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void load_speed_effect(Sequence * seq) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	SpeedControlVars * v = (SpeedControlVars *)seq->effectdata; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 	v->frameMap = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	v->length = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-03 12:30:59 +00:00
										 |  |  | static int num_inputs_speed(void) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void free_speed_effect(Sequence *seq) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	SpeedControlVars * v = (SpeedControlVars *)seq->effectdata; | 
					
						
							|  |  |  | 	if(v->frameMap) MEM_freeN(v->frameMap); | 
					
						
							|  |  |  | 	if(seq->effectdata) MEM_freeN(seq->effectdata); | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 	seq->effectdata = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void copy_speed_effect(Sequence *dst, Sequence *src) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	SpeedControlVars * v; | 
					
						
							|  |  |  | 	dst->effectdata = MEM_dupallocN(src->effectdata); | 
					
						
							|  |  |  | 	v = (SpeedControlVars *)dst->effectdata; | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 	v->frameMap = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	v->length = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static int early_out_speed(struct Sequence *UNUSED(seq), | 
					
						
							|  |  |  | 			  float UNUSED(facf0), float UNUSED(facf1)) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void store_icu_yrange_speed(struct Sequence * seq, | 
					
						
							| 
									
										
										
										
											2010-10-17 06:38:56 +00:00
										 |  |  | 				   short UNUSED(adrcode), float * ymin, float * ymax) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	SpeedControlVars * v = (SpeedControlVars *)seq->effectdata; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* if not already done, load / initialize data */ | 
					
						
							|  |  |  | 	get_sequence_effect(seq); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((v->flags & SEQ_SPEED_INTEGRATE) != 0) { | 
					
						
							|  |  |  | 		*ymin = -100.0; | 
					
						
							|  |  |  | 		*ymax = 100.0; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) { | 
					
						
							|  |  |  | 			*ymin = 0.0; | 
					
						
							|  |  |  | 			*ymax = 1.0; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			*ymin = 0.0; | 
					
						
							|  |  |  | 			*ymax = seq->len; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}	 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-11-14 14:58:19 +00:00
										 |  |  | void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int cfra; | 
					
						
							| 
									
										
										
										
											2010-09-29 13:38:43 +00:00
										 |  |  | 	float fallback_fac = 1.0f; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	SpeedControlVars * v = (SpeedControlVars *)seq->effectdata; | 
					
						
							| 
									
										
										
										
											2009-11-14 14:58:19 +00:00
										 |  |  | 	FCurve *fcu= NULL; | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	int flags = v->flags; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* if not already done, load / initialize data */ | 
					
						
							|  |  |  | 	get_sequence_effect(seq); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!(force || seq->len != v->length || !v->frameMap)) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-08-19 09:35:22 +00:00
										 |  |  | 	if (!seq->seq1) { /* make coverity happy and check for (CID 598)
 | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 						 input strip ... */ | 
					
						
							| 
									
										
										
										
											2009-08-19 09:35:22 +00:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-14 14:58:19 +00:00
										 |  |  | 	/* XXX - new in 2.5x. should we use the animation system this way?
 | 
					
						
							|  |  |  | 	 * The fcurve is needed because many frames need evaluating at once - campbell */ | 
					
						
							| 
									
										
										
										
											2010-09-29 13:38:43 +00:00
										 |  |  | 	fcu= id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0); | 
					
						
							| 
									
										
										
										
											2009-11-14 14:58:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	if (!v->frameMap || v->length != seq->len) { | 
					
						
							|  |  |  | 		if (v->frameMap) MEM_freeN(v->frameMap); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		v->length = seq->len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		v->frameMap = MEM_callocN(sizeof(float) * v->length,  | 
					
						
							|  |  |  | 					  "speedcontrol frameMap"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	fallback_fac = 1.0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) { | 
					
						
							|  |  |  | 		if (seq->seq1->enddisp != seq->seq1->start | 
					
						
							|  |  |  | 		    && seq->seq1->len != 0) { | 
					
						
							|  |  |  | 			fallback_fac = (float) seq->seq1->len /  | 
					
						
							|  |  |  | 				(float) (seq->seq1->enddisp - seq->seq1->start); | 
					
						
							|  |  |  | 			flags = SEQ_SPEED_INTEGRATE; | 
					
						
							|  |  |  | 			fcu = NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		/* if there is no fcurve, use value as simple multiplier */ | 
					
						
							|  |  |  | 		if (!fcu) { | 
					
						
							|  |  |  | 			fallback_fac = seq->speed_fader; /* same as speed_factor in rna*/ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (flags & SEQ_SPEED_INTEGRATE) { | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 		float cursor = 0; | 
					
						
							| 
									
										
										
										
											2009-11-22 20:22:35 +00:00
										 |  |  | 		float facf; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		v->frameMap[0] = 0; | 
					
						
							|  |  |  | 		v->lastValidFrame = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (cfra = 1; cfra < v->length; cfra++) { | 
					
						
							| 
									
										
										
										
											2009-11-14 14:58:19 +00:00
										 |  |  | 			if(fcu) { | 
					
						
							| 
									
										
										
										
											2010-09-29 13:38:43 +00:00
										 |  |  | 				facf = evaluate_fcurve(fcu, seq->startdisp + cfra); | 
					
						
							| 
									
										
										
										
											2009-11-22 20:22:35 +00:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				facf = fallback_fac; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-11-22 20:22:35 +00:00
										 |  |  | 			facf *= v->globalSpeed; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-22 20:22:35 +00:00
										 |  |  | 			cursor += facf; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-08 13:55:30 +00:00
										 |  |  | 			if (cursor >= seq->seq1->len) { | 
					
						
							|  |  |  | 				v->frameMap[cfra] = seq->seq1->len - 1; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				v->frameMap[cfra] = cursor; | 
					
						
							|  |  |  | 				v->lastValidFrame = cfra; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2009-11-22 20:22:35 +00:00
										 |  |  | 		float facf; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 		v->lastValidFrame = 0; | 
					
						
							|  |  |  | 		for (cfra = 0; cfra < v->length; cfra++) { | 
					
						
							| 
									
										
										
										
											2009-11-14 14:58:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if(fcu) { | 
					
						
							| 
									
										
										
										
											2010-09-29 13:38:43 +00:00
										 |  |  | 				facf = evaluate_fcurve(fcu, seq->startdisp + cfra); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				facf = fallback_fac; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2010-09-29 13:38:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 			if (flags & SEQ_SPEED_COMPRESS_IPO_Y) { | 
					
						
							| 
									
										
										
										
											2010-09-30 09:34:22 +00:00
										 |  |  | 				facf *= seq->seq1->len; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-11-22 20:22:35 +00:00
										 |  |  | 			facf *= v->globalSpeed; | 
					
						
							| 
									
										
										
										
											2010-09-29 13:38:43 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2010-08-08 13:55:30 +00:00
										 |  |  | 			if (facf >= seq->seq1->len) { | 
					
						
							|  |  |  | 				facf = seq->seq1->len - 1; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				v->lastValidFrame = cfra; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-11-22 20:22:35 +00:00
										 |  |  | 			v->frameMap[cfra] = facf; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* **********************************************************************
 | 
					
						
							|  |  |  |    sequence effect factory | 
					
						
							|  |  |  |    ********************************************************************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static void init_noop(struct Sequence *UNUSED(seq)) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static void load_noop(struct Sequence *UNUSED(seq)) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static void init_plugin_noop(struct Sequence *UNUSED(seq), const char *UNUSED(fname)) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static void free_noop(struct Sequence *UNUSED(seq)) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-03 12:30:59 +00:00
										 |  |  | static int num_inputs_default(void) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return 2; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static int early_out_noop(struct Sequence *UNUSED(seq), | 
					
						
							|  |  |  | 			  float UNUSED(facf0), float UNUSED(facf1)) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static int early_out_fade(struct Sequence *UNUSED(seq), | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 			  float facf0, float facf1) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (facf0 == 0.0 && facf1 == 0.0) { | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 	} else if (facf0 == 1.0 && facf1 == 1.0) { | 
					
						
							|  |  |  | 		return 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static int early_out_mul_input2(struct Sequence *UNUSED(seq), | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 				float facf0, float facf1) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (facf0 == 0.0 && facf1 == 0.0) { | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static void store_icu_yrange_noop(struct Sequence * UNUSED(seq), | 
					
						
							| 
									
										
										
										
											2010-10-17 06:38:56 +00:00
										 |  |  | 				  short UNUSED(adrcode), float *UNUSED(ymin), float *UNUSED(ymax)) | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* defaults are fine */ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static void get_default_fac_noop(struct Sequence *UNUSED(seq), float UNUSED(cfra), | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 				 float * facf0, float * facf1) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	*facf0 = *facf1 = 1.0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | static void get_default_fac_fade(struct Sequence *seq, float cfra, | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 				 float * facf0, float * facf1) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	*facf0 = (float)(cfra - seq->startdisp); | 
					
						
							|  |  |  | 	*facf1 = (float)(*facf0 + 0.5); | 
					
						
							|  |  |  | 	*facf0 /= seq->len; | 
					
						
							|  |  |  | 	*facf1 /= seq->len; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | static struct ImBuf * do_overdrop_effect(SeqRenderData context,  | 
					
						
							|  |  |  | 					 Sequence *UNUSED(seq),  | 
					
						
							|  |  |  | 					 float UNUSED(cfra), | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 					 float facf0, float facf1,  | 
					
						
							|  |  |  | 					 struct ImBuf * ibuf1,  | 
					
						
							|  |  |  | 					 struct ImBuf * ibuf2,  | 
					
						
							|  |  |  | 					 struct ImBuf * ibuf3) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-11-21 20:00:31 +00:00
										 |  |  | 	struct ImBuf * out = prepare_effect_imbufs(context,ibuf1, ibuf2, ibuf3); | 
					
						
							|  |  |  | 	int x = context.rectx; | 
					
						
							|  |  |  | 	int y = context.recty; | 
					
						
							| 
									
										
										
										
											2010-07-25 17:19:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (out->rect_float) { | 
					
						
							|  |  |  | 		do_drop_effect_float( | 
					
						
							|  |  |  | 			facf0, facf1, x, y, | 
					
						
							|  |  |  | 			ibuf1->rect_float, ibuf2->rect_float, | 
					
						
							|  |  |  | 			out->rect_float); | 
					
						
							|  |  |  | 		do_alphaover_effect_float( | 
					
						
							|  |  |  | 			facf0, facf1, x, y, | 
					
						
							|  |  |  | 			ibuf1->rect_float, ibuf2->rect_float, | 
					
						
							|  |  |  | 			out->rect_float); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		do_drop_effect_byte( | 
					
						
							|  |  |  | 			facf0, facf1, x, y, | 
					
						
							|  |  |  | 			(char*) ibuf1->rect,  | 
					
						
							|  |  |  | 			(char*) ibuf2->rect, | 
					
						
							|  |  |  | 			(char*) out->rect); | 
					
						
							|  |  |  | 		do_alphaover_effect_byte( | 
					
						
							|  |  |  | 			facf0, facf1, x, y, | 
					
						
							|  |  |  | 			(char*) ibuf1->rect, (char*) ibuf2->rect, | 
					
						
							|  |  |  | 			(char*) out->rect); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return out; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct SeqEffectHandle get_sequence_effect_impl(int seq_type) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct SeqEffectHandle rval; | 
					
						
							|  |  |  | 	int sequence_type = seq_type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rval.init = init_noop; | 
					
						
							|  |  |  | 	rval.init_plugin = init_plugin_noop; | 
					
						
							|  |  |  | 	rval.num_inputs = num_inputs_default; | 
					
						
							|  |  |  | 	rval.load = load_noop; | 
					
						
							|  |  |  | 	rval.free = free_noop; | 
					
						
							|  |  |  | 	rval.early_out = early_out_noop; | 
					
						
							|  |  |  | 	rval.get_default_fac = get_default_fac_noop; | 
					
						
							|  |  |  | 	rval.store_icu_yrange = store_icu_yrange_noop; | 
					
						
							|  |  |  | 	rval.execute = NULL; | 
					
						
							|  |  |  | 	rval.copy = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (sequence_type) { | 
					
						
							|  |  |  | 	case SEQ_CROSS: | 
					
						
							|  |  |  | 		rval.execute = do_cross_effect; | 
					
						
							|  |  |  | 		rval.early_out = early_out_fade; | 
					
						
							|  |  |  | 		rval.get_default_fac = get_default_fac_fade; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SEQ_GAMCROSS: | 
					
						
							|  |  |  | 		rval.init = init_gammacross; | 
					
						
							|  |  |  | 		rval.load = load_gammacross; | 
					
						
							|  |  |  | 		rval.free = free_gammacross; | 
					
						
							|  |  |  | 		rval.early_out = early_out_fade; | 
					
						
							|  |  |  | 		rval.get_default_fac = get_default_fac_fade; | 
					
						
							|  |  |  | 		rval.execute = do_gammacross_effect; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SEQ_ADD: | 
					
						
							|  |  |  | 		rval.execute = do_add_effect; | 
					
						
							|  |  |  | 		rval.early_out = early_out_mul_input2; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SEQ_SUB: | 
					
						
							|  |  |  | 		rval.execute = do_sub_effect; | 
					
						
							|  |  |  | 		rval.early_out = early_out_mul_input2; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SEQ_MUL: | 
					
						
							|  |  |  | 		rval.execute = do_mul_effect; | 
					
						
							|  |  |  | 		rval.early_out = early_out_mul_input2; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SEQ_ALPHAOVER: | 
					
						
							|  |  |  | 		rval.init = init_alpha_over_or_under; | 
					
						
							|  |  |  | 		rval.execute = do_alphaover_effect; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SEQ_OVERDROP: | 
					
						
							|  |  |  | 		rval.execute = do_overdrop_effect; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SEQ_ALPHAUNDER: | 
					
						
							|  |  |  | 		rval.init = init_alpha_over_or_under; | 
					
						
							|  |  |  | 		rval.execute = do_alphaunder_effect; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SEQ_WIPE: | 
					
						
							|  |  |  | 		rval.init = init_wipe_effect; | 
					
						
							|  |  |  | 		rval.num_inputs = num_inputs_wipe; | 
					
						
							|  |  |  | 		rval.free = free_wipe_effect; | 
					
						
							|  |  |  | 		rval.copy = copy_wipe_effect; | 
					
						
							|  |  |  | 		rval.early_out = early_out_fade; | 
					
						
							|  |  |  | 		rval.get_default_fac = get_default_fac_fade; | 
					
						
							|  |  |  | 		rval.execute = do_wipe_effect; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SEQ_GLOW: | 
					
						
							|  |  |  | 		rval.init = init_glow_effect; | 
					
						
							|  |  |  | 		rval.num_inputs = num_inputs_glow; | 
					
						
							|  |  |  | 		rval.free = free_glow_effect; | 
					
						
							|  |  |  | 		rval.copy = copy_glow_effect; | 
					
						
							|  |  |  | 		rval.execute = do_glow_effect; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SEQ_TRANSFORM: | 
					
						
							|  |  |  | 		rval.init = init_transform_effect; | 
					
						
							|  |  |  | 		rval.num_inputs = num_inputs_transform; | 
					
						
							|  |  |  | 		rval.free = free_transform_effect; | 
					
						
							|  |  |  | 		rval.copy = copy_transform_effect; | 
					
						
							|  |  |  | 		rval.execute = do_transform_effect; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SEQ_SPEED: | 
					
						
							|  |  |  | 		rval.init = init_speed_effect; | 
					
						
							|  |  |  | 		rval.num_inputs = num_inputs_speed; | 
					
						
							|  |  |  | 		rval.load = load_speed_effect; | 
					
						
							|  |  |  | 		rval.free = free_speed_effect; | 
					
						
							|  |  |  | 		rval.copy = copy_speed_effect; | 
					
						
							|  |  |  | 		rval.execute = do_cross_effect; | 
					
						
							|  |  |  | 		rval.early_out = early_out_speed; | 
					
						
							|  |  |  | 		rval.store_icu_yrange = store_icu_yrange_speed; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SEQ_COLOR: | 
					
						
							|  |  |  | 		rval.init = init_solid_color; | 
					
						
							|  |  |  | 		rval.num_inputs = num_inputs_color; | 
					
						
							|  |  |  | 		rval.early_out = early_out_color; | 
					
						
							|  |  |  | 		rval.free = free_solid_color; | 
					
						
							|  |  |  | 		rval.copy = copy_solid_color; | 
					
						
							|  |  |  | 		rval.execute = do_solid_color; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SEQ_PLUGIN: | 
					
						
							|  |  |  | 		rval.init_plugin = init_plugin; | 
					
						
							|  |  |  | 		rval.num_inputs = num_inputs_plugin; | 
					
						
							|  |  |  | 		rval.load = load_plugin; | 
					
						
							|  |  |  | 		rval.free = free_plugin; | 
					
						
							|  |  |  | 		rval.copy = copy_plugin; | 
					
						
							|  |  |  | 		rval.execute = do_plugin_effect; | 
					
						
							|  |  |  | 		rval.early_out = do_plugin_early_out; | 
					
						
							|  |  |  | 		rval.get_default_fac = get_default_fac_fade; | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
											  
											
												== Sequencer ==
This adds MULTICAM-editing support for blender. (Well, the beginning of.)
There is now a new effect track, named MULTICAM, which just selects
one of the lower tracks.
Doesn't sound that exciting, but if you combine this with A/B-Trim (moving
split points of two directly connected tracks around, while magically
resizing both strips, something to be added), you just do:
* add several tracks for your camera angles
* (optionally) sync those tracks
* add one multicam track on top
Use that multicam-track to edit your movie. (Either using fcurves on the
multicam source selector or using knife-tool and A/B-Trim.)
Compare that to:
* add several tracks
* add cross fades between them
* do some python scripting to add several fcurves to make that beast
  somewhat work.
* cry out loud, using it, if you have to move cut points around
Alternatively, even harder:
* just edit the old way and put strip after strip
You might think, that this isn't really helpfull for animators, but
consider using scene-strips (in OpenGL-mode) for input, that are set for
different camera angles and can now be intercut a lot more easily...
Also: small fix on the way: the speed effect can now be used in cascade.
(Don't know, if anyone used it that way, but now it works.)
											
										 
											2010-04-25 12:53:39 +00:00
										 |  |  | 	case SEQ_MULTICAM: | 
					
						
							|  |  |  | 		rval.num_inputs = num_inputs_multicam; | 
					
						
							|  |  |  | 		rval.early_out = early_out_multicam; | 
					
						
							|  |  |  | 		rval.execute = do_multicam; | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return rval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct SeqEffectHandle get_sequence_effect(Sequence * seq) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 	struct SeqEffectHandle rval= {NULL}; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (seq->type & SEQ_EFFECT) { | 
					
						
							|  |  |  | 		rval = get_sequence_effect_impl(seq->type); | 
					
						
							|  |  |  | 		if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) { | 
					
						
							|  |  |  | 			rval.load(seq); | 
					
						
							|  |  |  | 			seq->flag &= ~SEQ_EFFECT_NOT_LOADED; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return rval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct SeqEffectHandle get_sequence_blend(Sequence * seq) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 	struct SeqEffectHandle rval= {NULL}; | 
					
						
							| 
									
										
										
										
											2009-01-12 19:02:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (seq->blend_mode != 0) { | 
					
						
							|  |  |  | 		rval = get_sequence_effect_impl(seq->blend_mode); | 
					
						
							|  |  |  | 		if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) { | 
					
						
							|  |  |  | 			rval.load(seq); | 
					
						
							|  |  |  | 			seq->flag &= ~SEQ_EFFECT_NOT_LOADED; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return rval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int get_sequence_effect_num_inputs(int seq_type) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct SeqEffectHandle rval = get_sequence_effect_impl(seq_type); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int cnt = rval.num_inputs(); | 
					
						
							|  |  |  | 	if (rval.execute) { | 
					
						
							|  |  |  | 		return cnt; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } |