4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
24 * - Blender Foundation, 2003-2009
25 * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
27 * ***** END GPL LICENSE BLOCK *****
34 #include "MEM_guardedalloc.h"
35 #include "PIL_dynlib.h"
37 #include "DNA_scene_types.h"
38 #include "DNA_sequence_types.h"
40 #include "BLI_blenlib.h"
41 #include "BLI_arithb.h"
43 #include "BKE_global.h"
44 #include "BKE_plugin_types.h"
45 #include "BKE_sequence.h"
46 #include "BKE_texture.h"
47 #include "BKE_utildefines.h"
49 #include "IMB_imbuf_types.h"
50 #include "IMB_imbuf.h"
53 static void error() {}
69 /* **********************************************************************
71 ********************************************************************** */
73 static void open_plugin_seq(PluginSeq *pis, const char *seqname)
76 void* (*alloc_private)();
79 /* to be sure: (is tested for) */
85 pis->instance_private_data = 0;
87 /* clear the error list */
88 PIL_dynlib_get_error_as_string(NULL);
90 /* if(pis->handle) PIL_dynlib_close(pis->handle); */
93 /* open the needed object */
94 pis->handle= PIL_dynlib_open(pis->name);
95 if(test_dlerr(pis->name, pis->name)) return;
97 if (pis->handle != 0) {
98 /* find the address of the version function */
99 version= (int (*)())PIL_dynlib_find_symbol(pis->handle, "plugin_seq_getversion");
100 if (test_dlerr(pis->name, "plugin_seq_getversion")) return;
103 pis->version= version();
104 if (pis->version >= 2 && pis->version <= 6) {
105 int (*info_func)(PluginInfo *);
106 PluginInfo *info= (PluginInfo*) MEM_mallocN(sizeof(PluginInfo), "plugin_info");
108 info_func= (int (*)(PluginInfo *))PIL_dynlib_find_symbol(pis->handle, "plugin_getinfo");
110 if(info_func == NULL) error("No info func");
114 pis->pname= info->name;
115 pis->vars= info->nvars;
116 pis->cfra= info->cfra;
118 pis->varstr= info->varstr;
120 pis->doit= (void(*)(void))info->seq_doit;
126 cp= PIL_dynlib_find_symbol(pis->handle, "seqname");
127 if(cp) strncpy(cp, seqname, 21);
129 printf ("Plugin returned unrecognized version number\n");
133 alloc_private = (void* (*)())PIL_dynlib_find_symbol(
134 pis->handle, "plugin_seq_alloc_private_data");
136 pis->instance_private_data = alloc_private();
139 pis->current_private_data = (void**)
140 PIL_dynlib_find_symbol(
141 pis->handle, "plugin_private_data");
145 static PluginSeq *add_plugin_seq(const char *str, const char *seqname)
151 pis= MEM_callocN(sizeof(PluginSeq), "PluginSeq");
153 strncpy(pis->name, str, FILE_MAXDIR+FILE_MAXFILE);
154 open_plugin_seq(pis, seqname);
157 if(pis->handle==0) error("no plugin: %s", str);
158 else error("in plugin: %s", str);
165 for(a=0; a<pis->vars; a++, varstr++) {
166 if( (varstr->type & FLO)==FLO)
167 pis->data[a]= varstr->def;
168 else if( (varstr->type & INT)==INT)
169 *((int *)(pis->data+a))= (int) varstr->def;
175 static void free_plugin_seq(PluginSeq *pis)
179 /* no PIL_dynlib_close: same plugin can be opened multiple times with 1 handle */
181 if (pis->instance_private_data) {
182 void (*free_private)(void *);
184 free_private = (void (*)(void *))PIL_dynlib_find_symbol(
185 pis->handle, "plugin_seq_free_private_data");
187 free_private(pis->instance_private_data);
194 static void init_plugin(Sequence * seq, const char * fname)
196 seq->plugin= (PluginSeq *)add_plugin_seq(fname, seq->name+2);
200 * FIXME: should query plugin! Could be generator, that needs zero inputs...
202 static int num_inputs_plugin()
207 static void load_plugin(Sequence * seq)
210 open_plugin_seq(seq->plugin, seq->name+2);
214 static void copy_plugin(Sequence * dst, Sequence * src)
217 dst->plugin= MEM_dupallocN(src->plugin);
218 open_plugin_seq(dst->plugin, dst->name+2);
222 static ImBuf * IMB_cast_away_list(ImBuf * i)
227 return (ImBuf*) (((void**) i) + 2);
230 static void do_plugin_effect(Sequence * seq,int cfra,
231 float facf0, float facf1, int x, int y,
232 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
233 struct ImBuf *ibuf3, struct ImBuf *out)
237 int use_temp_bufs = 0; /* Are needed since blur.c (and maybe some other
238 old plugins) do very bad stuff
239 with imbuf-internals */
241 if(seq->plugin && seq->plugin->doit) {
243 if(seq->plugin->cfra)
244 *(seq->plugin->cfra)= cfra;
245 // XXX *(seq->plugin->cfra)= frame_to_float(scene, cfra);
247 cp = PIL_dynlib_find_symbol(
248 seq->plugin->handle, "seqname");
250 if(cp) strncpy(cp, seq->name+2, 22);
252 if (seq->plugin->current_private_data) {
253 *seq->plugin->current_private_data
254 = seq->plugin->instance_private_data;
257 float_rendering = (out->rect_float != NULL);
259 if (seq->plugin->version<=3 && float_rendering) {
263 ibuf1 = IMB_dupImBuf(ibuf1);
264 IMB_rect_from_float(ibuf1);
265 imb_freerectfloatImBuf(ibuf1);
266 ibuf1->flags &= ~IB_rectfloat;
269 ibuf2 = IMB_dupImBuf(ibuf2);
270 IMB_rect_from_float(ibuf2);
271 imb_freerectfloatImBuf(ibuf2);
272 ibuf2->flags &= ~IB_rectfloat;
275 ibuf3 = IMB_dupImBuf(ibuf3);
276 IMB_rect_from_float(ibuf3);
277 imb_freerectfloatImBuf(ibuf3);
278 ibuf3->flags &= ~IB_rectfloat;
280 if (!out->rect) imb_addrectImBuf(out);
281 imb_freerectfloatImBuf(out);
282 out->flags &= ~IB_rectfloat;
285 if (seq->plugin->version<=2) {
286 if(ibuf1) IMB_convert_rgba_to_abgr(ibuf1);
287 if(ibuf2) IMB_convert_rgba_to_abgr(ibuf2);
288 if(ibuf3) IMB_convert_rgba_to_abgr(ibuf3);
291 if (seq->plugin->version<=4) {
292 ((SeqDoit)seq->plugin->doit)(
293 seq->plugin->data, facf0, facf1, x, y,
294 IMB_cast_away_list(ibuf1),
295 IMB_cast_away_list(ibuf2),
296 IMB_cast_away_list(out),
297 IMB_cast_away_list(ibuf3));
299 ((SeqDoit)seq->plugin->doit)(
300 seq->plugin->data, facf0, facf1, x, y,
301 ibuf1, ibuf2, out, ibuf3);
304 if (seq->plugin->version<=2) {
305 if (!use_temp_bufs) {
306 if(ibuf1) IMB_convert_rgba_to_abgr(ibuf1);
307 if(ibuf2) IMB_convert_rgba_to_abgr(ibuf2);
308 if(ibuf3) IMB_convert_rgba_to_abgr(ibuf3);
310 IMB_convert_rgba_to_abgr(out);
312 if (seq->plugin->version<=3 && float_rendering) {
313 IMB_float_from_rect(out);
317 if (ibuf1) IMB_freeImBuf(ibuf1);
318 if (ibuf2) IMB_freeImBuf(ibuf2);
319 if (ibuf3) IMB_freeImBuf(ibuf3);
324 static int do_plugin_early_out(struct Sequence *seq,
325 float facf0, float facf1)
330 static void free_plugin(struct Sequence * seq)
332 free_plugin_seq(seq->plugin);
336 /* **********************************************************************
338 ********************************************************************** */
340 static void init_alpha_over_or_under(Sequence * seq)
342 Sequence * seq1 = seq->seq1;
343 Sequence * seq2 = seq->seq2;
349 static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y,
350 char * rect1, char *rect2, char *out)
352 int fac2, mfac, fac, fac4;
354 char *rt1, *rt2, *rt;
361 fac2= (int)(256.0*facf0);
362 fac4= (int)(256.0*facf1);
369 /* rt = rt1 over rt2 (alpha from rt1) */
372 mfac= 256 - ( (fac2*rt1[3])>>8 );
374 if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
375 else if(mfac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
377 tempc= ( fac*rt1[0] + mfac*rt2[0])>>8;
378 if(tempc>255) rt[0]= 255; else rt[0]= tempc;
379 tempc= ( fac*rt1[1] + mfac*rt2[1])>>8;
380 if(tempc>255) rt[1]= 255; else rt[1]= tempc;
381 tempc= ( fac*rt1[2] + mfac*rt2[2])>>8;
382 if(tempc>255) rt[2]= 255; else rt[2]= tempc;
383 tempc= ( fac*rt1[3] + mfac*rt2[3])>>8;
384 if(tempc>255) rt[3]= 255; else rt[3]= tempc;
386 rt1+= 4; rt2+= 4; rt+= 4;
396 mfac= 256 - ( (fac4*rt1[3])>>8 );
398 if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
399 else if(mfac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
401 tempc= ( fac*rt1[0] + mfac*rt2[0])>>8;
402 if(tempc>255) rt[0]= 255; else rt[0]= tempc;
403 tempc= ( fac*rt1[1] + mfac*rt2[1])>>8;
404 if(tempc>255) rt[1]= 255; else rt[1]= tempc;
405 tempc= ( fac*rt1[2] + mfac*rt2[2])>>8;
406 if(tempc>255) rt[2]= 255; else rt[2]= tempc;
407 tempc= ( fac*rt1[3] + mfac*rt2[3])>>8;
408 if(tempc>255) rt[3]= 255; else rt[3]= tempc;
410 rt1+= 4; rt2+= 4; rt+= 4;
415 static void do_alphaover_effect_float(float facf0, float facf1, int x, int y,
416 float * rect1, float *rect2, float *out)
418 float fac2, mfac, fac, fac4;
420 float *rt1, *rt2, *rt;
435 /* rt = rt1 over rt2 (alpha from rt1) */
438 mfac= 1.0 - (fac2*rt1[3]) ;
441 memcpy(rt, rt2, 4 * sizeof(float));
442 } else if(mfac <=0) {
443 memcpy(rt, rt1, 4 * sizeof(float));
445 rt[0] = fac*rt1[0] + mfac*rt2[0];
446 rt[1] = fac*rt1[1] + mfac*rt2[1];
447 rt[2] = fac*rt1[2] + mfac*rt2[2];
448 rt[3] = fac*rt1[3] + mfac*rt2[3];
450 rt1+= 4; rt2+= 4; rt+= 4;
460 mfac= 1.0 - (fac4*rt1[3]);
463 memcpy(rt, rt2, 4 * sizeof(float));
464 } else if(mfac <= 0.0) {
465 memcpy(rt, rt1, 4 * sizeof(float));
467 rt[0] = fac*rt1[0] + mfac*rt2[0];
468 rt[1] = fac*rt1[1] + mfac*rt2[1];
469 rt[2] = fac*rt1[2] + mfac*rt2[2];
470 rt[3] = fac*rt1[3] + mfac*rt2[3];
472 rt1+= 4; rt2+= 4; rt+= 4;
477 static void do_alphaover_effect(Sequence * seq,int cfra,
478 float facf0, float facf1, int x, int y,
479 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
480 struct ImBuf *ibuf3, struct ImBuf *out)
482 if (out->rect_float) {
483 do_alphaover_effect_float(
485 ibuf1->rect_float, ibuf2->rect_float,
488 do_alphaover_effect_byte(
490 (char*) ibuf1->rect, (char*) ibuf2->rect,
496 /* **********************************************************************
498 ********************************************************************** */
500 void do_alphaunder_effect_byte(
501 float facf0, float facf1, int x, int y, char *rect1,
502 char *rect2, char *out)
504 int fac2, mfac, fac, fac4;
506 char *rt1, *rt2, *rt;
513 fac2= (int)(256.0*facf0);
514 fac4= (int)(256.0*facf1);
521 /* rt = rt1 under rt2 (alpha from rt2) */
523 /* this complex optimalisation is because the
524 * 'skybuf' can be crossed in
526 if(rt2[3]==0 && fac2==256) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
527 else if(rt2[3]==255) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
530 fac= (fac2*(256-mfac))>>8;
532 if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
534 rt[0]= ( fac*rt1[0] + mfac*rt2[0])>>8;
535 rt[1]= ( fac*rt1[1] + mfac*rt2[1])>>8;
536 rt[2]= ( fac*rt1[2] + mfac*rt2[2])>>8;
537 rt[3]= ( fac*rt1[3] + mfac*rt2[3])>>8;
540 rt1+= 4; rt2+= 4; rt+= 4;
549 if(rt2[3]==0 && fac4==256) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
550 else if(rt2[3]==255) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
553 fac= (fac4*(256-mfac))>>8;
555 if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
557 rt[0]= ( fac*rt1[0] + mfac*rt2[0])>>8;
558 rt[1]= ( fac*rt1[1] + mfac*rt2[1])>>8;
559 rt[2]= ( fac*rt1[2] + mfac*rt2[2])>>8;
560 rt[3]= ( fac*rt1[3] + mfac*rt2[3])>>8;
563 rt1+= 4; rt2+= 4; rt+= 4;
569 static void do_alphaunder_effect_float(float facf0, float facf1, int x, int y,
570 float *rect1, float *rect2,
573 float fac2, mfac, fac, fac4;
575 float *rt1, *rt2, *rt;
590 /* rt = rt1 under rt2 (alpha from rt2) */
592 /* this complex optimalisation is because the
593 * 'skybuf' can be crossed in
595 if( rt2[3]<=0 && fac2>=1.0) {
596 memcpy(rt, rt1, 4 * sizeof(float));
597 } else if(rt2[3]>=1.0) {
598 memcpy(rt, rt2, 4 * sizeof(float));
601 fac = fac2 * (1.0 - mfac);
604 memcpy(rt, rt2, 4 * sizeof(float));
606 rt[0]= fac*rt1[0] + mfac*rt2[0];
607 rt[1]= fac*rt1[1] + mfac*rt2[1];
608 rt[2]= fac*rt1[2] + mfac*rt2[2];
609 rt[3]= fac*rt1[3] + mfac*rt2[3];
612 rt1+= 4; rt2+= 4; rt+= 4;
621 if(rt2[3]<=0 && fac4 >= 1.0) {
622 memcpy(rt, rt1, 4 * sizeof(float));
624 } else if(rt2[3]>=1.0) {
625 memcpy(rt, rt2, 4 * sizeof(float));
628 fac= fac4*(1.0-mfac);
631 memcpy(rt, rt2, 4 * sizeof(float));
633 rt[0]= fac * rt1[0] + mfac * rt2[0];
634 rt[1]= fac * rt1[1] + mfac * rt2[1];
635 rt[2]= fac * rt1[2] + mfac * rt2[2];
636 rt[3]= fac * rt1[3] + mfac * rt2[3];
639 rt1+= 4; rt2+= 4; rt+= 4;
644 static void do_alphaunder_effect(Sequence * seq,int cfra,
645 float facf0, float facf1, int x, int y,
646 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
647 struct ImBuf *ibuf3, struct ImBuf *out)
649 if (out->rect_float) {
650 do_alphaunder_effect_float(
652 ibuf1->rect_float, ibuf2->rect_float,
655 do_alphaunder_effect_byte(
657 (char*) ibuf1->rect, (char*) ibuf2->rect,
663 /* **********************************************************************
665 ********************************************************************** */
667 void do_cross_effect_byte(float facf0, float facf1, int x, int y,
668 char *rect1, char *rect2,
671 int fac1, fac2, fac3, fac4;
673 char *rt1, *rt2, *rt;
680 fac2= (int)(256.0*facf0);
682 fac4= (int)(256.0*facf1);
690 rt[0]= (fac1*rt1[0] + fac2*rt2[0])>>8;
691 rt[1]= (fac1*rt1[1] + fac2*rt2[1])>>8;
692 rt[2]= (fac1*rt1[2] + fac2*rt2[2])>>8;
693 rt[3]= (fac1*rt1[3] + fac2*rt2[3])>>8;
695 rt1+= 4; rt2+= 4; rt+= 4;
704 rt[0]= (fac3*rt1[0] + fac4*rt2[0])>>8;
705 rt[1]= (fac3*rt1[1] + fac4*rt2[1])>>8;
706 rt[2]= (fac3*rt1[2] + fac4*rt2[2])>>8;
707 rt[3]= (fac3*rt1[3] + fac4*rt2[3])>>8;
709 rt1+= 4; rt2+= 4; rt+= 4;
715 void do_cross_effect_float(float facf0, float facf1, int x, int y,
716 float *rect1, float *rect2, float *out)
718 float fac1, fac2, fac3, fac4;
720 float *rt1, *rt2, *rt;
737 rt[0]= fac1*rt1[0] + fac2*rt2[0];
738 rt[1]= fac1*rt1[1] + fac2*rt2[1];
739 rt[2]= fac1*rt1[2] + fac2*rt2[2];
740 rt[3]= fac1*rt1[3] + fac2*rt2[3];
742 rt1+= 4; rt2+= 4; rt+= 4;
751 rt[0]= fac3*rt1[0] + fac4*rt2[0];
752 rt[1]= fac3*rt1[1] + fac4*rt2[1];
753 rt[2]= fac3*rt1[2] + fac4*rt2[2];
754 rt[3]= fac3*rt1[3] + fac4*rt2[3];
756 rt1+= 4; rt2+= 4; rt+= 4;
762 /* carefull: also used by speed effect! */
764 static void do_cross_effect(Sequence * seq,int cfra,
765 float facf0, float facf1, int x, int y,
766 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
767 struct ImBuf *ibuf3, struct ImBuf *out)
769 if (out->rect_float) {
770 do_cross_effect_float(
772 ibuf1->rect_float, ibuf2->rect_float,
775 do_cross_effect_byte(
777 (char*) ibuf1->rect, (char*) ibuf2->rect,
783 /* **********************************************************************
785 ********************************************************************** */
787 /* copied code from initrender.c */
788 static unsigned short gamtab[65536];
789 static unsigned short igamtab1[256];
790 static int gamma_tabs_init = FALSE;
792 #define RE_GAMMA_TABLE_SIZE 400
794 static float gamma_range_table[RE_GAMMA_TABLE_SIZE + 1];
795 static float gamfactor_table[RE_GAMMA_TABLE_SIZE];
796 static float inv_gamma_range_table[RE_GAMMA_TABLE_SIZE + 1];
797 static float inv_gamfactor_table[RE_GAMMA_TABLE_SIZE];
798 static float color_domain_table[RE_GAMMA_TABLE_SIZE + 1];
799 static float color_step;
800 static float inv_color_step;
801 static float valid_gamma;
802 static float valid_inv_gamma;
804 static void makeGammaTables(float gamma)
806 /* we need two tables: one forward, one backward */
810 valid_inv_gamma = 1.0 / gamma;
811 color_step = 1.0 / RE_GAMMA_TABLE_SIZE;
812 inv_color_step = (float) RE_GAMMA_TABLE_SIZE;
814 /* We could squeeze out the two range tables to gain some memory. */
815 for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++) {
816 color_domain_table[i] = i * color_step;
817 gamma_range_table[i] = pow(color_domain_table[i],
819 inv_gamma_range_table[i] = pow(color_domain_table[i],
823 /* The end of the table should match 1.0 carefully. In order to avoid */
824 /* rounding errors, we just set this explicitly. The last segment may */
825 /* have a different lenght than the other segments, but our */
826 /* interpolation is insensitive to that. */
827 color_domain_table[RE_GAMMA_TABLE_SIZE] = 1.0;
828 gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0;
829 inv_gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0;
831 /* To speed up calculations, we make these calc factor tables. They are */
832 /* multiplication factors used in scaling the interpolation. */
833 for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++ ) {
834 gamfactor_table[i] = inv_color_step
835 * (gamma_range_table[i + 1] - gamma_range_table[i]) ;
836 inv_gamfactor_table[i] = inv_color_step
837 * (inv_gamma_range_table[i + 1] - inv_gamma_range_table[i]) ;
840 } /* end of void makeGammaTables(float gamma) */
843 static float gammaCorrect(float c)
848 i = floor(c * inv_color_step);
849 /* Clip to range [0,1]: outside, just do the complete calculation. */
850 /* We may have some performance problems here. Stretching up the LUT */
851 /* may help solve that, by exchanging LUT size for the interpolation. */
852 /* Negative colors are explicitly handled. */
853 if (i < 0) res = -pow(abs(c), valid_gamma);
854 else if (i >= RE_GAMMA_TABLE_SIZE ) res = pow(c, valid_gamma);
855 else res = gamma_range_table[i] +
856 ( (c - color_domain_table[i]) * gamfactor_table[i]);
859 } /* end of float gammaCorrect(float col) */
861 /* ------------------------------------------------------------------------- */
863 static float invGammaCorrect(float col)
868 i = floor(col*inv_color_step);
869 /* Negative colors are explicitly handled. */
870 if (i < 0) res = -pow(abs(col), valid_inv_gamma);
871 else if (i >= RE_GAMMA_TABLE_SIZE) res = pow(col, valid_inv_gamma);
872 else res = inv_gamma_range_table[i] +
873 ( (col - color_domain_table[i]) * inv_gamfactor_table[i]);
876 } /* end of float invGammaCorrect(float col) */
879 static void gamtabs(float gamma)
881 float val, igamma= 1.0f/gamma;
884 /* gamtab: in short, out short */
885 for(a=0; a<65536; a++) {
889 if(gamma==2.0) val= sqrt(val);
890 else if(gamma!=1.0) val= pow(val, igamma);
892 gamtab[a]= (65535.99*val);
894 /* inverse gamtab1 : in byte, out short */
895 for(a=1; a<=256; a++) {
896 if(gamma==2.0) igamtab1[a-1]= a*a-1;
897 else if(gamma==1.0) igamtab1[a-1]= 256*a-1;
900 igamtab1[a-1]= (65535.0*pow(val, gamma)) -1 ;
906 static void build_gammatabs()
908 if (gamma_tabs_init == FALSE) {
910 makeGammaTables(2.0f);
911 gamma_tabs_init = TRUE;
915 static void init_gammacross(Sequence * seq)
919 static void load_gammacross(Sequence * seq)
923 static void free_gammacross(Sequence * seq)
927 static void do_gammacross_effect_byte(float facf0, float facf1,
929 unsigned char *rect1,
930 unsigned char *rect2,
935 unsigned char *rt1, *rt2, *rt;
938 rt1= (unsigned char *)rect1;
939 rt2= (unsigned char *)rect2;
940 rt= (unsigned char *)out;
942 fac2= (int)(256.0*facf0);
950 col= (fac1*igamtab1[rt1[0]] + fac2*igamtab1[rt2[0]])>>8;
951 if(col>65535) rt[0]= 255; else rt[0]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
952 col=(fac1*igamtab1[rt1[1]] + fac2*igamtab1[rt2[1]])>>8;
953 if(col>65535) rt[1]= 255; else rt[1]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
954 col= (fac1*igamtab1[rt1[2]] + fac2*igamtab1[rt2[2]])>>8;
955 if(col>65535) rt[2]= 255; else rt[2]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
956 col= (fac1*igamtab1[rt1[3]] + fac2*igamtab1[rt2[3]])>>8;
957 if(col>65535) rt[3]= 255; else rt[3]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
959 rt1+= 4; rt2+= 4; rt+= 4;
968 col= (fac1*igamtab1[rt1[0]] + fac2*igamtab1[rt2[0]])>>8;
969 if(col>65535) rt[0]= 255; else rt[0]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
970 col= (fac1*igamtab1[rt1[1]] + fac2*igamtab1[rt2[1]])>>8;
971 if(col>65535) rt[1]= 255; else rt[1]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
972 col= (fac1*igamtab1[rt1[2]] + fac2*igamtab1[rt2[2]])>>8;
973 if(col>65535) rt[2]= 255; else rt[2]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
974 col= (fac1*igamtab1[rt1[3]] + fac2*igamtab1[rt2[3]])>>8;
975 if(col>65535) rt[3]= 255; else rt[3]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
977 rt1+= 4; rt2+= 4; rt+= 4;
983 static void do_gammacross_effect_float(float facf0, float facf1,
985 float *rect1, float *rect2,
990 float *rt1, *rt2, *rt;
1006 fac1 * invGammaCorrect(*rt1)
1007 + fac2 * invGammaCorrect(*rt2));
1018 fac1*invGammaCorrect(*rt1)
1019 + fac2*invGammaCorrect(*rt2));
1026 static void do_gammacross_effect(Sequence * seq,int cfra,
1027 float facf0, float facf1, int x, int y,
1028 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
1029 struct ImBuf *ibuf3, struct ImBuf *out)
1033 if (out->rect_float) {
1034 do_gammacross_effect_float(
1036 ibuf1->rect_float, ibuf2->rect_float,
1039 do_gammacross_effect_byte(
1041 (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect,
1042 (unsigned char*) out->rect);
1047 /* **********************************************************************
1049 ********************************************************************** */
1051 static void do_add_effect_byte(float facf0, float facf1, int x, int y,
1052 unsigned char *rect1, unsigned char *rect2,
1055 int col, xo, fac1, fac3;
1056 char *rt1, *rt2, *rt;
1063 fac1= (int)(256.0*facf0);
1064 fac3= (int)(256.0*facf1);
1071 col= rt1[0]+ ((fac1*rt2[0])>>8);
1072 if(col>255) rt[0]= 255; else rt[0]= col;
1073 col= rt1[1]+ ((fac1*rt2[1])>>8);
1074 if(col>255) rt[1]= 255; else rt[1]= col;
1075 col= rt1[2]+ ((fac1*rt2[2])>>8);
1076 if(col>255) rt[2]= 255; else rt[2]= col;
1077 col= rt1[3]+ ((fac1*rt2[3])>>8);
1078 if(col>255) rt[3]= 255; else rt[3]= col;
1080 rt1+= 4; rt2+= 4; rt+= 4;
1089 col= rt1[0]+ ((fac3*rt2[0])>>8);
1090 if(col>255) rt[0]= 255; else rt[0]= col;
1091 col= rt1[1]+ ((fac3*rt2[1])>>8);
1092 if(col>255) rt[1]= 255; else rt[1]= col;
1093 col= rt1[2]+ ((fac3*rt2[2])>>8);
1094 if(col>255) rt[2]= 255; else rt[2]= col;
1095 col= rt1[3]+ ((fac3*rt2[3])>>8);
1096 if(col>255) rt[3]= 255; else rt[3]= col;
1098 rt1+= 4; rt2+= 4; rt+= 4;
1103 static void do_add_effect_float(float facf0, float facf1, int x, int y,
1104 float *rect1, float *rect2,
1109 float *rt1, *rt2, *rt;
1123 *rt = *rt1 + fac1 * (*rt2);
1133 *rt = *rt1 + fac3 * (*rt2);
1140 static void do_add_effect(Sequence * seq,int cfra,
1141 float facf0, float facf1, int x, int y,
1142 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
1143 struct ImBuf *ibuf3, struct ImBuf *out)
1145 if (out->rect_float) {
1146 do_add_effect_float(
1148 ibuf1->rect_float, ibuf2->rect_float,
1153 (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect,
1154 (unsigned char*) out->rect);
1159 /* **********************************************************************
1161 ********************************************************************** */
1163 static void do_sub_effect_byte(float facf0, float facf1,
1165 char *rect1, char *rect2, char *out)
1167 int col, xo, fac1, fac3;
1168 char *rt1, *rt2, *rt;
1175 fac1= (int)(256.0*facf0);
1176 fac3= (int)(256.0*facf1);
1183 col= rt1[0]- ((fac1*rt2[0])>>8);
1184 if(col<0) rt[0]= 0; else rt[0]= col;
1185 col= rt1[1]- ((fac1*rt2[1])>>8);
1186 if(col<0) rt[1]= 0; else rt[1]= col;
1187 col= rt1[2]- ((fac1*rt2[2])>>8);
1188 if(col<0) rt[2]= 0; else rt[2]= col;
1189 col= rt1[3]- ((fac1*rt2[3])>>8);
1190 if(col<0) rt[3]= 0; else rt[3]= col;
1192 rt1+= 4; rt2+= 4; rt+= 4;
1201 col= rt1[0]- ((fac3*rt2[0])>>8);
1202 if(col<0) rt[0]= 0; else rt[0]= col;
1203 col= rt1[1]- ((fac3*rt2[1])>>8);
1204 if(col<0) rt[1]= 0; else rt[1]= col;
1205 col= rt1[2]- ((fac3*rt2[2])>>8);
1206 if(col<0) rt[2]= 0; else rt[2]= col;
1207 col= rt1[3]- ((fac3*rt2[3])>>8);
1208 if(col<0) rt[3]= 0; else rt[3]= col;
1210 rt1+= 4; rt2+= 4; rt+= 4;
1215 static void do_sub_effect_float(float facf0, float facf1, int x, int y,
1216 float *rect1, float *rect2,
1221 float *rt1, *rt2, *rt;
1235 *rt = *rt1 - fac1 * (*rt2);
1245 *rt = *rt1 - fac3 * (*rt2);
1252 static void do_sub_effect(Sequence * seq,int cfra,
1253 float facf0, float facf1, int x, int y,
1254 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
1255 struct ImBuf *ibuf3, struct ImBuf *out)
1257 if (out->rect_float) {
1258 do_sub_effect_float(
1260 ibuf1->rect_float, ibuf2->rect_float,
1265 (char*) ibuf1->rect, (char*) ibuf2->rect,
1270 /* **********************************************************************
1272 ********************************************************************** */
1274 /* Must be > 0 or add precopy, etc to the function */
1278 static void do_drop_effect_byte(float facf0, float facf1, int x, int y,
1279 unsigned char *rect2i, unsigned char *rect1i,
1280 unsigned char *outi)
1282 int height, width, temp, fac, fac1, fac2;
1283 char *rt1, *rt2, *out;
1289 fac1= (int)(70.0*facf0);
1290 fac2= (int)(70.0*facf1);
1292 rt2= (char*) (rect2i + YOFF*width);
1293 rt1= (char*) rect1i;
1295 for (y=0; y<height-YOFF; y++) {
1296 if(field) fac= fac1;
1300 memcpy(out, rt1, sizeof(int)*XOFF);
1304 for (x=XOFF; x<width; x++) {
1305 temp= ((fac*rt2[3])>>8);
1307 *(out++)= MAX2(0, *rt1 - temp); rt1++;
1308 *(out++)= MAX2(0, *rt1 - temp); rt1++;
1309 *(out++)= MAX2(0, *rt1 - temp); rt1++;
1310 *(out++)= MAX2(0, *rt1 - temp); rt1++;
1315 memcpy(out, rt1, sizeof(int)*YOFF*width);
1318 static void do_drop_effect_float(float facf0, float facf1, int x, int y,
1319 float *rect2i, float *rect1i,
1323 float temp, fac, fac1, fac2;
1324 float *rt1, *rt2, *out;
1333 rt2= (rect2i + YOFF*width);
1336 for (y=0; y<height-YOFF; y++) {
1337 if(field) fac= fac1;
1341 memcpy(out, rt1, 4 * sizeof(float)*XOFF);
1345 for (x=XOFF; x<width; x++) {
1348 *(out++)= MAX2(0.0, *rt1 - temp); rt1++;
1349 *(out++)= MAX2(0.0, *rt1 - temp); rt1++;
1350 *(out++)= MAX2(0.0, *rt1 - temp); rt1++;
1351 *(out++)= MAX2(0.0, *rt1 - temp); rt1++;
1356 memcpy(out, rt1, 4 * sizeof(float)*YOFF*width);
1360 static void do_drop_effect(Sequence * seq,int cfra,
1361 float facf0, float facf1, int x, int y,
1362 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
1363 struct ImBuf * ibuf3,
1366 if (out->rect_float) {
1367 do_drop_effect_float(
1369 ibuf1->rect_float, ibuf2->rect_float,
1372 do_drop_effect_byte(
1374 (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect,
1375 (unsigned char*) out->rect);
1379 /* **********************************************************************
1381 ********************************************************************** */
1383 static void do_mul_effect_byte(float facf0, float facf1, int x, int y,
1384 unsigned char *rect1, unsigned char *rect2,
1388 char *rt1, *rt2, *rt;
1395 fac1= (int)(256.0*facf0);
1396 fac3= (int)(256.0*facf1);
1399 * fac*(a*b) + (1-fac)*a => fac*a*(b-1)+axaux= c*px + py*s ;//+centx
1400 yaux= -s*px + c*py;//+centy
1408 rt[0]= rt1[0] + ((fac1*rt1[0]*(rt2[0]-256))>>16);
1409 rt[1]= rt1[1] + ((fac1*rt1[1]*(rt2[1]-256))>>16);
1410 rt[2]= rt1[2] + ((fac1*rt1[2]*(rt2[2]-256))>>16);
1411 rt[3]= rt1[3] + ((fac1*rt1[3]*(rt2[3]-256))>>16);
1413 rt1+= 4; rt2+= 4; rt+= 4;
1422 rt[0]= rt1[0] + ((fac3*rt1[0]*(rt2[0]-256))>>16);
1423 rt[1]= rt1[1] + ((fac3*rt1[1]*(rt2[1]-256))>>16);
1424 rt[2]= rt1[2] + ((fac3*rt1[2]*(rt2[2]-256))>>16);
1425 rt[3]= rt1[3] + ((fac3*rt1[3]*(rt2[3]-256))>>16);
1427 rt1+= 4; rt2+= 4; rt+= 4;
1432 static void do_mul_effect_float(float facf0, float facf1, int x, int y,
1433 float *rect1, float *rect2,
1438 float *rt1, *rt2, *rt;
1449 * fac*(a*b) + (1-fac)*a => fac*a*(b-1)+a
1457 rt[0]= rt1[0] + fac1*rt1[0]*(rt2[0]-1.0);
1458 rt[1]= rt1[1] + fac1*rt1[1]*(rt2[1]-1.0);
1459 rt[2]= rt1[2] + fac1*rt1[2]*(rt2[2]-1.0);
1460 rt[3]= rt1[3] + fac1*rt1[3]*(rt2[3]-1.0);
1462 rt1+= 4; rt2+= 4; rt+= 4;
1471 rt[0]= rt1[0] + fac3*rt1[0]*(rt2[0]-1.0);
1472 rt[1]= rt1[1] + fac3*rt1[1]*(rt2[1]-1.0);
1473 rt[2]= rt1[2] + fac3*rt1[2]*(rt2[2]-1.0);
1474 rt[3]= rt1[3] + fac3*rt1[3]*(rt2[3]-1.0);
1476 rt1+= 4; rt2+= 4; rt+= 4;
1481 static void do_mul_effect(Sequence * seq,int cfra,
1482 float facf0, float facf1, int x, int y,
1483 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
1484 struct ImBuf *ibuf3, struct ImBuf *out)
1486 if (out->rect_float) {
1487 do_mul_effect_float(
1489 ibuf1->rect_float, ibuf2->rect_float,
1494 (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect,
1495 (unsigned char*) out->rect);
1499 /* **********************************************************************
1501 ********************************************************************** */
1503 typedef struct WipeZone {
1512 static void precalc_wipe_zone(WipeZone *wipezone, WipeVars *wipe, int xo, int yo)
1514 wipezone->flip = (wipe->angle < 0);
1515 wipezone->angle = pow(fabs(wipe->angle)/45.0f, log(xo)/log(2.0f));
1518 wipezone->width = (int)(wipe->edgeWidth*((xo+yo)/2.0f));
1519 wipezone->pythangle = 1.0f/sqrt(wipe->angle*wipe->angle + 1.0f);
1521 if(wipe->wipetype == DO_SINGLE_WIPE)
1522 wipezone->invwidth = 1.0f/wipezone->width;
1524 wipezone->invwidth = 1.0f/(0.5f*wipezone->width);
1527 // This function calculates the blur band for the wipe effects
1528 static float in_band(WipeZone *wipezone,float width,float dist,float perc,int side,int dir)
1530 float t1,t2,alpha,percwidth;
1536 percwidth = width * perc;
1538 percwidth = width * (1 - perc);
1543 t1 = dist * wipezone->invwidth; //percentange of width that is
1544 t2 = wipezone->invwidth; //amount of alpha per % point
1547 alpha = (t1*t2*100) + (1-perc); // add point's alpha contrib to current position in wipe
1549 alpha = (1-perc) - (t1*t2*100);
1557 static float check_zone(WipeZone *wipezone, int x, int y,
1558 Sequence *seq, float facf0)
1560 float posx, posy,hyp,hyp2,angle,hwidth,b1,b2,b3,pointdist;
1562 float hyp3,hyp4,b4,b5
1564 float temp1,temp2,temp3,temp4; //some placeholder variables
1565 int xo = wipezone->xo;
1566 int yo = wipezone->yo;
1567 float halfx = xo*0.5f;
1568 float halfy = yo*0.5f;
1569 float widthf,output=0;
1570 WipeVars *wipe = (WipeVars *)seq->effectdata;
1573 if(wipezone->flip) x = xo - x;
1574 angle = wipezone->angle;
1582 posx = xo - facf0 * xo;
1583 posy = yo - facf0 * yo;
1586 switch (wipe->wipetype) {
1587 case DO_SINGLE_WIPE:
1588 width = wipezone->width;
1589 hwidth = width*0.5f;
1594 hyp = fabs(y - posy);
1597 b1 = posy - (-angle)*posx;
1598 b2 = y - (-angle)*x;
1599 hyp = fabs(angle*x+y+(-posy-angle*posx))*wipezone->pythangle;
1610 output = in_band(wipezone,width,hyp,facf0,1,1);
1612 output = in_band(wipezone,width,hyp,facf0,0,1);
1616 output = in_band(wipezone,width,hyp,facf0,0,1);
1618 output = in_band(wipezone,width,hyp,facf0,1,1);
1622 case DO_DOUBLE_WIPE:
1624 facf0 = 1.0f-facf0; // Go the other direction
1626 width = wipezone->width; // calculate the blur width
1627 hwidth = width*0.5f;
1633 hyp = abs(y - posy*0.5f);
1634 hyp2 = abs(y - (yo-posy*0.5f));
1637 b1 = posy*0.5f - (-angle)*posx*0.5f;
1638 b3 = (yo-posy*0.5f) - (-angle)*(xo-posx*0.5f);
1639 b2 = y - (-angle)*x;
1641 hyp = abs(angle*x+y+(-posy*0.5f-angle*posx*0.5f))*wipezone->pythangle;
1642 hyp2 = abs(angle*x+y+(-(yo-posy*0.5f)-angle*(xo-posx*0.5f)))*wipezone->pythangle;
1645 temp1 = xo*(1-facf0*0.5f)-xo*facf0*0.5f;
1646 temp2 = yo*(1-facf0*0.5f)-yo*facf0*0.5f;
1647 pointdist = sqrt(temp1*temp1 + temp2*temp2);
1649 if(b2 < b1 && b2 < b3 ){
1650 if(hwidth < pointdist)
1651 output = in_band(wipezone,hwidth,hyp,facf0,0,1);
1652 } else if(b2 > b1 && b2 > b3 ){
1653 if(hwidth < pointdist)
1654 output = in_band(wipezone,hwidth,hyp2,facf0,0,1);
1656 if( hyp < hwidth && hyp2 > hwidth )
1657 output = in_band(wipezone,hwidth,hyp,facf0,1,1);
1658 else if( hyp > hwidth && hyp2 < hwidth )
1659 output = in_band(wipezone,hwidth,hyp2,facf0,1,1);
1661 output = in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1);
1663 if(!wipe->forward)output = 1-output;
1667 temp1: angle of effect center in rads
1668 temp2: angle of line through (halfx,halfy) and (x,y) in rads
1669 temp3: angle of low side of blur
1670 temp4: angle of high side of blur
1672 output = 1.0f - facf0;
1673 widthf = wipe->edgeWidth*2.0f*(float)M_PI;
1674 temp1 = 2.0f * (float)M_PI * facf0;
1677 temp1 = 2.0f*(float)M_PI - temp1;
1683 temp2 = asin(abs(y)/sqrt(x*x + y*y));
1684 if(x <= 0 && y >= 0) temp2 = (float)M_PI - temp2;
1685 else if(x<=0 && y <= 0) temp2 += (float)M_PI;
1686 else if(x >= 0 && y <= 0) temp2 = 2.0f*(float)M_PI - temp2;
1689 temp3 = temp1-(widthf*0.5f)*facf0;
1690 temp4 = temp1+(widthf*0.5f)*(1-facf0);
1692 temp3 = temp1-(widthf*0.5f)*(1-facf0);
1693 temp4 = temp1+(widthf*0.5f)*facf0;
1695 if (temp3 < 0) temp3 = 0;
1696 if (temp4 > 2.0f*(float)M_PI) temp4 = 2.0f*(float)M_PI;
1699 if(temp2 < temp3) output = 0;
1700 else if (temp2 > temp4) output = 1;
1701 else output = (temp2-temp3)/(temp4-temp3);
1702 if(x == 0 && y == 0) output = 1;
1703 if(output != output) output = 1;
1704 if(wipe->forward) output = 1 - output;
1706 /* BOX WIPE IS NOT WORKING YET */
1707 /* case DO_CROSS_WIPE: */
1708 /* BOX WIPE IS NOT WORKING YET */
1711 if(invert)facf0 = 1-facf0;
1713 width = (int)(wipe->edgeWidth*((xo+yo)/2.0));
1714 hwidth = (float)width/2.0;
1715 if (angle == 0)angle = 0.000001;
1716 b1 = posy/2 - (-angle)*posx/2;
1717 b3 = (yo-posy/2) - (-angle)*(xo-posx/2);
1718 b2 = y - (-angle)*x;
1720 hyp = abs(angle*x+y+(-posy/2-angle*posx/2))*wipezone->pythangle;
1721 hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))*wipezone->pythangle;
1723 temp1 = xo*(1-facf0/2)-xo*facf0/2;
1724 temp2 = yo*(1-facf0/2)-yo*facf0/2;
1725 pointdist = sqrt(temp1*temp1 + temp2*temp2);
1727 if(b2 < b1 && b2 < b3 ){
1728 if(hwidth < pointdist)
1729 output = in_band(wipezone,hwidth,hyp,facf0,0,1);
1730 } else if(b2 > b1 && b2 > b3 ){
1731 if(hwidth < pointdist)
1732 output = in_band(wipezone,hwidth,hyp2,facf0,0,1);
1734 if( hyp < hwidth && hyp2 > hwidth )
1735 output = in_band(wipezone,hwidth,hyp,facf0,1,1);
1736 else if( hyp > hwidth && hyp2 < hwidth )
1737 output = in_band(wipezone,hwidth,hyp2,facf0,1,1);
1739 output = in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1);
1742 if(invert)facf0 = 1-facf0;
1744 b1 = posy/2 - (-angle)*posx/2;
1745 b3 = (yo-posy/2) - (-angle)*(xo-posx/2);
1746 b2 = y - (-angle)*x;
1748 hyp = abs(angle*x+y+(-posy/2-angle*posx/2))*wipezone->pythangle;
1749 hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))*wipezone->pythangle;
1751 if(b2 < b1 && b2 < b3 ){
1752 if(hwidth < pointdist)
1753 output *= in_band(wipezone,hwidth,hyp,facf0,0,1);
1754 } else if(b2 > b1 && b2 > b3 ){
1755 if(hwidth < pointdist)
1756 output *= in_band(wipezone,hwidth,hyp2,facf0,0,1);
1758 if( hyp < hwidth && hyp2 > hwidth )
1759 output *= in_band(wipezone,hwidth,hyp,facf0,1,1);
1760 else if( hyp > hwidth && hyp2 < hwidth )
1761 output *= in_band(wipezone,hwidth,hyp2,facf0,1,1);
1763 output *= in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1);
1769 if(xo > yo) yo = xo;
1772 if(!wipe->forward) facf0 = 1-facf0;
1774 width = wipezone->width;
1775 hwidth = width*0.5f;
1777 temp1 = (halfx-(halfx)*facf0);
1778 pointdist = sqrt(temp1*temp1 + temp1*temp1);
1780 temp2 = sqrt((halfx-x)*(halfx-x) + (halfy-y)*(halfy-y));
1781 if(temp2 > pointdist) output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,0,1);
1782 else output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,1,1);
1784 if(!wipe->forward) output = 1-output;
1788 if (output < 0) output = 0;
1789 else if(output > 1) output = 1;
1793 static void init_wipe_effect(Sequence *seq)
1795 if(seq->effectdata)MEM_freeN(seq->effectdata);
1796 seq->effectdata = MEM_callocN(sizeof(struct WipeVars), "wipevars");
1799 static int num_inputs_wipe()
1804 static void free_wipe_effect(Sequence *seq)
1806 if(seq->effectdata)MEM_freeN(seq->effectdata);
1807 seq->effectdata = 0;
1810 static void copy_wipe_effect(Sequence *dst, Sequence *src)
1812 dst->effectdata = MEM_dupallocN(src->effectdata);
1815 static void do_wipe_effect_byte(Sequence *seq, float facf0, float facf1,
1817 unsigned char *rect1,
1818 unsigned char *rect2, unsigned char *out)
1821 WipeVars *wipe = (WipeVars *)seq->effectdata;
1823 char *rt1, *rt2, *rt;
1825 precalc_wipe_zone(&wipezone, wipe, x, y);
1827 rt1 = (char *)rect1;
1828 rt2 = (char *)rect2;
1835 float check = check_zone(&wipezone,x,y,seq,facf0);
1838 rt[0] = (int)(rt1[0]*check)+ (int)(rt2[0]*(1-check));
1839 rt[1] = (int)(rt1[1]*check)+ (int)(rt2[1]*(1-check));
1840 rt[2] = (int)(rt1[2]*check)+ (int)(rt2[2]*(1-check));
1841 rt[3] = (int)(rt1[3]*check)+ (int)(rt2[3]*(1-check));
1873 static void do_wipe_effect_float(Sequence *seq, float facf0, float facf1,
1876 float *rect2, float *out)
1879 WipeVars *wipe = (WipeVars *)seq->effectdata;
1881 float *rt1, *rt2, *rt;
1883 precalc_wipe_zone(&wipezone, wipe, x, y);
1893 float check = check_zone(&wipezone,x,y,seq,facf0);
1896 rt[0] = rt1[0]*check+ rt2[0]*(1-check);
1897 rt[1] = rt1[1]*check+ rt2[1]*(1-check);
1898 rt[2] = rt1[2]*check+ rt2[2]*(1-check);
1899 rt[3] = rt1[3]*check+ rt2[3]*(1-check);
1931 static void do_wipe_effect(Sequence * seq,int cfra,
1932 float facf0, float facf1, int x, int y,
1933 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
1934 struct ImBuf *ibuf3, struct ImBuf *out)
1936 if (out->rect_float) {
1937 do_wipe_effect_float(seq,
1939 ibuf1->rect_float, ibuf2->rect_float,
1942 do_wipe_effect_byte(seq,
1944 (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect,
1945 (unsigned char*) out->rect);
1948 /* **********************************************************************
1950 ********************************************************************** */
1951 static void init_transform_effect(Sequence *seq)
1953 TransformVars *scale;
1955 if(seq->effectdata)MEM_freeN(seq->effectdata);
1956 seq->effectdata = MEM_callocN(sizeof(struct TransformVars), "transformvars");
1958 scale = (TransformVars *)seq->effectdata;
1959 scale->ScalexIni = 1;
1960 scale->ScaleyIni = 1;
1961 scale->ScalexFin = 1;
1962 scale->ScaleyFin = 1;
1972 scale->interpolation=1;
1976 static int num_inputs_transform()
1981 static void free_transform_effect(Sequence *seq)
1983 if(seq->effectdata)MEM_freeN(seq->effectdata);
1984 seq->effectdata = 0;
1987 static void copy_transform_effect(Sequence *dst, Sequence *src)
1989 dst->effectdata = MEM_dupallocN(src->effectdata);
1992 static void do_transform(Sequence * seq,float facf0, int x, int y,
1993 struct ImBuf *ibuf1,struct ImBuf *out)
1996 float xs,ys,factxScale,factyScale,tx,ty,rad,s,c,xaux,yaux,factRot,px,py;
1997 TransformVars *scale;
1999 // XXX struct RenderData *rd = NULL; // 2.5 global: &G.scene->r;
2002 scale = (TransformVars *)seq->effectdata;
2007 factxScale = scale->ScalexIni + (scale->ScalexFin - scale->ScalexIni) * facf0;
2008 factyScale = scale->ScaleyIni + (scale->ScaleyFin - scale->ScaleyIni) * facf0;
2011 if(!scale->percent){
2012 float rd_s = 0.0f; // XXX 2.5 global: (rd->size / 100.0f);
2014 tx = scale->xIni * rd_s+(xo / 2.0f) + (scale->xFin * rd_s -(xo / 2.0f) - scale->xIni * rd_s +(xo / 2.0f)) * facf0;
2015 ty = scale->yIni * rd_s+(yo / 2.0f) + (scale->yFin * rd_s -(yo / 2.0f) - scale->yIni * rd_s +(yo / 2.0f)) * facf0;
2017 tx = xo*(scale->xIni/100.0f)+(xo / 2.0f) + (xo*(scale->xFin/100.0f)-(xo / 2.0f) - xo*(scale->xIni/100.0f)+(xo / 2.0f)) * facf0;
2018 ty = yo*(scale->yIni/100.0f)+(yo / 2.0f) + (yo*(scale->yFin/100.0f)-(yo / 2.0f) - yo*(scale->yIni/100.0f)+(yo / 2.0f)) * facf0;
2022 factRot = scale->rotIni + (scale->rotFin - scale->rotIni) * facf0;
2023 rad = (M_PI * factRot) / 180.0f;
2028 for (yi = 0; yi < yo; yi++) {
2029 for (xi = 0; xi < xo; xi++) {
2034 //rotate point with center ref
2035 xaux = c*px + py*s ;
2036 yaux = -s*px + c*py;
2038 //scale point with center ref
2039 xs = xaux / factxScale;
2040 ys = yaux / factyScale;
2042 //undo reference center point
2047 switch(scale->interpolation) {
2049 neareast_interpolation(ibuf1,out, xs,ys,xi,yi);
2052 bilinear_interpolation(ibuf1,out, xs,ys,xi,yi);
2055 bicubic_interpolation(ibuf1,out, xs,ys,xi,yi);
2062 static void do_transform_effect(Sequence * seq,int cfra,
2063 float facf0, float facf1, int x, int y,
2064 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
2065 struct ImBuf *ibuf3, struct ImBuf *out)
2067 do_transform(seq, facf0, x, y, ibuf1, out);
2071 /* **********************************************************************
2073 ********************************************************************** */
2075 static void RVBlurBitmap2_byte ( unsigned char* map, int width,int height,
2078 /* MUUUCCH better than the previous blur. */
2079 /* We do the blurring in two passes which is a whole lot faster. */
2080 /* I changed the math arount to implement an actual Gaussian */
2083 /* Watch out though, it tends to misbehaven with large blur values on */
2084 /* a small bitmap. Avoid avoid avoid. */
2085 /*=============================== */
2087 unsigned char* temp=NULL,*swap;
2090 int index, ix, halfWidth;
2091 float fval, k, curColor[3], curColor2[3], weight=0;
2093 /* If we're not really blurring, bail out */
2097 /* Allocate memory for the tempmap and the blur filter matrix */
2098 temp= MEM_mallocN( (width*height*4), "blurbitmaptemp");
2102 /* Allocate memory for the filter elements */
2103 halfWidth = ((quality+1)*blur);
2104 filter = (float *)MEM_mallocN(sizeof(float)*halfWidth*2, "blurbitmapfilter");
2110 /* Apparently we're calculating a bell curve */
2111 /* based on the standard deviation (or radius) */
2112 /* This code is based on an example */
2113 /* posted to comp.graphics.algorithms by */
2114 /* Blancmange (bmange@airdmhor.gen.nz) */
2116 k = -1.0/(2.0*3.14159*blur*blur);
2118 for (ix = 0;ix< halfWidth;ix++){
2119 weight = (float)exp(k*(ix*ix));
2120 filter[halfWidth - ix] = weight;
2121 filter[halfWidth + ix] = weight;
2125 /* Normalize the array */
2127 for (ix = 0;ix< halfWidth*2;ix++)
2130 for (ix = 0;ix< halfWidth*2;ix++)
2134 for (y=0;y<height;y++){
2135 /* Do the left & right strips */
2136 for (x=0;x<halfWidth;x++){
2137 index=(x+y*width)*4;
2139 curColor[0]=curColor[1]=curColor[2]=0;
2140 curColor2[0]=curColor2[1]=curColor2[2]=0;
2142 for (i=x-halfWidth;i<x+halfWidth;i++){
2143 if ((i>=0)&&(i<width)){
2144 curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
2145 curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
2146 curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
2148 curColor2[0]+=map[(width-1-i+y*width)*4+GlowR] *
2150 curColor2[1]+=map[(width-1-i+y*width)*4+GlowG] *
2152 curColor2[2]+=map[(width-1-i+y*width)*4+GlowB] *
2157 temp[index+GlowR]=curColor[0];
2158 temp[index+GlowG]=curColor[1];
2159 temp[index+GlowB]=curColor[2];
2161 temp[((width-1-x+y*width)*4)+GlowR]=curColor2[0];
2162 temp[((width-1-x+y*width)*4)+GlowG]=curColor2[1];
2163 temp[((width-1-x+y*width)*4)+GlowB]=curColor2[2];
2166 /* Do the main body */
2167 for (x=halfWidth;x<width-halfWidth;x++){
2168 index=(x+y*width)*4;
2170 curColor[0]=curColor[1]=curColor[2]=0;
2171 for (i=x-halfWidth;i<x+halfWidth;i++){
2172 curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
2173 curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
2174 curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
2177 temp[index+GlowR]=curColor[0];
2178 temp[index+GlowG]=curColor[1];
2179 temp[index+GlowB]=curColor[2];
2184 swap=temp;temp=map;map=swap;
2187 /* Blur the columns */
2188 for (x=0;x<width;x++){
2189 /* Do the top & bottom strips */
2190 for (y=0;y<halfWidth;y++){
2191 index=(x+y*width)*4;
2193 curColor[0]=curColor[1]=curColor[2]=0;
2194 curColor2[0]=curColor2[1]=curColor2[2]=0;
2195 for (i=y-halfWidth;i<y+halfWidth;i++){
2196 if ((i>=0)&&(i<height)){
2198 curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
2199 curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
2200 curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
2203 curColor2[0]+=map[(x+(height-1-i)*width) *
2204 4+GlowR]*filter[fy];
2205 curColor2[1]+=map[(x+(height-1-i)*width) *
2206 4+GlowG]*filter[fy];
2207 curColor2[2]+=map[(x+(height-1-i)*width) *
2208 4+GlowB]*filter[fy];
2212 temp[index+GlowR]=curColor[0];
2213 temp[index+GlowG]=curColor[1];
2214 temp[index+GlowB]=curColor[2];
2215 temp[((x+(height-1-y)*width)*4)+GlowR]=curColor2[0];
2216 temp[((x+(height-1-y)*width)*4)+GlowG]=curColor2[1];
2217 temp[((x+(height-1-y)*width)*4)+GlowB]=curColor2[2];
2219 /* Do the main body */
2220 for (y=halfWidth;y<height-halfWidth;y++){
2221 index=(x+y*width)*4;
2223 curColor[0]=curColor[1]=curColor[2]=0;
2224 for (i=y-halfWidth;i<y+halfWidth;i++){
2225 curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
2226 curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
2227 curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
2230 temp[index+GlowR]=curColor[0];
2231 temp[index+GlowG]=curColor[1];
2232 temp[index+GlowB]=curColor[2];
2238 swap=temp;temp=map;map=swap;
2245 static void RVBlurBitmap2_float ( float* map, int width,int height,
2248 /* MUUUCCH better than the previous blur. */
2249 /* We do the blurring in two passes which is a whole lot faster. */
2250 /* I changed the math arount to implement an actual Gaussian */
2253 /* Watch out though, it tends to misbehaven with large blur values on */
2254 /* a small bitmap. Avoid avoid avoid. */
2255 /*=============================== */
2257 float* temp=NULL,*swap;
2260 int index, ix, halfWidth;
2261 float fval, k, curColor[3], curColor2[3], weight=0;
2263 /* If we're not really blurring, bail out */
2267 /* Allocate memory for the tempmap and the blur filter matrix */
2268 temp= MEM_mallocN( (width*height*4*sizeof(float)), "blurbitmaptemp");
2272 /* Allocate memory for the filter elements */
2273 halfWidth = ((quality+1)*blur);
2274 filter = (float *)MEM_mallocN(sizeof(float)*halfWidth*2, "blurbitmapfilter");
2280 /* Apparently we're calculating a bell curve */
2281 /* based on the standard deviation (or radius) */
2282 /* This code is based on an example */
2283 /* posted to comp.graphics.algorithms by */
2284 /* Blancmange (bmange@airdmhor.gen.nz) */
2286 k = -1.0/(2.0*3.14159*blur*blur);
2288 for (ix = 0;ix< halfWidth;ix++){
2289 weight = (float)exp(k*(ix*ix));
2290 filter[halfWidth - ix] = weight;
2291 filter[halfWidth + ix] = weight;
2295 /* Normalize the array */
2297 for (ix = 0;ix< halfWidth*2;ix++)
2300 for (ix = 0;ix< halfWidth*2;ix++)
2304 for (y=0;y<height;y++){
2305 /* Do the left & right strips */
2306 for (x=0;x<halfWidth;x++){
2307 index=(x+y*width)*4;
2309 curColor[0]=curColor[1]=curColor[2]=0.0f;
2310 curColor2[0]=curColor2[1]=curColor2[2]=0.0f;
2312 for (i=x-halfWidth;i<x+halfWidth;i++){
2313 if ((i>=0)&&(i<width)){
2314 curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
2315 curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
2316 curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
2318 curColor2[0]+=map[(width-1-i+y*width)*4+GlowR] *
2320 curColor2[1]+=map[(width-1-i+y*width)*4+GlowG] *
2322 curColor2[2]+=map[(width-1-i+y*width)*4+GlowB] *
2327 temp[index+GlowR]=curColor[0];
2328 temp[index+GlowG]=curColor[1];
2329 temp[index+GlowB]=curColor[2];
2331 temp[((width-1-x+y*width)*4)+GlowR]=curColor2[0];
2332 temp[((width-1-x+y*width)*4)+GlowG]=curColor2[1];
2333 temp[((width-1-x+y*width)*4)+GlowB]=curColor2[2];
2336 /* Do the main body */
2337 for (x=halfWidth;x<width-halfWidth;x++){
2338 index=(x+y*width)*4;
2340 curColor[0]=curColor[1]=curColor[2]=0;
2341 for (i=x-halfWidth;i<x+halfWidth;i++){
2342 curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
2343 curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
2344 curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
2347 temp[index+GlowR]=curColor[0];
2348 temp[index+GlowG]=curColor[1];
2349 temp[index+GlowB]=curColor[2];
2354 swap=temp;temp=map;map=swap;
2357 /* Blur the columns */
2358 for (x=0;x<width;x++){
2359 /* Do the top & bottom strips */
2360 for (y=0;y<halfWidth;y++){
2361 index=(x+y*width)*4;
2363 curColor[0]=curColor[1]=curColor[2]=0;
2364 curColor2[0]=curColor2[1]=curColor2[2]=0;
2365 for (i=y-halfWidth;i<y+halfWidth;i++){
2366 if ((i>=0)&&(i<height)){
2368 curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
2369 curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
2370 curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
2373 curColor2[0]+=map[(x+(height-1-i)*width) *
2374 4+GlowR]*filter[fy];
2375 curColor2[1]+=map[(x+(height-1-i)*width) *
2376 4+GlowG]*filter[fy];
2377 curColor2[2]+=map[(x+(height-1-i)*width) *
2378 4+GlowB]*filter[fy];
2382 temp[index+GlowR]=curColor[0];
2383 temp[index+GlowG]=curColor[1];
2384 temp[index+GlowB]=curColor[2];
2385 temp[((x+(height-1-y)*width)*4)+GlowR]=curColor2[0];
2386 temp[((x+(height-1-y)*width)*4)+GlowG]=curColor2[1];
2387 temp[((x+(height-1-y)*width)*4)+GlowB]=curColor2[2];
2389 /* Do the main body */
2390 for (y=halfWidth;y<height-halfWidth;y++){
2391 index=(x+y*width)*4;
2393 curColor[0]=curColor[1]=curColor[2]=0;
2394 for (i=y-halfWidth;i<y+halfWidth;i++){
2395 curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
2396 curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
2397 curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
2400 temp[index+GlowR]=curColor[0];
2401 temp[index+GlowG]=curColor[1];
2402 temp[index+GlowB]=curColor[2];
2408 swap=temp;temp=map;map=swap;
2416 /* Adds two bitmaps and puts the results into a third map. */
2417 /* C must have been previously allocated but it may be A or B. */
2418 /* We clamp values to 255 to prevent weirdness */
2419 /*=============================== */
2420 static void RVAddBitmaps_byte (unsigned char* a, unsigned char* b, unsigned char* c, int width, int height)
2424 for (y=0;y<height;y++){
2425 for (x=0;x<width;x++){
2426 index=(x+y*width)*4;
2427 c[index+GlowR]=MIN2(255,a[index+GlowR]+b[index+GlowR]);
2428 c[index+GlowG]=MIN2(255,a[index+GlowG]+b[index+GlowG]);
2429 c[index+GlowB]=MIN2(255,a[index+GlowB]+b[index+GlowB]);
2430 c[index+GlowA]=MIN2(255,a[index+GlowA]+b[index+GlowA]);
2435 static void RVAddBitmaps_float (float* a, float* b, float* c,
2436 int width, int height)
2440 for (y=0;y<height;y++){
2441 for (x=0;x<width;x++){
2442 index=(x+y*width)*4;
2443 c[index+GlowR]=MIN2(1.0,a[index+GlowR]+b[index+GlowR]);
2444 c[index+GlowG]=MIN2(1.0,a[index+GlowG]+b[index+GlowG]);
2445 c[index+GlowB]=MIN2(1.0,a[index+GlowB]+b[index+GlowB]);
2446 c[index+GlowA]=MIN2(1.0,a[index+GlowA]+b[index+GlowA]);
2451 /* For each pixel whose total luminance exceeds the threshold, */
2452 /* Multiply it's value by BOOST and add it to the output map */
2453 static void RVIsolateHighlights_byte (unsigned char* in, unsigned char* out,
2454 int width, int height, int threshold,
2455 float boost, float clamp)
2461 for(y=0;y< height;y++) {
2462 for (x=0;x< width;x++) {
2463 index= (x+y*width)*4;
2465 /* Isolate the intensity */
2466 intensity=(in[index+GlowR]+in[index+GlowG]+in[index+GlowB]-threshold);
2468 out[index+GlowR]=MIN2(255*clamp, (in[index+GlowR]*boost*intensity)/255);
2469 out[index+GlowG]=MIN2(255*clamp, (in[index+GlowG]*boost*intensity)/255);
2470 out[index+GlowB]=MIN2(255*clamp, (in[index+GlowB]*boost*intensity)/255);
2471 out[index+GlowA]=MIN2(255*clamp, (in[index+GlowA]*boost*intensity)/255);
2482 static void RVIsolateHighlights_float (float* in, float* out,
2483 int width, int height, float threshold,
2484 float boost, float clamp)
2490 for(y=0;y< height;y++) {
2491 for (x=0;x< width;x++) {
2492 index= (x+y*width)*4;
2494 /* Isolate the intensity */
2495 intensity=(in[index+GlowR]+in[index+GlowG]+in[index+GlowB]-threshold);
2497 out[index+GlowR]=MIN2(clamp, (in[index+GlowR]*boost*intensity));
2498 out[index+GlowG]=MIN2(clamp, (in[index+GlowG]*boost*intensity));
2499 out[index+GlowB]=MIN2(clamp, (in[index+GlowB]*boost*intensity));
2500 out[index+GlowA]=MIN2(clamp, (in[index+GlowA]*boost*intensity));
2511 static void init_glow_effect(Sequence *seq)
2515 if(seq->effectdata)MEM_freeN(seq->effectdata);
2516 seq->effectdata = MEM_callocN(sizeof(struct GlowVars), "glowvars");
2518 glow = (GlowVars *)seq->effectdata;
2527 static int num_inputs_glow()
2532 static void free_glow_effect(Sequence *seq)
2534 if(seq->effectdata)MEM_freeN(seq->effectdata);
2535 seq->effectdata = 0;
2538 static void copy_glow_effect(Sequence *dst, Sequence *src)
2540 dst->effectdata = MEM_dupallocN(src->effectdata);
2543 //void do_glow_effect(Cast *cast, float facf0, float facf1, int xo, int yo, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *outbuf, ImBuf *use)
2544 static void do_glow_effect_byte(Sequence *seq, float facf0, float facf1,
2545 int x, int y, char *rect1,
2546 char *rect2, char *out)
2548 unsigned char *outbuf=(unsigned char *)out;
2549 unsigned char *inbuf=(unsigned char *)rect1;
2550 GlowVars *glow = (GlowVars *)seq->effectdata;
2551 int size= 100; // renderdata XXX
2553 RVIsolateHighlights_byte(inbuf, outbuf , x, y, glow->fMini*765, glow->fBoost * facf0, glow->fClamp);
2554 RVBlurBitmap2_byte (outbuf, x, y, glow->dDist * (size / 100.0f),glow->dQuality);
2556 RVAddBitmaps_byte (inbuf , outbuf, outbuf, x, y);
2559 static void do_glow_effect_float(Sequence *seq, float facf0, float facf1,
2561 float *rect1, float *rect2, float *out)
2563 float *outbuf = out;
2564 float *inbuf = rect1;
2565 GlowVars *glow = (GlowVars *)seq->effectdata;
2566 int size= 100; // renderdata XXX
2568 RVIsolateHighlights_float(inbuf, outbuf , x, y, glow->fMini*3.0f, glow->fBoost * facf0, glow->fClamp);
2569 RVBlurBitmap2_float (outbuf, x, y, glow->dDist * (size / 100.0f),glow->dQuality);
2571 RVAddBitmaps_float (inbuf , outbuf, outbuf, x, y);
2574 static void do_glow_effect(Sequence * seq,int cfra,
2575 float facf0, float facf1, int x, int y,
2576 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
2577 struct ImBuf *ibuf3, struct ImBuf *out)
2579 if (out->rect_float) {
2580 do_glow_effect_float(seq,
2582 ibuf1->rect_float, ibuf2->rect_float,
2585 do_glow_effect_byte(seq,
2587 (char*) ibuf1->rect, (char*) ibuf2->rect,
2592 /* **********************************************************************
2594 ********************************************************************** */
2596 static void init_solid_color(Sequence *seq)
2600 if(seq->effectdata)MEM_freeN(seq->effectdata);
2601 seq->effectdata = MEM_callocN(sizeof(struct SolidColorVars), "solidcolor");
2603 cv = (SolidColorVars *)seq->effectdata;
2604 cv->col[0] = cv->col[1] = cv->col[2] = 0.5;
2607 static int num_inputs_color()
2612 static void free_solid_color(Sequence *seq)
2614 if(seq->effectdata)MEM_freeN(seq->effectdata);
2615 seq->effectdata = 0;
2618 static void copy_solid_color(Sequence *dst, Sequence *src)
2620 dst->effectdata = MEM_dupallocN(src->effectdata);
2623 static int early_out_color(struct Sequence *seq,
2624 float facf0, float facf1)
2629 static void do_solid_color(Sequence * seq,int cfra,
2630 float facf0, float facf1, int x, int y,
2631 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
2632 struct ImBuf *ibuf3, struct ImBuf *out)
2634 SolidColorVars *cv = (SolidColorVars *)seq->effectdata;
2636 unsigned char *rect;
2640 unsigned char col0[3];
2641 unsigned char col1[3];
2643 col0[0] = facf0 * cv->col[0] * 255;
2644 col0[1] = facf0 * cv->col[1] * 255;
2645 col0[2] = facf0 * cv->col[2] * 255;
2647 col1[0] = facf1 * cv->col[0] * 255;
2648 col1[1] = facf1 * cv->col[1] * 255;
2649 col1[2] = facf1 * cv->col[2] * 255;
2651 rect = (unsigned char *)out->rect;
2653 for(y=0; y<out->y; y++) {
2654 for(x=0; x<out->x; x++, rect+=4) {
2662 for(x=0; x<out->x; x++, rect+=4) {
2671 } else if (out->rect_float) {
2675 col0[0] = facf0 * cv->col[0];
2676 col0[1] = facf0 * cv->col[1];
2677 col0[2] = facf0 * cv->col[2];
2679 col1[0] = facf1 * cv->col[0];
2680 col1[1] = facf1 * cv->col[1];
2681 col1[2] = facf1 * cv->col[2];
2683 rect_float = out->rect_float;
2685 for(y=0; y<out->y; y++) {
2686 for(x=0; x<out->x; x++, rect_float+=4) {
2687 rect_float[0]= col0[0];
2688 rect_float[1]= col0[1];
2689 rect_float[2]= col0[2];
2694 for(x=0; x<out->x; x++, rect_float+=4) {
2695 rect_float[0]= col1[0];
2696 rect_float[1]= col1[1];
2697 rect_float[2]= col1[2];
2705 /* **********************************************************************
2707 ********************************************************************** */
2708 static void init_speed_effect(Sequence *seq)
2710 SpeedControlVars * v;
2712 if(seq->effectdata) MEM_freeN(seq->effectdata);
2713 seq->effectdata = MEM_callocN(sizeof(struct SpeedControlVars),
2714 "speedcontrolvars");
2716 v = (SpeedControlVars *)seq->effectdata;
2717 v->globalSpeed = 1.0;
2719 v->flags = SEQ_SPEED_COMPRESS_IPO_Y;
2723 static void load_speed_effect(Sequence * seq)
2725 SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
2731 static int num_inputs_speed()
2736 static void free_speed_effect(Sequence *seq)
2738 SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
2739 if(v->frameMap) MEM_freeN(v->frameMap);
2740 if(seq->effectdata) MEM_freeN(seq->effectdata);
2741 seq->effectdata = 0;
2744 static void copy_speed_effect(Sequence *dst, Sequence *src)
2746 SpeedControlVars * v;
2747 dst->effectdata = MEM_dupallocN(src->effectdata);
2748 v = (SpeedControlVars *)dst->effectdata;
2753 static int early_out_speed(struct Sequence *seq,
2754 float facf0, float facf1)
2759 static void store_icu_yrange_speed(struct Sequence * seq,
2760 short adrcode, float * ymin, float * ymax)
2762 SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
2764 /* if not already done, load / initialize data */
2765 get_sequence_effect(seq);
2767 if ((v->flags & SEQ_SPEED_INTEGRATE) != 0) {
2771 if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
2781 void sequence_effect_speed_rebuild_map(Sequence * seq, int force)
2783 float facf0 = seq->facf0;
2787 SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
2789 /* if not already done, load / initialize data */
2790 get_sequence_effect(seq);
2792 if (!(force || seq->len != v->length || !v->frameMap)) {
2796 if (!v->frameMap || v->length != seq->len) {
2797 if (v->frameMap) MEM_freeN(v->frameMap);
2799 v->length = seq->len;
2801 v->frameMap = MEM_callocN(sizeof(float) * v->length,
2802 "speedcontrol frameMap");
2807 /* if there is no IPO, try to make retiming easy by stretching the
2809 // XXX old animation system - seq
2810 if (/*!seq->ipo &&*/ seq->seq1 && seq->seq1->enddisp != seq->seq1->start
2811 && seq->seq1->len != 0) {
2812 fallback_fac = (float) seq->seq1->len /
2813 (float) (seq->seq1->enddisp - seq->seq1->start);
2814 /* FIXME: this strip stretching gets screwed by stripdata
2815 handling one layer up.
2817 So it currently works by enlarging, never by shrinking!
2819 (IPOs still work, if used correctly)
2821 if (fallback_fac > 1.0) {
2826 if ((v->flags & SEQ_SPEED_INTEGRATE) != 0) {
2830 v->lastValidFrame = 0;
2832 for (cfra = 1; cfra < v->length; cfra++) {
2833 #if 0 // XXX old animation system
2835 if((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) {
2836 ctime = frame_to_float(scene, seq->startdisp + cfra);
2839 ctime= frame_to_float(scene, cfra);
2840 div= v->length / 100.0f;
2841 if(div==0.0) return;
2844 calc_ipo(seq->ipo, ctime/div);
2845 execute_ipo((ID *)seq, seq->ipo);
2847 #endif // XXX old animation system
2849 seq->facf0 = fallback_fac;
2851 seq->facf0 *= v->globalSpeed;
2853 cursor += seq->facf0;
2855 if (cursor >= v->length) {
2856 v->frameMap[cfra] = v->length - 1;
2858 v->frameMap[cfra] = cursor;
2859 v->lastValidFrame = cfra;
2863 v->lastValidFrame = 0;
2864 for (cfra = 0; cfra < v->length; cfra++) {
2865 #if 0 // XXX old animation system
2867 if((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) {
2868 ctime = frame_to_float(scene, seq->startdisp + cfra);
2871 ctime= frame_to_float(scene, cfra);
2872 div= v->length / 100.0f;
2873 if(div==0.0) return;
2876 calc_ipo(seq->ipo, ctime/div);
2877 execute_ipo((ID *)seq, seq->ipo);
2879 #endif // XXX old animation system
2881 if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
2882 seq->facf0 *= v->length;
2884 if (/*!seq->ipo*/ 1) { // XXX old animation system - seq
2885 seq->facf0 = (float) cfra * fallback_fac;
2887 seq->facf0 *= v->globalSpeed;
2888 if (seq->facf0 >= v->length) {
2889 seq->facf0 = v->length - 1;
2891 v->lastValidFrame = cfra;
2893 v->frameMap[cfra] = seq->facf0;
2900 simply reuse do_cross_effect for blending...
2902 static void do_speed_effect(Sequence * seq,int cfra,
2903 float facf0, float facf1, int x, int y,
2904 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
2905 struct ImBuf *ibuf3, struct ImBuf *out)
2912 /* **********************************************************************
2913 sequence effect factory
2914 ********************************************************************** */
2917 static void init_noop(struct Sequence *seq)
2922 static void load_noop(struct Sequence *seq)
2927 static void init_plugin_noop(struct Sequence *seq, const char * fname)
2932 static void free_noop(struct Sequence *seq)
2937 static int num_inputs_default()
2942 static int early_out_noop(struct Sequence *seq,
2943 float facf0, float facf1)
2948 static int early_out_fade(struct Sequence *seq,
2949 float facf0, float facf1)
2951 if (facf0 == 0.0 && facf1 == 0.0) {
2953 } else if (facf0 == 1.0 && facf1 == 1.0) {
2959 static int early_out_mul_input2(struct Sequence *seq,
2960 float facf0, float facf1)
2962 if (facf0 == 0.0 && facf1 == 0.0) {
2968 static void store_icu_yrange_noop(struct Sequence * seq,
2969 short adrcode, float * ymin, float * ymax)
2971 /* defaults are fine */
2974 static void get_default_fac_noop(struct Sequence *seq, int cfra,
2975 float * facf0, float * facf1)
2977 *facf0 = *facf1 = 1.0;
2980 static void get_default_fac_fade(struct Sequence *seq, int cfra,
2981 float * facf0, float * facf1)
2983 *facf0 = (float)(cfra - seq->startdisp);
2984 *facf1 = (float)(*facf0 + 0.5);
2989 static void do_overdrop_effect(struct Sequence * seq, int cfra,
2990 float fac, float facf,
2991 int x, int y, struct ImBuf * ibuf1,
2992 struct ImBuf * ibuf2,
2993 struct ImBuf * ibuf3,
2996 do_drop_effect(seq, cfra, fac, facf, x, y,
2997 ibuf1, ibuf2, ibuf3, out);
2998 do_alphaover_effect(seq, cfra, fac, facf, x, y,
2999 ibuf1, ibuf2, ibuf3, out);
3002 static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
3004 struct SeqEffectHandle rval;
3005 int sequence_type = seq_type;
3007 rval.init = init_noop;
3008 rval.init_plugin = init_plugin_noop;
3009 rval.num_inputs = num_inputs_default;
3010 rval.load = load_noop;
3011 rval.free = free_noop;
3012 rval.early_out = early_out_noop;
3013 rval.get_default_fac = get_default_fac_noop;
3014 rval.store_icu_yrange = store_icu_yrange_noop;
3015 rval.execute = NULL;
3018 switch (sequence_type) {
3020 rval.execute = do_cross_effect;
3021 rval.early_out = early_out_fade;
3022 rval.get_default_fac = get_default_fac_fade;
3025 rval.init = init_gammacross;
3026 rval.load = load_gammacross;
3027 rval.free = free_gammacross;
3028 rval.early_out = early_out_fade;
3029 rval.get_default_fac = get_default_fac_fade;
3030 rval.execute = do_gammacross_effect;
3033 rval.execute = do_add_effect;
3034 rval.early_out = early_out_mul_input2;
3037 rval.execute = do_sub_effect;
3038 rval.early_out = early_out_mul_input2;
3041 rval.execute = do_mul_effect;
3042 rval.early_out = early_out_mul_input2;
3045 rval.init = init_alpha_over_or_under;
3046 rval.execute = do_alphaover_effect;
3049 rval.execute = do_overdrop_effect;
3051 case SEQ_ALPHAUNDER:
3052 rval.init = init_alpha_over_or_under;
3053 rval.execute = do_alphaunder_effect;
3056 rval.init = init_wipe_effect;
3057 rval.num_inputs = num_inputs_wipe;
3058 rval.free = free_wipe_effect;
3059 rval.copy = copy_wipe_effect;
3060 rval.early_out = early_out_fade;
3061 rval.get_default_fac = get_default_fac_fade;
3062 rval.execute = do_wipe_effect;
3065 rval.init = init_glow_effect;
3066 rval.num_inputs = num_inputs_glow;
3067 rval.free = free_glow_effect;
3068 rval.copy = copy_glow_effect;
3069 rval.execute = do_glow_effect;
3072 rval.init = init_transform_effect;
3073 rval.num_inputs = num_inputs_transform;
3074 rval.free = free_transform_effect;
3075 rval.copy = copy_transform_effect;
3076 rval.execute = do_transform_effect;
3079 rval.init = init_speed_effect;
3080 rval.num_inputs = num_inputs_speed;
3081 rval.load = load_speed_effect;
3082 rval.free = free_speed_effect;
3083 rval.copy = copy_speed_effect;
3084 rval.execute = do_cross_effect;
3085 rval.early_out = early_out_speed;
3086 rval.store_icu_yrange = store_icu_yrange_speed;
3089 rval.init = init_solid_color;
3090 rval.num_inputs = num_inputs_color;
3091 rval.early_out = early_out_color;
3092 rval.free = free_solid_color;
3093 rval.copy = copy_solid_color;
3094 rval.execute = do_solid_color;