diff options
Diffstat (limited to 'source/blender/src/seqeffects.c')
-rw-r--r-- | source/blender/src/seqeffects.c | 3139 |
1 files changed, 0 insertions, 3139 deletions
diff --git a/source/blender/src/seqeffects.c b/source/blender/src/seqeffects.c deleted file mode 100644 index 05aff70dedf..00000000000 --- a/source/blender/src/seqeffects.c +++ /dev/null @@ -1,3139 +0,0 @@ -/** - * $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, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * Contributor(s): Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006 - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include <string.h> -#include <math.h> -#include <stdlib.h> - -#include "MEM_guardedalloc.h" -#include "PIL_dynlib.h" - -#include "DNA_scene_types.h" -#include "DNA_sequence_types.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" - -#include "BIF_interface.h" -#include "BIF_toolbox.h" - -#include "BSE_seqeffects.h" -#include "BSE_sequence.h" - -#include "BKE_global.h" -#include "BKE_ipo.h" -#include "BKE_plugin_types.h" -#include "BKE_texture.h" -#include "BKE_utildefines.h" - -#include "IMB_imbuf_types.h" -#include "IMB_imbuf.h" - -#include "RE_pipeline.h" // talks to entire render API - -#include "blendef.h" - -/* Glow effect */ -enum { - GlowR=0, - GlowG=1, - GlowB=2, - GlowA=3 -}; - - -/* ********************************************************************** - PLUGINS - ********************************************************************** */ - -static void open_plugin_seq(PluginSeq *pis, const char *seqname) -{ - int (*version)(); - void* (*alloc_private)(); - char *cp; - - /* to be sure: (is tested for) */ - pis->doit= 0; - pis->pname= 0; - pis->varstr= 0; - pis->cfra= 0; - pis->version= 0; - pis->instance_private_data = 0; - - /* 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; - - if (pis->handle != 0) { - /* find the address of the version function */ - version= (int (*)())PIL_dynlib_find_symbol(pis->handle, "plugin_seq_getversion"); - if (test_dlerr(pis->name, "plugin_seq_getversion")) return; - - if (version != 0) { - 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; - } - } - alloc_private = (void* (*)())PIL_dynlib_find_symbol( - 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); - - if(pis->doit==0) { - if(pis->handle==0) error("no plugin: %s", str); - else error("in plugin: %s", str); - MEM_freeN(pis); - return 0; - } - - /* 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) -{ - if(pis==0) return; - - /* 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... - */ -static int num_inputs_plugin() -{ - 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) { - return 0; - } - return (ImBuf*) (((void**) i) + 2); -} - -static void do_plugin_effect(Sequence * seq,int cfra, - float facf0, float facf1, int x, int y, - struct ImBuf *ibuf1, struct ImBuf *ibuf2, - struct ImBuf *ibuf3, struct ImBuf *out) -{ - 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 */ - - if(seq->plugin && seq->plugin->doit) { - if(seq->plugin->cfra) - *(seq->plugin->cfra)= frame_to_float(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) { - IMB_float_from_rect(out); - } - - if (use_temp_bufs) { - if (ibuf1) IMB_freeImBuf(ibuf1); - if (ibuf2) IMB_freeImBuf(ibuf2); - if (ibuf3) IMB_freeImBuf(ibuf3); - } - } -} - -static int do_plugin_early_out(struct Sequence *seq, - float facf0, float facf1) -{ - return 0; -} - -static void free_plugin(struct Sequence * seq) -{ - free_plugin_seq(seq->plugin); - seq->plugin = 0; -} - -/* ********************************************************************** - 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, - char * rect1, char *rect2, char *out) -{ - 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, - float * rect1, float *rect2, float *out) -{ - 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; - } - } -} - -static void do_alphaover_effect(Sequence * seq,int cfra, - float facf0, float facf1, int x, int y, - struct ImBuf *ibuf1, struct ImBuf *ibuf2, - struct ImBuf *ibuf3, struct ImBuf *out) -{ - if (out->rect_float) { - do_alphaover_effect_float( - facf0, facf1, x, y, - ibuf1->rect_float, ibuf2->rect_float, - out->rect_float); - } else { - do_alphaover_effect_byte( - facf0, facf1, x, y, - (char*) ibuf1->rect, (char*) ibuf2->rect, - (char*) out->rect); - } -} - - -/* ********************************************************************** - ALPHA UNDER - ********************************************************************** */ - -void do_alphaunder_effect_byte( - 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, - float *rect1, float *rect2, - float *out) -{ - 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; - } - } -} - -static void do_alphaunder_effect(Sequence * seq,int cfra, - float facf0, float facf1, int x, int y, - struct ImBuf *ibuf1, struct ImBuf *ibuf2, - struct ImBuf *ibuf3, struct ImBuf *out) -{ - if (out->rect_float) { - do_alphaunder_effect_float( - facf0, facf1, x, y, - ibuf1->rect_float, ibuf2->rect_float, - out->rect_float); - } else { - do_alphaunder_effect_byte( - facf0, facf1, x, y, - (char*) ibuf1->rect, (char*) ibuf2->rect, - (char*) out->rect); - } -} - - -/* ********************************************************************** - CROSS - ********************************************************************** */ - -void do_cross_effect_byte(float facf0, float facf1, int x, int y, - 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; - } - - } -} - -void do_cross_effect_float(float facf0, float facf1, int x, int y, - 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! */ - -static void do_cross_effect(Sequence * seq,int cfra, - float facf0, float facf1, int x, int y, - struct ImBuf *ibuf1, struct ImBuf *ibuf2, - struct ImBuf *ibuf3, struct ImBuf *out) -{ - if (out->rect_float) { - do_cross_effect_float( - facf0, facf1, x, y, - ibuf1->rect_float, ibuf2->rect_float, - out->rect_float); - } else { - do_cross_effect_byte( - facf0, facf1, x, y, - (char*) ibuf1->rect, (char*) ibuf2->rect, - (char*) out->rect); - } -} - - -/* ********************************************************************** - 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 */ - /* have a different lenght than the other segments, but our */ - /* 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] + - ( (c - color_domain_table[i]) * gamfactor_table[i]); - - 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] + - ( (col - color_domain_table[i]) * inv_gamfactor_table[i]); - - 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 ; - } - } - -} - -static void build_gammatabs() -{ - if (gamma_tabs_init == FALSE) { - gamtabs(2.0f); - makeGammaTables(2.0f); - gamma_tabs_init = TRUE; - } -} - -static void init_gammacross(Sequence * seq) -{ -} - -static void load_gammacross(Sequence * seq) -{ -} - -static void free_gammacross(Sequence * seq) -{ -} - -static void do_gammacross_effect_byte(float facf0, float facf1, - int x, int y, - char *rect1, - char *rect2, - char *out) -{ - int fac1, fac2, col; - int xo; - char *rt1, *rt2, *rt; - - xo= x; - rt1= (char *)rect1; - rt2= (char *)rect2; - rt= (char *)out; - - 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; - } - } - -} - -static void do_gammacross_effect_float(float facf0, float facf1, - int x, int y, - float *rect1, float *rect2, - float *out) -{ - 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++; - } - } -} - -static void do_gammacross_effect(Sequence * seq,int cfra, - float facf0, float facf1, int x, int y, - struct ImBuf *ibuf1, struct ImBuf *ibuf2, - struct ImBuf *ibuf3, struct ImBuf *out) -{ - build_gammatabs(); - - if (out->rect_float) { - do_gammacross_effect_float( - facf0, facf1, x, y, - ibuf1->rect_float, ibuf2->rect_float, - out->rect_float); - } else { - do_gammacross_effect_byte( - facf0, facf1, x, y, - (char*) ibuf1->rect, (char*) ibuf2->rect, - (char*) out->rect); - } -} - - -/* ********************************************************************** - ADD - ********************************************************************** */ - -static void do_add_effect_byte(float facf0, float facf1, int x, int y, - unsigned char *rect1, unsigned char *rect2, - unsigned char *out) -{ - 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++; - } - } -} - -static void do_add_effect(Sequence * seq,int cfra, - float facf0, float facf1, int x, int y, - struct ImBuf *ibuf1, struct ImBuf *ibuf2, - struct ImBuf *ibuf3, struct ImBuf *out) -{ - if (out->rect_float) { - do_add_effect_float( - facf0, facf1, x, y, - ibuf1->rect_float, ibuf2->rect_float, - out->rect_float); - } else { - do_add_effect_byte( - facf0, facf1, x, y, - (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect, - (unsigned char*) out->rect); - } -} - - -/* ********************************************************************** - SUB - ********************************************************************** */ - -static void do_sub_effect_byte(float facf0, float facf1, - int x, int y, - char *rect1, char *rect2, char *out) -{ - 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++; - } - } -} - -static void do_sub_effect(Sequence * seq,int cfra, - float facf0, float facf1, int x, int y, - struct ImBuf *ibuf1, struct ImBuf *ibuf2, - struct ImBuf *ibuf3, struct ImBuf *out) -{ - if (out->rect_float) { - do_sub_effect_float( - facf0, facf1, x, y, - ibuf1->rect_float, ibuf2->rect_float, - out->rect_float); - } else { - do_sub_effect_byte( - facf0, facf1, x, y, - (char*) ibuf1->rect, (char*) ibuf2->rect, - (char*) out->rect); - } -} - -/* ********************************************************************** - 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, - unsigned char *rect2i, unsigned char *rect1i, - unsigned char *outi) -{ - 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); -} - - -static void do_drop_effect(Sequence * seq,int cfra, - float facf0, float facf1, int x, int y, - struct ImBuf *ibuf1, struct ImBuf *ibuf2, - struct ImBuf * ibuf3, - struct ImBuf *out) -{ - if (out->rect_float) { - do_drop_effect_float( - facf0, facf1, x, y, - ibuf1->rect_float, ibuf2->rect_float, - out->rect_float); - } else { - do_drop_effect_byte( - facf0, facf1, x, y, - (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect, - (unsigned char*) out->rect); - } -} - -/* ********************************************************************** - MUL - ********************************************************************** */ - -static void do_mul_effect_byte(float facf0, float facf1, int x, int y, - unsigned char *rect1, unsigned char *rect2, - unsigned char *out) -{ - 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, - 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; - - /* 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; - } - } -} - -static void do_mul_effect(Sequence * seq,int cfra, - float facf0, float facf1, int x, int y, - struct ImBuf *ibuf1, struct ImBuf *ibuf2, - struct ImBuf *ibuf3, struct ImBuf *out) -{ - if (out->rect_float) { - do_mul_effect_float( - facf0, facf1, x, y, - ibuf1->rect_float, ibuf2->rect_float, - out->rect_float); - } else { - do_mul_effect_byte( - facf0, facf1, x, y, - (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect, - (unsigned char*) out->rect); - } -} - -/* ********************************************************************** - 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) -{ - float t1,t2,alpha,percwidth; - - if(width == 0) - return (float)side; - - if(side == 1) - percwidth = width * perc; - else - percwidth = width * (1 - perc); - - 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); - } - else { - if(b1 < b2) - output = in_band(wipezone,width,hyp,facf0,0,1); - else - output = in_band(wipezone,width,hyp,facf0,1,1); - } - 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 ) - 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); - } - if(!wipe->forward)output = 1-output; - 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; - - if(wipe->forward){ - temp1 = 2.0f*(float)M_PI - temp1; - } - - 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; - } - if (temp3 < 0) temp3 = 0; - if (temp4 > 2.0f*(float)M_PI) temp4 = 2.0f*(float)M_PI; - - - if(temp2 < temp3) output = 0; - else if (temp2 > temp4) output = 1; - else output = (temp2-temp3)/(temp4-temp3); - if(x == 0 && y == 0) output = 1; - 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 ) - 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); - } - - 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); - pointdist = sqrt(temp1*temp1 + temp1*temp1); - - 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); - - 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"); -} - -static int num_inputs_wipe() -{ - return 1; -} - -static void free_wipe_effect(Sequence *seq) -{ - if(seq->effectdata)MEM_freeN(seq->effectdata); - seq->effectdata = 0; -} - -static void copy_wipe_effect(Sequence *dst, Sequence *src) -{ - dst->effectdata = MEM_dupallocN(src->effectdata); -} - -static void do_wipe_effect_byte(Sequence *seq, float facf0, float facf1, - 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; - } - } - } -} - -static void do_wipe_effect_float(Sequence *seq, float facf0, float facf1, - 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; - } - } - } -} - -static void do_wipe_effect(Sequence * seq,int cfra, - float facf0, float facf1, int x, int y, - struct ImBuf *ibuf1, struct ImBuf *ibuf2, - struct ImBuf *ibuf3, struct ImBuf *out) -{ - if (out->rect_float) { - do_wipe_effect_float(seq, - facf0, facf1, x, y, - ibuf1->rect_float, ibuf2->rect_float, - out->rect_float); - } else { - do_wipe_effect_byte(seq, - facf0, facf1, x, y, - (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect, - (unsigned char*) out->rect); - } -} -/* ********************************************************************** - TRANSFORM - ********************************************************************** */ -static void init_transform_effect(Sequence *seq) -{ - TransformVars *scale; - - if(seq->effectdata)MEM_freeN(seq->effectdata); - seq->effectdata = MEM_callocN(sizeof(struct TransformVars), "transformvars"); - - scale = (TransformVars *)seq->effectdata; - scale->ScalexIni = 1; - scale->ScaleyIni = 1; - scale->ScalexFin = 1; - scale->ScaleyFin = 1; - - scale->xIni=0; - scale->xFin=0; - scale->yIni=0; - scale->yFin=0; - - scale->rotIni=0; - scale->rotFin=0; - - scale->interpolation=1; - scale->percent=1; -} - -static int num_inputs_transform() -{ - return 1; -} - -static void free_transform_effect(Sequence *seq) -{ - if(seq->effectdata)MEM_freeN(seq->effectdata); - seq->effectdata = 0; -} - -static void copy_transform_effect(Sequence *dst, Sequence *src) -{ - dst->effectdata = MEM_dupallocN(src->effectdata); -} - -static void do_transform(Sequence * seq,float facf0, int x, int y, - struct ImBuf *ibuf1,struct ImBuf *out) -{ - int xo, yo, xi, yi; - float xs,ys,factxScale,factyScale,tx,ty,rad,s,c,xaux,yaux,factRot,px,py; - TransformVars *scale; - - scale = (TransformVars *)seq->effectdata; - xo = x; - yo = y; - - //factor scale - factxScale = scale->ScalexIni + (scale->ScalexFin - scale->ScalexIni) * facf0; - factyScale = scale->ScaleyIni + (scale->ScaleyFin - scale->ScaleyIni) * facf0; - - //Factor translate - if(!scale->percent){ - tx = scale->xIni+(xo / 2.0f) + (scale->xFin-(xo / 2.0f) - scale->xIni+(xo / 2.0f)) * facf0; - ty = scale->yIni+(yo / 2.0f) + (scale->yFin-(yo / 2.0f) - scale->yIni+(yo / 2.0f)) * facf0; - }else{ - tx = xo*(scale->xIni/100.0)+(xo / 2.0f) + (xo*(scale->xFin/100.0)-(xo / 2.0f) - xo*(scale->xIni/100.0)+(xo / 2.0f)) * facf0; - ty = yo*(scale->yIni/100.0)+(yo / 2.0f) + (yo*(scale->yFin/100.0)-(yo / 2.0f) - yo*(scale->yIni/100.0)+(yo / 2.0f)) * facf0; - } - - //factor Rotate - factRot = scale->rotIni + (scale->rotFin - scale->rotIni) * facf0; - rad = (M_PI * factRot) / 180.0f; - s= sin(rad); - c= cos(rad); - - for (yi = 0; yi < yo; yi++) { - for (xi = 0; xi < xo; xi++) { - //tranlate point - px = xi-tx; - py = yi-ty; - - //rotate point with center ref - xaux = c*px + py*s ; - yaux = -s*px + c*py; - - //scale point with center ref - xs = xaux / factxScale; - ys = yaux / factyScale; - - //undo reference center point - xs += (xo / 2.0f); - ys += (yo / 2.0f); - - //interpolate - if(scale->interpolation==0) - neareast_interpolation(ibuf1,out, xs,ys,xi,yi); - if(scale->interpolation==1) - bilinear_interpolation(ibuf1,out, xs,ys,xi,yi); - if(scale->interpolation==2) - bicubic_interpolation(ibuf1,out, xs,ys,xi,yi); - } - } - -} -static void do_transform_effect(Sequence * seq,int cfra, - float facf0, float facf1, int x, int y, - struct ImBuf *ibuf1, struct ImBuf *ibuf2, - struct ImBuf *ibuf3, struct ImBuf *out) -{ - do_transform(seq, facf0, x, y, ibuf1, out); -} - - -/* ********************************************************************** - 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); - 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; - 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, - int width, int height, int threshold, - float boost, float clamp) -{ - int x,y,index; - int intensity; - - - for(y=0;y< height;y++) { - for (x=0;x< width;x++) { - index= (x+y*width)*4; - - /* 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, - int width, int height, float threshold, - float boost, float clamp) -{ - int x,y,index; - float intensity; - - - for(y=0;y< height;y++) { - for (x=0;x< width;x++) { - index= (x+y*width)*4; - - /* 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; -} - -static int num_inputs_glow() -{ - return 1; -} - -static void free_glow_effect(Sequence *seq) -{ - if(seq->effectdata)MEM_freeN(seq->effectdata); - seq->effectdata = 0; -} - -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) -static void do_glow_effect_byte(Sequence *seq, float facf0, float facf1, - int x, int y, char *rect1, - char *rect2, char *out) -{ - unsigned char *outbuf=(unsigned char *)out; - unsigned char *inbuf=(unsigned char *)rect1; - GlowVars *glow = (GlowVars *)seq->effectdata; - struct RenderData *rd = &G.scene->r; - - RVIsolateHighlights_byte(inbuf, outbuf , x, y, glow->fMini*765, glow->fBoost * facf0, glow->fClamp); - RVBlurBitmap2_byte (outbuf, x, y, glow->dDist * (rd->size / 100.0f),glow->dQuality); - if (!glow->bNoComp) - RVAddBitmaps_byte (inbuf , outbuf, outbuf, x, y); -} - -static void do_glow_effect_float(Sequence *seq, float facf0, float facf1, - int x, int y, - float *rect1, float *rect2, float *out) -{ - float *outbuf = out; - float *inbuf = rect1; - GlowVars *glow = (GlowVars *)seq->effectdata; - struct RenderData *rd = &G.scene->r; - - RVIsolateHighlights_float(inbuf, outbuf , x, y, glow->fMini*3.0f, glow->fBoost * facf0, glow->fClamp); - RVBlurBitmap2_float (outbuf, x, y, glow->dDist * (rd->size / 100.0f),glow->dQuality); - if (!glow->bNoComp) - RVAddBitmaps_float (inbuf , outbuf, outbuf, x, y); -} - -static void do_glow_effect(Sequence * seq,int cfra, - float facf0, float facf1, int x, int y, - struct ImBuf *ibuf1, struct ImBuf *ibuf2, - struct ImBuf *ibuf3, struct ImBuf *out) -{ - if (out->rect_float) { - do_glow_effect_float(seq, - facf0, facf1, x, y, - ibuf1->rect_float, ibuf2->rect_float, - out->rect_float); - } else { - do_glow_effect_byte(seq, - facf0, facf1, x, y, - (char*) ibuf1->rect, (char*) ibuf2->rect, - (char*) out->rect); - } -} - -/* ********************************************************************** - 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; -} - -static int num_inputs_color() -{ - return 0; -} - -static void free_solid_color(Sequence *seq) -{ - if(seq->effectdata)MEM_freeN(seq->effectdata); - seq->effectdata = 0; -} - -static void copy_solid_color(Sequence *dst, Sequence *src) -{ - dst->effectdata = MEM_dupallocN(src->effectdata); -} - -static int early_out_color(struct Sequence *seq, - float facf0, float facf1) -{ - return -1; -} - -static void do_solid_color(Sequence * seq,int cfra, - float facf0, float facf1, int x, int y, - struct ImBuf *ibuf1, struct ImBuf *ibuf2, - struct ImBuf *ibuf3, struct ImBuf *out) -{ - SolidColorVars *cv = (SolidColorVars *)seq->effectdata; - - unsigned char *rect; - float *rect_float; - - 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; - } - } - } - } -} - -/* ********************************************************************** - SPEED - ********************************************************************** */ -static void init_speed_effect(Sequence *seq) -{ - SpeedControlVars * v; - - if(seq->effectdata) MEM_freeN(seq->effectdata); - seq->effectdata = MEM_callocN(sizeof(struct SpeedControlVars), - "speedcontrolvars"); - - v = (SpeedControlVars *)seq->effectdata; - v->globalSpeed = 1.0; - v->frameMap = 0; - v->flags = SEQ_SPEED_COMPRESS_IPO_Y; - v->length = 0; -} - -static void load_speed_effect(Sequence * seq) -{ - SpeedControlVars * v = (SpeedControlVars *)seq->effectdata; - - v->frameMap = 0; - v->length = 0; -} - -static int num_inputs_speed() -{ - 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); - seq->effectdata = 0; -} - -static void copy_speed_effect(Sequence *dst, Sequence *src) -{ - SpeedControlVars * v; - dst->effectdata = MEM_dupallocN(src->effectdata); - v = (SpeedControlVars *)dst->effectdata; - v->frameMap = 0; - v->length = 0; -} - -static int early_out_speed(struct Sequence *seq, - float facf0, float facf1) -{ - return 1; -} - -static void store_icu_yrange_speed(struct Sequence * seq, - short adrcode, float * ymin, float * ymax) -{ - 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; - } - } -} - -void sequence_effect_speed_rebuild_map(struct Sequence * seq, int force) -{ - float facf0 = seq->facf0; - float ctime, div; - int cfra; - float fallback_fac; - SpeedControlVars * v = (SpeedControlVars *)seq->effectdata; - - /* if not already done, load / initialize data */ - get_sequence_effect(seq); - - if (!(force || seq->len != v->length || !v->frameMap)) { - return; - } - - 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"); - } - - fallback_fac = 1.0; - - /* if there is no IPO, try to make retiming easy by stretching the - strip */ - - if (!seq->ipo && seq->seq1 && seq->seq1->enddisp != seq->seq1->start - && seq->seq1->len != 0) { - fallback_fac = (float) seq->seq1->len / - (float) (seq->seq1->enddisp - seq->seq1->start); - /* FIXME: this strip stretching gets screwed by stripdata - handling one layer up. - - So it currently works by enlarging, never by shrinking! - - (IPOs still work, if used correctly) - */ - if (fallback_fac > 1.0) { - fallback_fac = 1.0; - } - } - - if ((v->flags & SEQ_SPEED_INTEGRATE) != 0) { - float cursor = 0; - - v->frameMap[0] = 0; - v->lastValidFrame = 0; - - for (cfra = 1; cfra < v->length; cfra++) { - if(seq->ipo) { - if((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) { - ctime = frame_to_float(seq->startdisp - + cfra); - div = 1.0; - } else { - ctime= frame_to_float(cfra); - div= v->length / 100.0f; - if(div==0.0) return; - } - - calc_ipo(seq->ipo, ctime/div); - execute_ipo((ID *)seq, seq->ipo); - } else { - seq->facf0 = fallback_fac; - } - seq->facf0 *= v->globalSpeed; - - cursor += seq->facf0; - - if (cursor >= v->length) { - v->frameMap[cfra] = v->length - 1; - } else { - v->frameMap[cfra] = cursor; - v->lastValidFrame = cfra; - } - } - } else { - v->lastValidFrame = 0; - for (cfra = 0; cfra < v->length; cfra++) { - if(seq->ipo) { - if((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) { - ctime = frame_to_float(seq->startdisp - + cfra); - div = 1.0; - } else { - ctime= frame_to_float(cfra); - div= v->length / 100.0f; - if(div==0.0) return; - } - - calc_ipo(seq->ipo, ctime/div); - execute_ipo((ID *)seq, seq->ipo); - } - - if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) { - seq->facf0 *= v->length; - } - if (!seq->ipo) { - seq->facf0 = (float) cfra * fallback_fac; - } - seq->facf0 *= v->globalSpeed; - if (seq->facf0 >= v->length) { - seq->facf0 = v->length - 1; - } else { - v->lastValidFrame = cfra; - } - v->frameMap[cfra] = seq->facf0; - } - } - seq->facf0 = facf0; -} - -/* - simply reuse do_cross_effect for blending... - -static void do_speed_effect(Sequence * seq,int cfra, - float facf0, float facf1, int x, int y, - struct ImBuf *ibuf1, struct ImBuf *ibuf2, - struct ImBuf *ibuf3, struct ImBuf *out) -{ - -} -*/ - - -/* ********************************************************************** - sequence effect factory - ********************************************************************** */ - - -static void init_noop(struct Sequence *seq) -{ - -} - -static void load_noop(struct Sequence *seq) -{ - -} - -static void init_plugin_noop(struct Sequence *seq, const char * fname) -{ - -} - -static void free_noop(struct Sequence *seq) -{ - -} - -static int num_inputs_default() -{ - return 2; -} - -static int early_out_noop(struct Sequence *seq, - float facf0, float facf1) -{ - return 0; -} - -static int early_out_fade(struct Sequence *seq, - 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; -} - -static int early_out_mul_input2(struct Sequence *seq, - float facf0, float facf1) -{ - if (facf0 == 0.0 && facf1 == 0.0) { - return 1; - } - return 0; -} - -static void store_icu_yrange_noop(struct Sequence * seq, - short adrcode, float * ymin, float * ymax) -{ - /* defaults are fine */ -} - -static void get_default_fac_noop(struct Sequence *seq, int cfra, - float * facf0, float * facf1) -{ - *facf0 = *facf1 = 1.0; -} - -static void get_default_fac_fade(struct Sequence *seq, int cfra, - float * facf0, float * facf1) -{ - *facf0 = (float)(cfra - seq->startdisp); - *facf1 = (float)(*facf0 + 0.5); - *facf0 /= seq->len; - *facf1 /= seq->len; -} - -static void do_overdrop_effect(struct Sequence * seq, int cfra, - float fac, float facf, - int x, int y, struct ImBuf * ibuf1, - struct ImBuf * ibuf2, - struct ImBuf * ibuf3, - struct ImBuf * out) -{ - do_drop_effect(seq, cfra, fac, facf, x, y, - ibuf1, ibuf2, ibuf3, out); - do_alphaover_effect(seq, cfra, fac, facf, x, y, - ibuf1, ibuf2, ibuf3, out); -} - -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; - } - - return rval; -} - - -struct SeqEffectHandle get_sequence_effect(Sequence * seq) -{ - struct SeqEffectHandle rval; - - memset(&rval, 0, sizeof(struct SeqEffectHandle)); - - 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) -{ - struct SeqEffectHandle rval; - - memset(&rval, 0, sizeof(struct SeqEffectHandle)); - - 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; -} |