2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
22 * - Blender Foundation, 2003-2009
23 * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
25 * ***** END GPL LICENSE BLOCK *****
28 /** \file blender/blenkernel/intern/seqeffects.c
37 #include "MEM_guardedalloc.h"
38 #include "BLI_dynlib.h"
40 #include "BLI_math.h" /* windows needs for M_PI */
41 #include "BLI_utildefines.h"
42 #include "BLI_string.h"
44 #include "DNA_scene_types.h"
45 #include "DNA_sequence_types.h"
46 #include "DNA_anim_types.h"
48 #include "BKE_fcurve.h"
50 #include "BKE_plugin_types.h"
51 #include "BKE_sequencer.h"
52 #include "BKE_texture.h"
53 #include "BKE_utildefines.h"
55 #include "IMB_imbuf_types.h"
56 #include "IMB_imbuf.h"
58 #include "RNA_access.h"
61 static void error(const char *UNUSED(error), ...) {}
76 static ImBuf *prepare_effect_imbufs(
77 SeqRenderData context,
78 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
82 int x = context.rectx;
83 int y = context.recty;
85 if (!ibuf1 && !ibuf2 && !ibuf3) {
86 /* hmmm, global float option ? */
87 out = IMB_allocImBuf((short)x, (short)y, 32, IB_rect);
89 else if ((ibuf1 && ibuf1->rect_float) ||
90 (ibuf2 && ibuf2->rect_float) ||
91 (ibuf3 && ibuf3->rect_float))
93 /* if any inputs are rectfloat, output is float too */
95 out = IMB_allocImBuf((short)x, (short)y, 32, IB_rectfloat);
98 out = IMB_allocImBuf((short)x, (short)y, 32, IB_rect);
101 if (ibuf1 && !ibuf1->rect_float && out->rect_float) {
102 IMB_float_from_rect_simple(ibuf1);
104 if (ibuf2 && !ibuf2->rect_float && out->rect_float) {
105 IMB_float_from_rect_simple(ibuf2);
107 if (ibuf3 && !ibuf3->rect_float && out->rect_float) {
108 IMB_float_from_rect_simple(ibuf3);
111 if (ibuf1 && !ibuf1->rect && !out->rect_float) {
112 IMB_rect_from_float(ibuf1);
114 if (ibuf2 && !ibuf2->rect && !out->rect_float) {
115 IMB_rect_from_float(ibuf2);
117 if (ibuf3 && !ibuf3->rect && !out->rect_float) {
118 IMB_rect_from_float(ibuf3);
124 /* **********************************************************************
126 * ********************************************************************** */
128 static void open_plugin_seq(PluginSeq *pis, const char *seqname)
130 int (*version)(void);
131 void * (*alloc_private)(void);
134 /* to be sure: (is tested for) */
140 pis->instance_private_data = NULL;
142 /* clear the error list */
143 BLI_dynlib_get_error_as_string(NULL);
145 /* if (pis->handle) BLI_dynlib_close(pis->handle); */
146 /* pis->handle = 0; */
148 /* open the needed object */
149 pis->handle = BLI_dynlib_open(pis->name);
150 if (test_dlerr(pis->name, pis->name)) return;
152 if (pis->handle != NULL) {
153 /* find the address of the version function */
154 version = (int (*)(void))BLI_dynlib_find_symbol(pis->handle, "plugin_seq_getversion");
155 if (test_dlerr(pis->name, "plugin_seq_getversion")) return;
157 if (version != NULL) {
158 pis->version = version();
159 if (pis->version >= 2 && pis->version <= 6) {
160 int (*info_func)(PluginInfo *);
161 PluginInfo *info = (PluginInfo *) MEM_mallocN(sizeof(PluginInfo), "plugin_info");
163 info_func = (int (*)(PluginInfo *))BLI_dynlib_find_symbol(pis->handle, "plugin_getinfo");
165 if (info_func == NULL) error("No info func");
169 pis->pname = info->name;
170 pis->vars = info->nvars;
171 pis->cfra = info->cfra;
173 pis->varstr = info->varstr;
175 pis->doit = (void (*)(void))info->seq_doit;
181 cp = BLI_dynlib_find_symbol(pis->handle, "seqname");
182 if (cp) BLI_strncpy(cp, seqname, SEQ_NAME_MAXSTR);
185 printf("Plugin returned unrecognized version number\n");
189 alloc_private = (void * (*)(void))BLI_dynlib_find_symbol(
190 pis->handle, "plugin_seq_alloc_private_data");
192 pis->instance_private_data = alloc_private();
195 pis->current_private_data = (void **)
196 BLI_dynlib_find_symbol(pis->handle, "plugin_private_data");
200 static PluginSeq *add_plugin_seq(const char *str, const char *seqname)
206 pis = MEM_callocN(sizeof(PluginSeq), "PluginSeq");
208 BLI_strncpy(pis->name, str, FILE_MAX);
209 open_plugin_seq(pis, seqname);
211 if (pis->doit == NULL) {
212 if (pis->handle == NULL) error("no plugin: %s", str);
213 else error("in plugin: %s", str);
219 varstr = pis->varstr;
220 for (a = 0; a < pis->vars; a++, varstr++) {
221 if ( (varstr->type & FLO) == FLO)
222 pis->data[a] = varstr->def;
223 else if ( (varstr->type & INT) == INT)
224 *((int *)(pis->data + a)) = (int) varstr->def;
230 static void free_plugin_seq(PluginSeq *pis)
232 if (pis == NULL) return;
234 /* no BLI_dynlib_close: same plugin can be opened multiple times with 1 handle */
236 if (pis->instance_private_data) {
237 void (*free_private)(void *);
239 free_private = (void (*)(void *))BLI_dynlib_find_symbol(
240 pis->handle, "plugin_seq_free_private_data");
242 free_private(pis->instance_private_data);
249 static void init_plugin(Sequence *seq, const char *fname)
251 seq->plugin = (PluginSeq *)add_plugin_seq(fname, seq->name + 2);
255 * FIXME: should query plugin! Could be generator, that needs zero inputs...
257 static int num_inputs_plugin(void)
262 static void load_plugin(Sequence *seq)
265 open_plugin_seq(seq->plugin, seq->name + 2);
269 static void copy_plugin(Sequence *dst, Sequence *src)
272 dst->plugin = MEM_dupallocN(src->plugin);
273 open_plugin_seq(dst->plugin, dst->name + 2);
277 static ImBuf *IMB_cast_away_list(ImBuf *i)
282 return (ImBuf *) (((void **) i) + 2);
285 static ImBuf *do_plugin_effect(
286 SeqRenderData context, Sequence *seq, float cfra,
287 float facf0, float facf1,
288 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
293 int use_temp_bufs = FALSE; /* Are needed since blur.c (and maybe some other
294 * old plugins) do very bad stuff
295 * with imbuf-internals */
297 struct ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
298 int x = context.rectx;
299 int y = context.recty;
301 if (seq->plugin && seq->plugin->doit) {
303 if (seq->plugin->cfra)
304 *(seq->plugin->cfra) = cfra;
306 cp = BLI_dynlib_find_symbol(
307 seq->plugin->handle, "seqname");
309 /* XXX: it's crappy to limit copying buffer by it's lemgth,
310 * but assuming plugin stuff is using correct buffer size
311 * it should be fine */
312 if (cp) strncpy(cp, seq->name + 2, sizeof(seq->name) - 2);
314 if (seq->plugin->current_private_data) {
315 *seq->plugin->current_private_data = seq->plugin->instance_private_data;
318 float_rendering = (out->rect_float != NULL);
320 if (seq->plugin->version <= 3 && float_rendering) {
321 use_temp_bufs = TRUE;
324 ibuf1 = IMB_dupImBuf(ibuf1);
325 IMB_rect_from_float(ibuf1);
326 imb_freerectfloatImBuf(ibuf1);
327 ibuf1->flags &= ~IB_rectfloat;
330 ibuf2 = IMB_dupImBuf(ibuf2);
331 IMB_rect_from_float(ibuf2);
332 imb_freerectfloatImBuf(ibuf2);
333 ibuf2->flags &= ~IB_rectfloat;
336 ibuf3 = IMB_dupImBuf(ibuf3);
337 IMB_rect_from_float(ibuf3);
338 imb_freerectfloatImBuf(ibuf3);
339 ibuf3->flags &= ~IB_rectfloat;
341 if (!out->rect) imb_addrectImBuf(out);
342 imb_freerectfloatImBuf(out);
343 out->flags &= ~IB_rectfloat;
346 if (seq->plugin->version <= 2) {
347 if (ibuf1) IMB_convert_rgba_to_abgr(ibuf1);
348 if (ibuf2) IMB_convert_rgba_to_abgr(ibuf2);
349 if (ibuf3) IMB_convert_rgba_to_abgr(ibuf3);
352 if (seq->plugin->version <= 4) {
353 ((SeqDoit)seq->plugin->doit)(
354 seq->plugin->data, facf0, facf1, x, y,
355 IMB_cast_away_list(ibuf1),
356 IMB_cast_away_list(ibuf2),
357 IMB_cast_away_list(out),
358 IMB_cast_away_list(ibuf3));
361 ((SeqDoit)seq->plugin->doit)(
362 seq->plugin->data, facf0, facf1, x, y,
363 ibuf1, ibuf2, out, ibuf3);
366 if (seq->plugin->version <= 2) {
367 if (!use_temp_bufs) {
368 if (ibuf1) IMB_convert_rgba_to_abgr(ibuf1);
369 if (ibuf2) IMB_convert_rgba_to_abgr(ibuf2);
370 if (ibuf3) IMB_convert_rgba_to_abgr(ibuf3);
372 IMB_convert_rgba_to_abgr(out);
374 if (seq->plugin->version <= 3 && float_rendering) {
375 IMB_float_from_rect_simple(out);
379 if (ibuf1) IMB_freeImBuf(ibuf1);
380 if (ibuf2) IMB_freeImBuf(ibuf2);
381 if (ibuf3) IMB_freeImBuf(ibuf3);
387 static int do_plugin_early_out(struct Sequence *UNUSED(seq),
388 float UNUSED(facf0), float UNUSED(facf1))
393 static void free_plugin(struct Sequence *seq)
395 free_plugin_seq(seq->plugin);
399 /* **********************************************************************
401 * ********************************************************************** */
403 static void init_alpha_over_or_under(Sequence *seq)
405 Sequence *seq1 = seq->seq1;
406 Sequence *seq2 = seq->seq2;
412 static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y,
413 char *rect1, char *rect2, char *out)
415 int fac2, mfac, fac, fac4;
417 char *rt1, *rt2, *rt;
424 fac2 = (int)(256.0f * facf0);
425 fac4 = (int)(256.0f * facf1);
432 /* rt = rt1 over rt2 (alpha from rt1) */
435 mfac = 256 - ( (fac2 * rt1[3]) >> 8);
437 if (fac == 0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
438 else if (mfac == 0) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
440 tempc = (fac * rt1[0] + mfac * rt2[0]) >> 8;
441 if (tempc > 255) rt[0] = 255; else rt[0] = tempc;
442 tempc = (fac * rt1[1] + mfac * rt2[1]) >> 8;
443 if (tempc > 255) rt[1] = 255; else rt[1] = tempc;
444 tempc = (fac * rt1[2] + mfac * rt2[2]) >> 8;
445 if (tempc > 255) rt[2] = 255; else rt[2] = tempc;
446 tempc = (fac * rt1[3] + mfac * rt2[3]) >> 8;
447 if (tempc > 255) rt[3] = 255; else rt[3] = tempc;
449 rt1 += 4; rt2 += 4; rt += 4;
459 mfac = 256 - ( (fac4 * rt1[3]) >> 8);
461 if (fac == 0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
462 else if (mfac == 0) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
464 tempc = (fac * rt1[0] + mfac * rt2[0]) >> 8;
465 if (tempc > 255) rt[0] = 255; else rt[0] = tempc;
466 tempc = (fac * rt1[1] + mfac * rt2[1]) >> 8;
467 if (tempc > 255) rt[1] = 255; else rt[1] = tempc;
468 tempc = (fac * rt1[2] + mfac * rt2[2]) >> 8;
469 if (tempc > 255) rt[2] = 255; else rt[2] = tempc;
470 tempc = (fac * rt1[3] + mfac * rt2[3]) >> 8;
471 if (tempc > 255) rt[3] = 255; else rt[3] = tempc;
473 rt1 += 4; rt2 += 4; rt += 4;
478 static void do_alphaover_effect_float(float facf0, float facf1, int x, int y,
479 float *rect1, float *rect2, float *out)
481 float fac2, mfac, fac, fac4;
483 float *rt1, *rt2, *rt;
498 /* rt = rt1 over rt2 (alpha from rt1) */
501 mfac = 1.0f - (fac2 * rt1[3]);
504 memcpy(rt, rt2, 4 * sizeof(float));
506 else if (mfac <= 0) {
507 memcpy(rt, rt1, 4 * sizeof(float));
510 rt[0] = fac * rt1[0] + mfac * rt2[0];
511 rt[1] = fac * rt1[1] + mfac * rt2[1];
512 rt[2] = fac * rt1[2] + mfac * rt2[2];
513 rt[3] = fac * rt1[3] + mfac * rt2[3];
515 rt1 += 4; rt2 += 4; rt += 4;
525 mfac = 1.0f - (fac4 * rt1[3]);
528 memcpy(rt, rt2, 4 * sizeof(float));
530 else if (mfac <= 0.0f) {
531 memcpy(rt, rt1, 4 * sizeof(float));
534 rt[0] = fac * rt1[0] + mfac * rt2[0];
535 rt[1] = fac * rt1[1] + mfac * rt2[1];
536 rt[2] = fac * rt1[2] + mfac * rt2[2];
537 rt[3] = fac * rt1[3] + mfac * rt2[3];
539 rt1 += 4; rt2 += 4; rt += 4;
544 static ImBuf *do_alphaover_effect(
545 SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra),
546 float facf0, float facf1,
547 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
550 struct ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
552 if (out->rect_float) {
553 do_alphaover_effect_float(
554 facf0, facf1, context.rectx, context.recty,
555 ibuf1->rect_float, ibuf2->rect_float,
559 do_alphaover_effect_byte(
560 facf0, facf1, context.rectx, context.recty,
561 (char *) ibuf1->rect, (char *) ibuf2->rect,
568 /* **********************************************************************
570 * ********************************************************************** */
572 static void do_alphaunder_effect_byte(
573 float facf0, float facf1, int x, int y, char *rect1,
574 char *rect2, char *out)
576 int fac2, mfac, fac, fac4;
578 char *rt1, *rt2, *rt;
585 fac2 = (int)(256.0f * facf0);
586 fac4 = (int)(256.0f * facf1);
593 /* rt = rt1 under rt2 (alpha from rt2) */
595 /* this complex optimalisation is because the
596 * 'skybuf' can be crossed in
598 if (rt2[3] == 0 && fac2 == 256) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
599 else if (rt2[3] == 255) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
602 fac = (fac2 * (256 - mfac)) >> 8;
604 if (fac == 0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
606 rt[0] = (fac * rt1[0] + mfac * rt2[0]) >> 8;
607 rt[1] = (fac * rt1[1] + mfac * rt2[1]) >> 8;
608 rt[2] = (fac * rt1[2] + mfac * rt2[2]) >> 8;
609 rt[3] = (fac * rt1[3] + mfac * rt2[3]) >> 8;
612 rt1 += 4; rt2 += 4; rt += 4;
621 if (rt2[3] == 0 && fac4 == 256) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
622 else if (rt2[3] == 255) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
625 fac = (fac4 * (256 - mfac)) >> 8;
627 if (fac == 0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
629 rt[0] = (fac * rt1[0] + mfac * rt2[0]) >> 8;
630 rt[1] = (fac * rt1[1] + mfac * rt2[1]) >> 8;
631 rt[2] = (fac * rt1[2] + mfac * rt2[2]) >> 8;
632 rt[3] = (fac * rt1[3] + mfac * rt2[3]) >> 8;
635 rt1 += 4; rt2 += 4; rt += 4;
641 static void do_alphaunder_effect_float(float facf0, float facf1, int x, int y,
642 float *rect1, float *rect2,
645 float fac2, mfac, fac, fac4;
647 float *rt1, *rt2, *rt;
662 /* rt = rt1 under rt2 (alpha from rt2) */
664 /* this complex optimalisation is because the
665 * 'skybuf' can be crossed in
667 if (rt2[3] <= 0 && fac2 >= 1.0f) {
668 memcpy(rt, rt1, 4 * sizeof(float));
670 else if (rt2[3] >= 1.0f) {
671 memcpy(rt, rt2, 4 * sizeof(float));
675 fac = fac2 * (1.0f - mfac);
678 memcpy(rt, rt2, 4 * sizeof(float));
681 rt[0] = fac * rt1[0] + mfac * rt2[0];
682 rt[1] = fac * rt1[1] + mfac * rt2[1];
683 rt[2] = fac * rt1[2] + mfac * rt2[2];
684 rt[3] = fac * rt1[3] + mfac * rt2[3];
687 rt1 += 4; rt2 += 4; rt += 4;
696 if (rt2[3] <= 0 && fac4 >= 1.0f) {
697 memcpy(rt, rt1, 4 * sizeof(float));
700 else if (rt2[3] >= 1.0f) {
701 memcpy(rt, rt2, 4 * sizeof(float));
705 fac = fac4 * (1.0f - mfac);
708 memcpy(rt, rt2, 4 * sizeof(float));
711 rt[0] = fac * rt1[0] + mfac * rt2[0];
712 rt[1] = fac * rt1[1] + mfac * rt2[1];
713 rt[2] = fac * rt1[2] + mfac * rt2[2];
714 rt[3] = fac * rt1[3] + mfac * rt2[3];
717 rt1 += 4; rt2 += 4; rt += 4;
722 static ImBuf *do_alphaunder_effect(
723 SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra),
724 float facf0, float facf1,
725 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
728 struct ImBuf *out = prepare_effect_imbufs(
729 context, ibuf1, ibuf2, ibuf3);
731 if (out->rect_float) {
732 do_alphaunder_effect_float(
733 facf0, facf1, context.rectx, context.recty,
734 ibuf1->rect_float, ibuf2->rect_float,
738 do_alphaunder_effect_byte(
739 facf0, facf1, context.rectx, context.recty,
740 (char *) ibuf1->rect, (char *) ibuf2->rect,
747 /* **********************************************************************
749 * ********************************************************************** */
751 static void do_cross_effect_byte(float facf0, float facf1, int x, int y,
752 char *rect1, char *rect2,
755 int fac1, fac2, fac3, fac4;
757 char *rt1, *rt2, *rt;
764 fac2 = (int)(256.0f * facf0);
766 fac4 = (int)(256.0f * facf1);
774 rt[0] = (fac1 * rt1[0] + fac2 * rt2[0]) >> 8;
775 rt[1] = (fac1 * rt1[1] + fac2 * rt2[1]) >> 8;
776 rt[2] = (fac1 * rt1[2] + fac2 * rt2[2]) >> 8;
777 rt[3] = (fac1 * rt1[3] + fac2 * rt2[3]) >> 8;
779 rt1 += 4; rt2 += 4; rt += 4;
788 rt[0] = (fac3 * rt1[0] + fac4 * rt2[0]) >> 8;
789 rt[1] = (fac3 * rt1[1] + fac4 * rt2[1]) >> 8;
790 rt[2] = (fac3 * rt1[2] + fac4 * rt2[2]) >> 8;
791 rt[3] = (fac3 * rt1[3] + fac4 * rt2[3]) >> 8;
793 rt1 += 4; rt2 += 4; rt += 4;
799 static void do_cross_effect_float(float facf0, float facf1, int x, int y,
800 float *rect1, float *rect2, float *out)
802 float fac1, fac2, fac3, fac4;
804 float *rt1, *rt2, *rt;
821 rt[0] = fac1 * rt1[0] + fac2 * rt2[0];
822 rt[1] = fac1 * rt1[1] + fac2 * rt2[1];
823 rt[2] = fac1 * rt1[2] + fac2 * rt2[2];
824 rt[3] = fac1 * rt1[3] + fac2 * rt2[3];
826 rt1 += 4; rt2 += 4; rt += 4;
835 rt[0] = fac3 * rt1[0] + fac4 * rt2[0];
836 rt[1] = fac3 * rt1[1] + fac4 * rt2[1];
837 rt[2] = fac3 * rt1[2] + fac4 * rt2[2];
838 rt[3] = fac3 * rt1[3] + fac4 * rt2[3];
840 rt1 += 4; rt2 += 4; rt += 4;
846 /* careful: also used by speed effect! */
848 static ImBuf *do_cross_effect(
849 SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra),
850 float facf0, float facf1,
851 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
854 struct ImBuf *out = prepare_effect_imbufs(
855 context, ibuf1, ibuf2, ibuf3);
857 if (out->rect_float) {
858 do_cross_effect_float(
859 facf0, facf1, context.rectx, context.recty,
860 ibuf1->rect_float, ibuf2->rect_float,
864 do_cross_effect_byte(
865 facf0, facf1, context.rectx, context.recty,
866 (char *) ibuf1->rect, (char *) ibuf2->rect,
873 /* **********************************************************************
875 * ********************************************************************** */
877 /* copied code from initrender.c */
878 static unsigned short gamtab[65536];
879 static unsigned short igamtab1[256];
880 static int gamma_tabs_init = FALSE;
882 #define RE_GAMMA_TABLE_SIZE 400
884 static float gamma_range_table[RE_GAMMA_TABLE_SIZE + 1];
885 static float gamfactor_table[RE_GAMMA_TABLE_SIZE];
886 static float inv_gamma_range_table[RE_GAMMA_TABLE_SIZE + 1];
887 static float inv_gamfactor_table[RE_GAMMA_TABLE_SIZE];
888 static float color_domain_table[RE_GAMMA_TABLE_SIZE + 1];
889 static float color_step;
890 static float inv_color_step;
891 static float valid_gamma;
892 static float valid_inv_gamma;
894 static void makeGammaTables(float gamma)
896 /* we need two tables: one forward, one backward */
900 valid_inv_gamma = 1.0f / gamma;
901 color_step = 1.0f / RE_GAMMA_TABLE_SIZE;
902 inv_color_step = (float) RE_GAMMA_TABLE_SIZE;
904 /* We could squeeze out the two range tables to gain some memory. */
905 for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++) {
906 color_domain_table[i] = i * color_step;
907 gamma_range_table[i] = pow(color_domain_table[i],
909 inv_gamma_range_table[i] = pow(color_domain_table[i],
913 /* The end of the table should match 1.0 carefully. In order to avoid */
914 /* rounding errors, we just set this explicitly. The last segment may */
915 /* have a different length than the other segments, but our */
916 /* interpolation is insensitive to that. */
917 color_domain_table[RE_GAMMA_TABLE_SIZE] = 1.0;
918 gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0;
919 inv_gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0;
921 /* To speed up calculations, we make these calc factor tables. They are */
922 /* multiplication factors used in scaling the interpolation. */
923 for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++) {
924 gamfactor_table[i] = inv_color_step *
925 (gamma_range_table[i + 1] - gamma_range_table[i]);
926 inv_gamfactor_table[i] = inv_color_step *
927 (inv_gamma_range_table[i + 1] - inv_gamma_range_table[i]);
930 } /* end of void makeGammaTables(float gamma) */
933 static float gammaCorrect(float c)
938 i = floor(c * inv_color_step);
939 /* Clip to range [0, 1]: outside, just do the complete calculation. */
940 /* We may have some performance problems here. Stretching up the LUT */
941 /* may help solve that, by exchanging LUT size for the interpolation. */
942 /* Negative colors are explicitly handled. */
943 if (i < 0) res = -pow(abs(c), valid_gamma);
944 else if (i >= RE_GAMMA_TABLE_SIZE) res = pow(c, valid_gamma);
945 else res = gamma_range_table[i] +
946 ( (c - color_domain_table[i]) * gamfactor_table[i]);
949 } /* end of float gammaCorrect(float col) */
951 /* ------------------------------------------------------------------------- */
953 static float invGammaCorrect(float col)
958 i = floor(col * inv_color_step);
959 /* Negative colors are explicitly handled. */
960 if (i < 0) res = -pow(abs(col), valid_inv_gamma);
961 else if (i >= RE_GAMMA_TABLE_SIZE) res = pow(col, valid_inv_gamma);
962 else res = inv_gamma_range_table[i] +
963 ( (col - color_domain_table[i]) * inv_gamfactor_table[i]);
966 } /* end of float invGammaCorrect(float col) */
969 static void gamtabs(float gamma)
971 float val, igamma = 1.0f / gamma;
974 /* gamtab: in short, out short */
975 for (a = 0; a < 65536; a++) {
979 if (gamma == 2.0f) val = sqrt(val);
980 else if (gamma != 1.0f) val = pow(val, igamma);
982 gamtab[a] = (65535.99f * val);
984 /* inverse gamtab1 : in byte, out short */
985 for (a = 1; a <= 256; a++) {
986 if (gamma == 2.0f) igamtab1[a - 1] = a * a - 1;
987 else if (gamma == 1.0f) igamtab1[a - 1] = 256 * a - 1;
990 igamtab1[a - 1] = (65535.0 * pow(val, gamma)) - 1;
996 static void build_gammatabs(void)
998 if (gamma_tabs_init == FALSE) {
1000 makeGammaTables(2.0f);
1001 gamma_tabs_init = TRUE;
1005 static void init_gammacross(Sequence *UNUSED(seq))
1009 static void load_gammacross(Sequence *UNUSED(seq))
1013 static void free_gammacross(Sequence *UNUSED(seq))
1017 static void do_gammacross_effect_byte(float facf0, float UNUSED(facf1),
1019 unsigned char *rect1,
1020 unsigned char *rect2,
1023 int fac1, fac2, col;
1025 unsigned char *rt1, *rt2, *rt;
1028 rt1 = (unsigned char *)rect1;
1029 rt2 = (unsigned char *)rect2;
1030 rt = (unsigned char *)out;
1032 fac2 = (int)(256.0f * facf0);
1040 col = (fac1 * igamtab1[rt1[0]] + fac2 * igamtab1[rt2[0]]) >> 8;
1041 if (col > 65535) rt[0] = 255; else rt[0] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
1042 col = (fac1 * igamtab1[rt1[1]] + fac2 * igamtab1[rt2[1]]) >> 8;
1043 if (col > 65535) rt[1] = 255; else rt[1] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
1044 col = (fac1 * igamtab1[rt1[2]] + fac2 * igamtab1[rt2[2]]) >> 8;
1045 if (col > 65535) rt[2] = 255; else rt[2] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
1046 col = (fac1 * igamtab1[rt1[3]] + fac2 * igamtab1[rt2[3]]) >> 8;
1047 if (col > 65535) rt[3] = 255; else rt[3] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
1049 rt1 += 4; rt2 += 4; rt += 4;
1058 col = (fac1 * igamtab1[rt1[0]] + fac2 * igamtab1[rt2[0]]) >> 8;
1059 if (col > 65535) rt[0] = 255; else rt[0] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
1060 col = (fac1 * igamtab1[rt1[1]] + fac2 * igamtab1[rt2[1]]) >> 8;
1061 if (col > 65535) rt[1] = 255; else rt[1] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
1062 col = (fac1 * igamtab1[rt1[2]] + fac2 * igamtab1[rt2[2]]) >> 8;
1063 if (col > 65535) rt[2] = 255; else rt[2] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
1064 col = (fac1 * igamtab1[rt1[3]] + fac2 * igamtab1[rt2[3]]) >> 8;
1065 if (col > 65535) rt[3] = 255; else rt[3] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
1067 rt1 += 4; rt2 += 4; rt += 4;
1073 static void do_gammacross_effect_float(float facf0, float UNUSED(facf1),
1075 float *rect1, float *rect2,
1080 float *rt1, *rt2, *rt;
1096 fac1 * invGammaCorrect(*rt1) + fac2 * invGammaCorrect(*rt2));
1107 fac1 * invGammaCorrect(*rt1) + fac2 * invGammaCorrect(*rt2));
1114 static ImBuf *do_gammacross_effect(
1115 SeqRenderData context,
1116 Sequence *UNUSED(seq), float UNUSED(cfra),
1117 float facf0, float facf1,
1118 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
1119 struct ImBuf *ibuf3)
1121 struct ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
1125 if (out->rect_float) {
1126 do_gammacross_effect_float(
1127 facf0, facf1, context.rectx, context.recty,
1128 ibuf1->rect_float, ibuf2->rect_float,
1132 do_gammacross_effect_byte(
1133 facf0, facf1, context.rectx, context.recty,
1134 (unsigned char *) ibuf1->rect, (unsigned char *) ibuf2->rect,
1135 (unsigned char *) out->rect);
1141 /* **********************************************************************
1143 * ********************************************************************** */
1145 static void do_add_effect_byte(float facf0, float facf1, int x, int y,
1146 unsigned char *rect1, unsigned char *rect2,
1149 int col, xo, fac1, fac3;
1150 char *rt1, *rt2, *rt;
1153 rt1 = (char *)rect1;
1154 rt2 = (char *)rect2;
1157 fac1 = (int)(256.0f * facf0);
1158 fac3 = (int)(256.0f * facf1);
1165 col = rt1[0] + ((fac1 * rt2[0]) >> 8);
1166 if (col > 255) rt[0] = 255; else rt[0] = col;
1167 col = rt1[1] + ((fac1 * rt2[1]) >> 8);
1168 if (col > 255) rt[1] = 255; else rt[1] = col;
1169 col = rt1[2] + ((fac1 * rt2[2]) >> 8);
1170 if (col > 255) rt[2] = 255; else rt[2] = col;
1171 col = rt1[3] + ((fac1 * rt2[3]) >> 8);
1172 if (col > 255) rt[3] = 255; else rt[3] = col;
1174 rt1 += 4; rt2 += 4; rt += 4;
1183 col = rt1[0] + ((fac3 * rt2[0]) >> 8);
1184 if (col > 255) rt[0] = 255; else rt[0] = col;
1185 col = rt1[1] + ((fac3 * rt2[1]) >> 8);
1186 if (col > 255) rt[1] = 255; else rt[1] = col;
1187 col = rt1[2] + ((fac3 * rt2[2]) >> 8);
1188 if (col > 255) rt[2] = 255; else rt[2] = col;
1189 col = rt1[3] + ((fac3 * rt2[3]) >> 8);
1190 if (col > 255) rt[3] = 255; else rt[3] = col;
1192 rt1 += 4; rt2 += 4; rt += 4;
1197 static void do_add_effect_float(float facf0, float facf1, int x, int y,
1198 float *rect1, float *rect2,
1203 float *rt1, *rt2, *rt;
1217 *rt = *rt1 + fac1 * (*rt2);
1227 *rt = *rt1 + fac3 * (*rt2);
1234 static ImBuf *do_add_effect(SeqRenderData context,
1235 Sequence *UNUSED(seq), float UNUSED(cfra),
1236 float facf0, float facf1,
1237 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
1238 struct ImBuf *ibuf3)
1240 struct ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
1242 if (out->rect_float) {
1243 do_add_effect_float(
1244 facf0, facf1, context.rectx, context.recty,
1245 ibuf1->rect_float, ibuf2->rect_float,
1250 facf0, facf1, context.rectx, context.recty,
1251 (unsigned char *) ibuf1->rect, (unsigned char *) ibuf2->rect,
1252 (unsigned char *) out->rect);
1258 /* **********************************************************************
1260 * ********************************************************************** */
1262 static void do_sub_effect_byte(float facf0, float facf1,
1264 char *rect1, char *rect2, char *out)
1266 int col, xo, fac1, fac3;
1267 char *rt1, *rt2, *rt;
1270 rt1 = (char *)rect1;
1271 rt2 = (char *)rect2;
1274 fac1 = (int)(256.0f * facf0);
1275 fac3 = (int)(256.0f * facf1);
1282 col = rt1[0] - ((fac1 * rt2[0]) >> 8);
1283 if (col < 0) rt[0] = 0; else rt[0] = col;
1284 col = rt1[1] - ((fac1 * rt2[1]) >> 8);
1285 if (col < 0) rt[1] = 0; else rt[1] = col;
1286 col = rt1[2] - ((fac1 * rt2[2]) >> 8);
1287 if (col < 0) rt[2] = 0; else rt[2] = col;
1288 col = rt1[3] - ((fac1 * rt2[3]) >> 8);
1289 if (col < 0) rt[3] = 0; else rt[3] = col;
1291 rt1 += 4; rt2 += 4; rt += 4;
1300 col = rt1[0] - ((fac3 * rt2[0]) >> 8);
1301 if (col < 0) rt[0] = 0; else rt[0] = col;
1302 col = rt1[1] - ((fac3 * rt2[1]) >> 8);
1303 if (col < 0) rt[1] = 0; else rt[1] = col;
1304 col = rt1[2] - ((fac3 * rt2[2]) >> 8);
1305 if (col < 0) rt[2] = 0; else rt[2] = col;
1306 col = rt1[3] - ((fac3 * rt2[3]) >> 8);
1307 if (col < 0) rt[3] = 0; else rt[3] = col;
1309 rt1 += 4; rt2 += 4; rt += 4;
1314 static void do_sub_effect_float(float facf0, float facf1, int x, int y,
1315 float *rect1, float *rect2,
1320 float *rt1, *rt2, *rt;
1334 *rt = *rt1 - fac1 * (*rt2);
1344 *rt = *rt1 - fac3 * (*rt2);
1351 static ImBuf *do_sub_effect(
1352 SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra),
1353 float facf0, float facf1,
1354 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
1355 struct ImBuf *ibuf3)
1357 struct ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
1359 if (out->rect_float) {
1360 do_sub_effect_float(
1361 facf0, facf1, context.rectx, context.recty,
1362 ibuf1->rect_float, ibuf2->rect_float,
1367 facf0, facf1, context.rectx, context.recty,
1368 (char *) ibuf1->rect, (char *) ibuf2->rect,
1369 (char *) out->rect);
1374 /* **********************************************************************
1376 * ********************************************************************** */
1378 /* Must be > 0 or add precopy, etc to the function */
1382 static void do_drop_effect_byte(float facf0, float facf1, int x, int y,
1383 char *rect2i, char *rect1i,
1386 int height, width, temp, fac, fac1, fac2;
1387 char *rt1, *rt2, *out;
1393 fac1 = (int)(70.0f * facf0);
1394 fac2 = (int)(70.0f * facf1);
1396 rt2 = (char *) (rect2i + YOFF * width);
1397 rt1 = (char *) rect1i;
1398 out = (char *) outi;
1399 for (y = 0; y < height - YOFF; y++) {
1400 if (field) fac = fac1;
1404 memcpy(out, rt1, sizeof(int) * XOFF);
1408 for (x = XOFF; x < width; x++) {
1409 temp = ((fac * rt2[3]) >> 8);
1411 *(out++) = MAX2(0, *rt1 - temp); rt1++;
1412 *(out++) = MAX2(0, *rt1 - temp); rt1++;
1413 *(out++) = MAX2(0, *rt1 - temp); rt1++;
1414 *(out++) = MAX2(0, *rt1 - temp); rt1++;
1419 memcpy(out, rt1, sizeof(int) * YOFF * width);
1422 static void do_drop_effect_float(float facf0, float facf1, int x, int y,
1423 float *rect2i, float *rect1i,
1427 float temp, fac, fac1, fac2;
1428 float *rt1, *rt2, *out;
1434 fac1 = 70.0f * facf0;
1435 fac2 = 70.0f * facf1;
1437 rt2 = (rect2i + YOFF * width);
1440 for (y = 0; y < height - YOFF; y++) {
1441 if (field) fac = fac1;
1445 memcpy(out, rt1, 4 * sizeof(float) * XOFF);
1449 for (x = XOFF; x < width; x++) {
1450 temp = fac * rt2[3];
1452 *(out++) = MAX2(0.0f, *rt1 - temp); rt1++;
1453 *(out++) = MAX2(0.0f, *rt1 - temp); rt1++;
1454 *(out++) = MAX2(0.0f, *rt1 - temp); rt1++;
1455 *(out++) = MAX2(0.0f, *rt1 - temp); rt1++;
1460 memcpy(out, rt1, 4 * sizeof(float) * YOFF * width);
1463 /* **********************************************************************
1465 * ********************************************************************** */
1467 static void do_mul_effect_byte(float facf0, float facf1, int x, int y,
1468 unsigned char *rect1, unsigned char *rect2,
1472 char *rt1, *rt2, *rt;
1475 rt1 = (char *)rect1;
1476 rt2 = (char *)rect2;
1479 fac1 = (int)(256.0f * facf0);
1480 fac3 = (int)(256.0f * facf1);
1483 * fac * (a * b) + (1-fac)*a => fac * a * (b - 1) + axaux = c * px + py * s; //+centx
1484 * yaux = -s * px + c * py; //+centy
1492 rt[0] = rt1[0] + ((fac1 * rt1[0] * (rt2[0] - 256)) >> 16);
1493 rt[1] = rt1[1] + ((fac1 * rt1[1] * (rt2[1] - 256)) >> 16);
1494 rt[2] = rt1[2] + ((fac1 * rt1[2] * (rt2[2] - 256)) >> 16);
1495 rt[3] = rt1[3] + ((fac1 * rt1[3] * (rt2[3] - 256)) >> 16);
1497 rt1 += 4; rt2 += 4; rt += 4;
1506 rt[0] = rt1[0] + ((fac3 * rt1[0] * (rt2[0] - 256)) >> 16);
1507 rt[1] = rt1[1] + ((fac3 * rt1[1] * (rt2[1] - 256)) >> 16);
1508 rt[2] = rt1[2] + ((fac3 * rt1[2] * (rt2[2] - 256)) >> 16);
1509 rt[3] = rt1[3] + ((fac3 * rt1[3] * (rt2[3] - 256)) >> 16);
1511 rt1 += 4; rt2 += 4; rt += 4;
1516 static void do_mul_effect_float(float facf0, float facf1, int x, int y,
1517 float *rect1, float *rect2,
1522 float *rt1, *rt2, *rt;
1533 * fac*(a*b) + (1-fac)*a => fac*a*(b-1)+a
1541 rt[0] = rt1[0] + fac1 * rt1[0] * (rt2[0] - 1.0f);
1542 rt[1] = rt1[1] + fac1 * rt1[1] * (rt2[1] - 1.0f);
1543 rt[2] = rt1[2] + fac1 * rt1[2] * (rt2[2] - 1.0f);
1544 rt[3] = rt1[3] + fac1 * rt1[3] * (rt2[3] - 1.0f);
1546 rt1 += 4; rt2 += 4; rt += 4;
1555 rt[0] = rt1[0] + fac3 * rt1[0] * (rt2[0] - 1.0f);
1556 rt[1] = rt1[1] + fac3 * rt1[1] * (rt2[1] - 1.0f);
1557 rt[2] = rt1[2] + fac3 * rt1[2] * (rt2[2] - 1.0f);
1558 rt[3] = rt1[3] + fac3 * rt1[3] * (rt2[3] - 1.0f);
1560 rt1 += 4; rt2 += 4; rt += 4;
1565 static ImBuf *do_mul_effect(
1566 SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra),
1567 float facf0, float facf1,
1568 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
1569 struct ImBuf *ibuf3)
1571 struct ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
1573 if (out->rect_float) {
1574 do_mul_effect_float(
1575 facf0, facf1, context.rectx, context.recty,
1576 ibuf1->rect_float, ibuf2->rect_float,
1581 facf0, facf1, context.rectx, context.recty,
1582 (unsigned char *) ibuf1->rect, (unsigned char *) ibuf2->rect,
1583 (unsigned char *) out->rect);
1589 /* **********************************************************************
1591 * ********************************************************************** */
1593 typedef struct WipeZone {
1601 static void precalc_wipe_zone(WipeZone *wipezone, WipeVars *wipe, int xo, int yo)
1603 wipezone->flip = (wipe->angle < 0);
1604 wipezone->angle = tanf(DEG2RADF(fabsf(wipe->angle)));
1607 wipezone->width = (int)(wipe->edgeWidth * ((xo + yo) / 2.0f));
1608 wipezone->pythangle = 1.0f / sqrtf(wipezone->angle * wipezone->angle + 1.0f);
1611 // This function calculates the blur band for the wipe effects
1612 static float in_band(float width, float dist, int side, int dir)
1623 alpha = (dist + 0.5f * width) / (width);
1625 alpha = (0.5f * width - dist) / (width);
1633 static float check_zone(WipeZone *wipezone, int x, int y,
1634 Sequence *seq, float facf0)
1636 float posx, posy, hyp, hyp2, angle, hwidth, b1, b2, b3, pointdist;
1637 /* some future stuff */
1638 // float hyp3, hyp4, b4, b5
1639 float temp1, temp2, temp3, temp4; //some placeholder variables
1640 int xo = wipezone->xo;
1641 int yo = wipezone->yo;
1642 float halfx = xo * 0.5f;
1643 float halfy = yo * 0.5f;
1644 float widthf, output = 0;
1645 WipeVars *wipe = (WipeVars *)seq->effectdata;
1648 if (wipezone->flip) x = xo - x;
1649 angle = wipezone->angle;
1651 if (wipe->forward) {
1656 posx = xo - facf0 * xo;
1657 posy = yo - facf0 * yo;
1660 switch (wipe->wipetype) {
1661 case DO_SINGLE_WIPE:
1662 width = wipezone->width;
1664 if (angle == 0.0f) {
1667 hyp = fabs(y - posy);
1670 b1 = posy - (-angle) * posx;
1671 b2 = y - (-angle) * x;
1672 hyp = fabsf(angle * x + y + (-posy - angle * posx)) * wipezone->pythangle;
1681 if (wipe->forward) {
1683 output = in_band(width, hyp, 1, 1);
1685 output = in_band(width, hyp, 0, 1);
1689 output = in_band(width, hyp, 0, 1);
1691 output = in_band(width, hyp, 1, 1);
1695 case DO_DOUBLE_WIPE:
1697 facf0 = 1.0f - facf0; // Go the other direction
1699 width = wipezone->width; // calculate the blur width
1700 hwidth = width * 0.5f;
1703 b3 = yo - posy * 0.5f;
1706 hyp = abs(y - posy * 0.5f);
1707 hyp2 = abs(y - (yo - posy * 0.5f));
1710 b1 = posy * 0.5f - (-angle) * posx * 0.5f;
1711 b3 = (yo - posy * 0.5f) - (-angle) * (xo - posx * 0.5f);
1712 b2 = y - (-angle) * x;
1714 hyp = fabsf(angle * x + y + (-posy * 0.5f - angle * posx * 0.5f)) * wipezone->pythangle;
1715 hyp2 = fabsf(angle * x + y + (-(yo - posy * 0.5f) - angle * (xo - posx * 0.5f))) * wipezone->pythangle;
1718 hwidth = minf(hwidth, fabsf(b3 - b1) / 2.0f);
1720 if (b2 < b1 && b2 < b3) {
1721 output = in_band(hwidth, hyp, 0, 1);
1723 else if (b2 > b1 && b2 > b3) {
1724 output = in_band(hwidth, hyp2, 0, 1);
1727 if (hyp < hwidth && hyp2 > hwidth)
1728 output = in_band(hwidth, hyp, 1, 1);
1729 else if (hyp > hwidth && hyp2 < hwidth)
1730 output = in_band(hwidth, hyp2, 1, 1);
1732 output = in_band(hwidth, hyp2, 1, 1) * in_band(hwidth, hyp, 1, 1);
1734 if (!wipe->forward) output = 1 - output;
1738 * temp1: angle of effect center in rads
1739 * temp2: angle of line through (halfx, halfy) and (x, y) in rads
1740 * temp3: angle of low side of blur
1741 * temp4: angle of high side of blur
1743 output = 1.0f - facf0;
1744 widthf = wipe->edgeWidth * 2.0f * (float)M_PI;
1745 temp1 = 2.0f * (float)M_PI * facf0;
1747 if (wipe->forward) {
1748 temp1 = 2.0f * (float)M_PI - temp1;
1754 temp2 = asin(abs(y) / sqrt(x * x + y * y));
1755 if (x <= 0 && y >= 0) temp2 = (float)M_PI - temp2;
1756 else if (x <= 0 && y <= 0) temp2 += (float)M_PI;
1757 else if (x >= 0 && y <= 0) temp2 = 2.0f * (float)M_PI - temp2;
1759 if (wipe->forward) {
1760 temp3 = temp1 - (widthf * 0.5f) * facf0;
1761 temp4 = temp1 + (widthf * 0.5f) * (1 - facf0);
1764 temp3 = temp1 - (widthf * 0.5f) * (1 - facf0);
1765 temp4 = temp1 + (widthf * 0.5f) * facf0;
1767 if (temp3 < 0) temp3 = 0;
1768 if (temp4 > 2.0f * (float)M_PI) temp4 = 2.0f * (float)M_PI;
1771 if (temp2 < temp3) output = 0;
1772 else if (temp2 > temp4) output = 1;
1773 else output = (temp2 - temp3) / (temp4 - temp3);
1774 if (x == 0 && y == 0) output = 1;
1775 if (output != output) output = 1;
1776 if (wipe->forward) output = 1 - output;
1778 /* BOX WIPE IS NOT WORKING YET */
1779 /* case DO_CROSS_WIPE: */
1780 /* BOX WIPE IS NOT WORKING YET */
1783 if (invert) facf0 = 1 - facf0;
1785 width = (int)(wipe->edgeWidth * ((xo + yo) / 2.0));
1786 hwidth = (float)width / 2.0;
1787 if (angle == 0) angle = 0.000001;
1788 b1 = posy / 2 - (-angle) * posx / 2;
1789 b3 = (yo - posy / 2) - (-angle) * (xo - posx / 2);
1790 b2 = y - (-angle) * x;
1792 hyp = abs(angle * x + y + (-posy / 2 - angle * posx / 2)) * wipezone->pythangle;
1793 hyp2 = abs(angle * x + y + (-(yo - posy / 2) - angle * (xo - posx / 2))) * wipezone->pythangle;
1795 temp1 = xo * (1 - facf0 / 2) - xo * facf0 / 2;
1796 temp2 = yo * (1 - facf0 / 2) - yo * facf0 / 2;
1797 pointdist = sqrt(temp1 * temp1 + temp2 * temp2);
1799 if (b2 < b1 && b2 < b3) {
1800 if (hwidth < pointdist)
1801 output = in_band(wipezone, hwidth, hyp, facf0, 0, 1);
1803 else if (b2 > b1 && b2 > b3) {
1804 if (hwidth < pointdist)
1805 output = in_band(wipezone, hwidth, hyp2, facf0, 0, 1);
1808 if (hyp < hwidth && hyp2 > hwidth)
1809 output = in_band(wipezone, hwidth, hyp, facf0, 1, 1);
1810 else if (hyp > hwidth && hyp2 < hwidth)
1811 output = in_band(wipezone, hwidth, hyp2, facf0, 1, 1);
1813 output = in_band(wipezone, hwidth, hyp2, facf0, 1, 1) * in_band(wipezone, hwidth, hyp, facf0, 1, 1);
1816 if (invert) facf0 = 1 - facf0;
1818 b1 = posy / 2 - (-angle) * posx / 2;
1819 b3 = (yo - posy / 2) - (-angle) * (xo - posx / 2);
1820 b2 = y - (-angle) * x;
1822 hyp = abs(angle * x + y + (-posy / 2 - angle * posx / 2)) * wipezone->pythangle;
1823 hyp2 = abs(angle * x + y + (-(yo - posy / 2) - angle * (xo - posx / 2))) * wipezone->pythangle;
1825 if (b2 < b1 && b2 < b3) {
1826 if (hwidth < pointdist)
1827 output *= in_band(wipezone, hwidth, hyp, facf0, 0, 1);
1829 else if (b2 > b1 && b2 > b3) {
1830 if (hwidth < pointdist)
1831 output *= in_band(wipezone, hwidth, hyp2, facf0, 0, 1);
1834 if (hyp < hwidth && hyp2 > hwidth)
1835 output *= in_band(wipezone, hwidth, hyp, facf0, 1, 1);
1836 else if (hyp > hwidth && hyp2 < hwidth)
1837 output *= in_band(wipezone, hwidth, hyp2, facf0, 1, 1);
1839 output *= in_band(wipezone, hwidth, hyp2, facf0, 1, 1) * in_band(wipezone, hwidth, hyp, facf0, 1, 1);
1845 if (xo > yo) yo = xo;
1848 if (!wipe->forward) facf0 = 1 - facf0;
1850 width = wipezone->width;
1851 hwidth = width * 0.5f;
1853 temp1 = (halfx - (halfx) * facf0);
1854 pointdist = sqrt(temp1 * temp1 + temp1 * temp1);
1856 temp2 = sqrt((halfx - x) * (halfx - x) + (halfy - y) * (halfy - y));
1857 if (temp2 > pointdist) output = in_band(hwidth, fabs(temp2 - pointdist), 0, 1);
1858 else output = in_band(hwidth, fabs(temp2 - pointdist), 1, 1);
1860 if (!wipe->forward) output = 1 - output;
1864 if (output < 0) output = 0;
1865 else if (output > 1) output = 1;
1869 static void init_wipe_effect(Sequence *seq)
1871 if (seq->effectdata) MEM_freeN(seq->effectdata);
1872 seq->effectdata = MEM_callocN(sizeof(struct WipeVars), "wipevars");
1875 static int num_inputs_wipe(void)
1880 static void free_wipe_effect(Sequence *seq)
1882 if (seq->effectdata) MEM_freeN(seq->effectdata);
1883 seq->effectdata = NULL;
1886 static void copy_wipe_effect(Sequence *dst, Sequence *src)
1888 dst->effectdata = MEM_dupallocN(src->effectdata);
1891 static void do_wipe_effect_byte(Sequence *seq, float facf0, float UNUSED(facf1),
1893 unsigned char *rect1,
1894 unsigned char *rect2, unsigned char *out)
1897 WipeVars *wipe = (WipeVars *)seq->effectdata;
1899 char *rt1, *rt2, *rt;
1901 precalc_wipe_zone(&wipezone, wipe, x, y);
1903 rt1 = (char *)rect1;
1904 rt2 = (char *)rect2;
1909 for (y = 0; y < yo; y++) {
1910 for (x = 0; x < xo; x++) {
1911 float check = check_zone(&wipezone, x, y, seq, facf0);
1914 rt[0] = (int)(rt1[0] * check) + (int)(rt2[0] * (1 - check));
1915 rt[1] = (int)(rt1[1] * check) + (int)(rt2[1] * (1 - check));
1916 rt[2] = (int)(rt1[2] * check) + (int)(rt2[2] * (1 - check));
1917 rt[3] = (int)(rt1[3] * check) + (int)(rt2[3] * (1 - check));
1952 static void do_wipe_effect_float(Sequence *seq, float facf0, float UNUSED(facf1),
1955 float *rect2, float *out)
1958 WipeVars *wipe = (WipeVars *)seq->effectdata;
1960 float *rt1, *rt2, *rt;
1962 precalc_wipe_zone(&wipezone, wipe, x, y);
1970 for (y = 0; y < yo; y++) {
1971 for (x = 0; x < xo; x++) {
1972 float check = check_zone(&wipezone, x, y, seq, facf0);
1975 rt[0] = rt1[0] * check + rt2[0] * (1 - check);
1976 rt[1] = rt1[1] * check + rt2[1] * (1 - check);
1977 rt[2] = rt1[2] * check + rt2[2] * (1 - check);
1978 rt[3] = rt1[3] * check + rt2[3] * (1 - check);
2013 static ImBuf *do_wipe_effect(
2014 SeqRenderData context, Sequence *seq, float UNUSED(cfra),
2015 float facf0, float facf1,
2016 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
2017 struct ImBuf *ibuf3)
2019 struct ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2021 if (out->rect_float) {
2022 do_wipe_effect_float(seq,
2023 facf0, facf1, context.rectx, context.recty,
2024 ibuf1->rect_float, ibuf2->rect_float,
2028 do_wipe_effect_byte(seq,
2029 facf0, facf1, context.rectx, context.recty,
2030 (unsigned char *) ibuf1->rect, (unsigned char *) ibuf2->rect,
2031 (unsigned char *) out->rect);
2036 /* **********************************************************************
2038 * ********************************************************************** */
2039 static void init_transform_effect(Sequence *seq)
2041 TransformVars *transform;
2043 if (seq->effectdata) MEM_freeN(seq->effectdata);
2044 seq->effectdata = MEM_callocN(sizeof(struct TransformVars), "transformvars");
2046 transform = (TransformVars *)seq->effectdata;
2048 transform->ScalexIni = 1.0f;
2049 transform->ScaleyIni = 1.0f;
2051 transform->xIni = 0.0f;
2052 transform->yIni = 0.0f;
2054 transform->rotIni = 0.0f;
2056 transform->interpolation = 1;
2057 transform->percent = 1;
2058 transform->uniform_scale = 0;
2061 static int num_inputs_transform(void)
2066 static void free_transform_effect(Sequence *seq)
2068 if (seq->effectdata) MEM_freeN(seq->effectdata);
2069 seq->effectdata = NULL;
2072 static void copy_transform_effect(Sequence *dst, Sequence *src)
2074 dst->effectdata = MEM_dupallocN(src->effectdata);
2077 static void transform_image(int x, int y, struct ImBuf *ibuf1, struct ImBuf *out,
2078 float scale_x, float scale_y, float translate_x, float translate_y,
2079 float rotate, int interpolation)
2082 float xt, yt, xr, yr;
2092 for (yi = 0; yi < yo; yi++) {
2093 for (xi = 0; xi < xo; xi++) {
2096 xt = xi - translate_x;
2097 yt = yi - translate_y;
2099 //rotate point with center ref
2100 xr = c * xt + s * yt;
2101 yr = -s * xt + c * yt;
2103 //scale point with center ref
2107 //undo reference center point
2112 switch (interpolation) {
2114 neareast_interpolation(ibuf1, out, xt, yt, xi, yi);
2117 bilinear_interpolation(ibuf1, out, xt, yt, xi, yi);
2120 bicubic_interpolation(ibuf1, out, xt, yt, xi, yi);
2127 static void do_transform(Scene *scene, Sequence *seq, float UNUSED(facf0), int x, int y,
2128 struct ImBuf *ibuf1, struct ImBuf *out)
2130 TransformVars *transform = (TransformVars *)seq->effectdata;
2131 float scale_x, scale_y, translate_x, translate_y, rotate_radians;
2134 if (transform->uniform_scale) {
2135 scale_x = scale_y = transform->ScalexIni;
2138 scale_x = transform->ScalexIni;
2139 scale_y = transform->ScaleyIni;
2143 if (!transform->percent) {
2144 float rd_s = (scene->r.size / 100.0f);
2146 translate_x = transform->xIni * rd_s + (x / 2.0f);
2147 translate_y = transform->yIni * rd_s + (y / 2.0f);
2150 translate_x = x * (transform->xIni / 100.0f) + (x / 2.0f);
2151 translate_y = y * (transform->yIni / 100.0f) + (y / 2.0f);
2155 rotate_radians = DEG2RADF(transform->rotIni);
2157 transform_image(x, y, ibuf1, out, scale_x, scale_y, translate_x, translate_y, rotate_radians, transform->interpolation);
2161 static ImBuf *do_transform_effect(
2162 SeqRenderData context, Sequence *seq, float UNUSED(cfra),
2163 float facf0, float UNUSED(facf1),
2164 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
2165 struct ImBuf *ibuf3)
2167 struct ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2169 do_transform(context.scene, seq, facf0,
2170 context.rectx, context.recty, ibuf1, out);
2176 /* **********************************************************************
2178 * ********************************************************************** */
2180 static void RVBlurBitmap2_byte(unsigned char *map, int width, int height,
2183 /* MUUUCCH better than the previous blur. */
2184 /* We do the blurring in two passes which is a whole lot faster. */
2185 /* I changed the math arount to implement an actual Gaussian */
2188 /* Watch out though, it tends to misbehaven with large blur values on */
2189 /* a small bitmap. Avoid avoid avoid. */
2190 /*=============================== */
2192 unsigned char *temp = NULL, *swap;
2193 float *filter = NULL;
2194 int x, y, i, fx, fy;
2195 int index, ix, halfWidth;
2196 float fval, k, curColor[3], curColor2[3], weight = 0;
2198 /* If we're not really blurring, bail out */
2202 /* Allocate memory for the tempmap and the blur filter matrix */
2203 temp = MEM_mallocN((width * height * 4), "blurbitmaptemp");
2207 /* Allocate memory for the filter elements */
2208 halfWidth = ((quality + 1) * blur);
2209 filter = (float *)MEM_mallocN(sizeof(float) * halfWidth * 2, "blurbitmapfilter");
2215 /* Apparently we're calculating a bell curve */
2216 /* based on the standard deviation (or radius) */
2217 /* This code is based on an example */
2218 /* posted to comp.graphics.algorithms by */
2219 /* Blancmange (bmange@airdmhor.gen.nz) */
2221 k = -1.0f / (2.0f * (float)M_PI * blur * blur);
2222 for (ix = 0; ix < halfWidth; ix++) {
2223 weight = (float)exp(k * (ix * ix));
2224 filter[halfWidth - ix] = weight;
2225 filter[halfWidth + ix] = weight;
2229 /* Normalize the array */
2231 for (ix = 0; ix < halfWidth * 2; ix++)
2234 for (ix = 0; ix < halfWidth * 2; ix++)
2238 for (y = 0; y < height; y++) {
2239 /* Do the left & right strips */
2240 for (x = 0; x < halfWidth; x++) {
2241 index = (x + y * width) * 4;
2246 for (i = x - halfWidth; i < x + halfWidth; i++) {
2247 if ((i >= 0) && (i < width)) {
2248 curColor[0] += map[(i + y * width) * 4 + GlowR] * filter[fx];
2249 curColor[1] += map[(i + y * width) * 4 + GlowG] * filter[fx];
2250 curColor[2] += map[(i + y * width) * 4 + GlowB] * filter[fx];
2252 curColor2[0] += map[(width - 1 - i + y * width) * 4 + GlowR] *
2254 curColor2[1] += map[(width - 1 - i + y * width) * 4 + GlowG] *
2256 curColor2[2] += map[(width - 1 - i + y * width) * 4 + GlowB] *
2261 temp[index + GlowR] = curColor[0];
2262 temp[index + GlowG] = curColor[1];
2263 temp[index + GlowB] = curColor[2];
2265 temp[((width - 1 - x + y * width) * 4) + GlowR] = curColor2[0];
2266 temp[((width - 1 - x + y * width) * 4) + GlowG] = curColor2[1];
2267 temp[((width - 1 - x + y * width) * 4) + GlowB] = curColor2[2];
2270 /* Do the main body */
2271 for (x = halfWidth; x < width - halfWidth; x++) {
2272 index = (x + y * width) * 4;
2275 for (i = x - halfWidth; i < x + halfWidth; i++) {
2276 curColor[0] += map[(i + y * width) * 4 + GlowR] * filter[fx];
2277 curColor[1] += map[(i + y * width) * 4 + GlowG] * filter[fx];
2278 curColor[2] += map[(i + y * width) * 4 + GlowB] * filter[fx];
2281 temp[index + GlowR] = curColor[0];
2282 temp[index + GlowG] = curColor[1];
2283 temp[index + GlowB] = curColor[2];
2288 swap = temp; temp = map; map = swap;
2291 /* Blur the columns */
2292 for (x = 0; x < width; x++) {
2293 /* Do the top & bottom strips */
2294 for (y = 0; y < halfWidth; y++) {
2295 index = (x + y * width) * 4;
2299 for (i = y - halfWidth; i < y + halfWidth; i++) {
2300 if ((i >= 0) && (i < height)) {
2302 curColor[0] += map[(x + i * width) * 4 + GlowR] * filter[fy];
2303 curColor[1] += map[(x + i * width) * 4 + GlowG] * filter[fy];
2304 curColor[2] += map[(x + i * width) * 4 + GlowB] * filter[fy];
2307 curColor2[0] += map[(x + (height - 1 - i) * width) *
2308 4 + GlowR] * filter[fy];
2309 curColor2[1] += map[(x + (height - 1 - i) * width) *
2310 4 + GlowG] * filter[fy];
2311 curColor2[2] += map[(x + (height - 1 - i) * width) *
2312 4 + GlowB] * filter[fy];
2316 temp[index + GlowR] = curColor[0];
2317 temp[index + GlowG] = curColor[1];
2318 temp[index + GlowB] = curColor[2];
2319 temp[((x + (height - 1 - y) * width) * 4) + GlowR] = curColor2[0];
2320 temp[((x + (height - 1 - y) * width) * 4) + GlowG] = curColor2[1];
2321 temp[((x + (height - 1 - y) * width) * 4) + GlowB] = curColor2[2];
2323 /* Do the main body */
2324 for (y = halfWidth; y < height - halfWidth; y++) {
2325 index = (x + y * width) * 4;
2328 for (i = y - halfWidth; i < y + halfWidth; i++) {
2329 curColor[0] += map[(x + i * width) * 4 + GlowR] * filter[fy];
2330 curColor[1] += map[(x + i * width) * 4 + GlowG] * filter[fy];
2331 curColor[2] += map[(x + i * width) * 4 + GlowB] * filter[fy];
2334 temp[index + GlowR] = curColor[0];
2335 temp[index + GlowG] = curColor[1];
2336 temp[index + GlowB] = curColor[2];
2342 swap = temp; temp = map; /* map = swap; */ /* UNUSED */
2349 static void RVBlurBitmap2_float(float *map, int width, int height,
2352 /* MUUUCCH better than the previous blur. */
2353 /* We do the blurring in two passes which is a whole lot faster. */
2354 /* I changed the math arount to implement an actual Gaussian */
2357 /* Watch out though, it tends to misbehaven with large blur values on */
2358 /* a small bitmap. Avoid avoid avoid. */
2359 /*=============================== */
2361 float *temp = NULL, *swap;
2362 float *filter = NULL;
2363 int x, y, i, fx, fy;
2364 int index, ix, halfWidth;
2365 float fval, k, curColor[3], curColor2[3], weight = 0;
2367 /* If we're not really blurring, bail out */
2371 /* Allocate memory for the tempmap and the blur filter matrix */
2372 temp = MEM_mallocN((width * height * 4 * sizeof(float)), "blurbitmaptemp");
2376 /* Allocate memory for the filter elements */
2377 halfWidth = ((quality + 1) * blur);
2378 filter = (float *)MEM_mallocN(sizeof(float) * halfWidth * 2, "blurbitmapfilter");
2384 /* Apparently we're calculating a bell curve */
2385 /* based on the standard deviation (or radius) */
2386 /* This code is based on an example */
2387 /* posted to comp.graphics.algorithms by */
2388 /* Blancmange (bmange@airdmhor.gen.nz) */
2390 k = -1.0f / (2.0f * (float)M_PI * blur * blur);
2392 for (ix = 0; ix < halfWidth; ix++) {
2393 weight = (float)exp(k * (ix * ix));
2394 filter[halfWidth - ix] = weight;
2395 filter[halfWidth + ix] = weight;
2399 /* Normalize the array */
2401 for (ix = 0; ix < halfWidth * 2; ix++)
2404 for (ix = 0; ix < halfWidth * 2; ix++)
2408 for (y = 0; y < height; y++) {
2409 /* Do the left & right strips */
2410 for (x = 0; x < halfWidth; x++) {
2411 index = (x + y * width) * 4;
2413 curColor[0] = curColor[1] = curColor[2] = 0.0f;
2414 curColor2[0] = curColor2[1] = curColor2[2] = 0.0f;
2416 for (i = x - halfWidth; i < x + halfWidth; i++) {
2417 if ((i >= 0) && (i < width)) {
2418 curColor[0] += map[(i + y * width) * 4 + GlowR] * filter[fx];
2419 curColor[1] += map[(i + y * width) * 4 + GlowG] * filter[fx];
2420 curColor[2] += map[(i + y * width) * 4 + GlowB] * filter[fx];
2422 curColor2[0] += map[(width - 1 - i + y * width) * 4 + GlowR] *
2424 curColor2[1] += map[(width - 1 - i + y * width) * 4 + GlowG] *
2426 curColor2[2] += map[(width - 1 - i + y * width) * 4 + GlowB] *
2431 temp[index + GlowR] = curColor[0];
2432 temp[index + GlowG] = curColor[1];
2433 temp[index + GlowB] = curColor[2];
2435 temp[((width - 1 - x + y * width) * 4) + GlowR] = curColor2[0];
2436 temp[((width - 1 - x + y * width) * 4) + GlowG] = curColor2[1];
2437 temp[((width - 1 - x + y * width) * 4) + GlowB] = curColor2[2];
2440 /* Do the main body */
2441 for (x = halfWidth; x < width - halfWidth; x++) {
2442 index = (x + y * width) * 4;
2445 for (i = x - halfWidth; i < x + halfWidth; i++) {
2446 curColor[0] += map[(i + y * width) * 4 + GlowR] * filter[fx];
2447 curColor[1] += map[(i + y * width) * 4 + GlowG] * filter[fx];
2448 curColor[2] += map[(i + y * width) * 4 + GlowB] * filter[fx];
2451 temp[index + GlowR] = curColor[0];
2452 temp[index + GlowG] = curColor[1];
2453 temp[index + GlowB] = curColor[2];
2458 swap = temp; temp = map; map = swap;
2461 /* Blur the columns */
2462 for (x = 0; x < width; x++) {
2463 /* Do the top & bottom strips */
2464 for (y = 0; y < halfWidth; y++) {
2465 index = (x + y * width) * 4;
2469 for (i = y - halfWidth; i < y + halfWidth; i++) {
2470 if ((i >= 0) && (i < height)) {
2472 curColor[0] += map[(x + i * width) * 4 + GlowR] * filter[fy];
2473 curColor[1] += map[(x + i * width) * 4 + GlowG] * filter[fy];
2474 curColor[2] += map[(x + i * width) * 4 + GlowB] * filter[fy];
2477 curColor2[0] += map[(x + (height - 1 - i) * width) *
2478 4 + GlowR] * filter[fy];
2479 curColor2[1] += map[(x + (height - 1 - i) * width) *
2480 4 + GlowG] * filter[fy];
2481 curColor2[2] += map[(x + (height - 1 - i) * width) *
2482 4 + GlowB] * filter[fy];
2486 temp[index + GlowR] = curColor[0];
2487 temp[index + GlowG] = curColor[1];
2488 temp[index + GlowB] = curColor[2];
2489 temp[((x + (height - 1 - y) * width) * 4) + GlowR] = curColor2[0];
2490 temp[((x + (height - 1 - y) * width) * 4) + GlowG] = curColor2[1];
2491 temp[((x + (height - 1 - y) * width) * 4) + GlowB] = curColor2[2];
2493 /* Do the main body */
2494 for (y = halfWidth; y < height - halfWidth; y++) {
2495 index = (x + y * width) * 4;
2498 for (i = y - halfWidth; i < y + halfWidth; i++) {
2499 curColor[0] += map[(x + i * width) * 4 + GlowR] * filter[fy];
2500 curColor[1] += map[(x + i * width) * 4 + GlowG] * filter[fy];
2501 curColor[2] += map[(x + i * width) * 4 + GlowB] * filter[fy];
2504 temp[index + GlowR] = curColor[0];
2505 temp[index + GlowG] = curColor[1];
2506 temp[index + GlowB] = curColor[2];
2512 swap = temp; temp = map; /* map = swap; */ /* UNUSED */
2520 /* Adds two bitmaps and puts the results into a third map. */
2521 /* C must have been previously allocated but it may be A or B. */
2522 /* We clamp values to 255 to prevent weirdness */
2523 /*=============================== */
2524 static void RVAddBitmaps_byte(unsigned char *a, unsigned char *b, unsigned char *c, int width, int height)
2528 for (y = 0; y < height; y++) {
2529 for (x = 0; x < width; x++) {
2530 index = (x + y * width) * 4;
2531 c[index + GlowR] = MIN2(255, a[index + GlowR] + b[index + GlowR]);
2532 c[index + GlowG] = MIN2(255, a[index + GlowG] + b[index + GlowG]);
2533 c[index + GlowB] = MIN2(255, a[index + GlowB] + b[index + GlowB]);
2534 c[index + GlowA] = MIN2(255, a[index + GlowA] + b[index + GlowA]);
2539 static void RVAddBitmaps_float(float *a, float *b, float *c,
2540 int width, int height)
2544 for (y = 0; y < height; y++) {
2545 for (x = 0; x < width; x++) {
2546 index = (x + y * width) * 4;
2547 c[index + GlowR] = MIN2(1.0f, a[index + GlowR] + b[index + GlowR]);
2548 c[index + GlowG] = MIN2(1.0f, a[index + GlowG] + b[index + GlowG]);
2549 c[index + GlowB] = MIN2(1.0f, a[index + GlowB] + b[index + GlowB]);
2550 c[index + GlowA] = MIN2(1.0f, a[index + GlowA] + b[index + GlowA]);
2555 /* For each pixel whose total luminance exceeds the threshold, */
2556 /* Multiply it's value by BOOST and add it to the output map */
2557 static void RVIsolateHighlights_byte(unsigned char *in, unsigned char *out,
2558 int width, int height, int threshold,
2559 float boost, float clamp)
2565 for (y = 0; y < height; y++) {
2566 for (x = 0; x < width; x++) {
2567 index = (x + y * width) * 4;
2569 /* Isolate the intensity */
2570 intensity = (in[index + GlowR] + in[index + GlowG] + in[index + GlowB] - threshold);
2571 if (intensity > 0) {
2572 out[index + GlowR] = MIN2(255 * clamp, (in[index + GlowR] * boost * intensity) / 255);
2573 out[index + GlowG] = MIN2(255 * clamp, (in[index + GlowG] * boost * intensity) / 255);
2574 out[index + GlowB] = MIN2(255 * clamp, (in[index + GlowB] * boost * intensity) / 255);
2575 out[index + GlowA] = MIN2(255 * clamp, (in[index + GlowA] * boost * intensity) / 255);
2578 out[index + GlowR] = 0;
2579 out[index + GlowG] = 0;
2580 out[index + GlowB] = 0;
2581 out[index + GlowA] = 0;
2587 static void RVIsolateHighlights_float(float *in, float *out,
2588 int width, int height, float threshold,
2589 float boost, float clamp)
2595 for (y = 0; y < height; y++) {
2596 for (x = 0; x < width; x++) {
2597 index = (x + y * width) * 4;
2599 /* Isolate the intensity */
2600 intensity = (in[index + GlowR] + in[index + GlowG] + in[index + GlowB] - threshold);
2601 if (intensity > 0) {
2602 out[index + GlowR] = MIN2(clamp, (in[index + GlowR] * boost * intensity));
2603 out[index + GlowG] = MIN2(clamp, (in[index + GlowG] * boost * intensity));
2604 out[index + GlowB] = MIN2(clamp, (in[index + GlowB] * boost * intensity));
2605 out[index + GlowA] = MIN2(clamp, (in[index + GlowA] * boost * intensity));
2608 out[index + GlowR] = 0;
2609 out[index + GlowG] = 0;
2610 out[index + GlowB] = 0;
2611 out[index + GlowA] = 0;
2617 static void init_glow_effect(Sequence *seq)
2621 if (seq->effectdata) MEM_freeN(seq->effectdata);
2622 seq->effectdata = MEM_callocN(sizeof(struct GlowVars), "glowvars");
2624 glow = (GlowVars *)seq->effectdata;
2633 static int num_inputs_glow(void)
2638 static void free_glow_effect(Sequence *seq)
2640 if (seq->effectdata) MEM_freeN(seq->effectdata);
2641 seq->effectdata = NULL;
2644 static void copy_glow_effect(Sequence *dst, Sequence *src)
2646 dst->effectdata = MEM_dupallocN(src->effectdata);
2649 //void do_glow_effect(Cast *cast, float facf0, float facf1, int xo, int yo, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *outbuf, ImBuf *use)
2650 static void do_glow_effect_byte(Sequence *seq, int render_size, float facf0, float UNUSED(facf1),
2651 int x, int y, char *rect1,
2652 char *UNUSED(rect2), char *out)
2654 unsigned char *outbuf = (unsigned char *)out;
2655 unsigned char *inbuf = (unsigned char *)rect1;
2656 GlowVars *glow = (GlowVars *)seq->effectdata;
2658 RVIsolateHighlights_byte(inbuf, outbuf, x, y, glow->fMini * 765, glow->fBoost * facf0, glow->fClamp);
2659 RVBlurBitmap2_byte(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality);
2661 RVAddBitmaps_byte(inbuf, outbuf, outbuf, x, y);
2664 static void do_glow_effect_float(Sequence *seq, int render_size, float facf0, float UNUSED(facf1),
2666 float *rect1, float *UNUSED(rect2), float *out)
2668 float *outbuf = out;
2669 float *inbuf = rect1;
2670 GlowVars *glow = (GlowVars *)seq->effectdata;
2672 RVIsolateHighlights_float(inbuf, outbuf, x, y, glow->fMini * 3.0f, glow->fBoost * facf0, glow->fClamp);
2673 RVBlurBitmap2_float(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality);
2675 RVAddBitmaps_float(inbuf, outbuf, outbuf, x, y);
2678 static ImBuf *do_glow_effect(
2679 SeqRenderData context, Sequence *seq, float UNUSED(cfra),
2680 float facf0, float facf1,
2681 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
2682 struct ImBuf *ibuf3)
2684 struct ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2686 int render_size = 100 * context.rectx / context.scene->r.xsch;
2688 if (out->rect_float) {
2689 do_glow_effect_float(seq, render_size,
2691 context.rectx, context.recty,
2692 ibuf1->rect_float, ibuf2->rect_float,
2696 do_glow_effect_byte(seq, render_size,
2698 context.rectx, context.recty,
2699 (char *) ibuf1->rect, (char *) ibuf2->rect,
2700 (char *) out->rect);
2706 /* **********************************************************************
2708 * ********************************************************************** */
2710 static void init_solid_color(Sequence *seq)
2714 if (seq->effectdata) MEM_freeN(seq->effectdata);
2715 seq->effectdata = MEM_callocN(sizeof(struct SolidColorVars), "solidcolor");
2717 cv = (SolidColorVars *)seq->effectdata;
2718 cv->col[0] = cv->col[1] = cv->col[2] = 0.5;
2721 static int num_inputs_color(void)
2726 static void free_solid_color(Sequence *seq)
2728 if (seq->effectdata) MEM_freeN(seq->effectdata);
2729 seq->effectdata = NULL;
2732 static void copy_solid_color(Sequence *dst, Sequence *src)
2734 dst->effectdata = MEM_dupallocN(src->effectdata);
2737 static int early_out_color(struct Sequence *UNUSED(seq),
2738 float UNUSED(facf0), float UNUSED(facf1))
2743 static ImBuf *do_solid_color(
2744 SeqRenderData context, Sequence *seq, float UNUSED(cfra),
2745 float facf0, float facf1,
2746 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
2747 struct ImBuf *ibuf3)
2749 struct ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2751 SolidColorVars *cv = (SolidColorVars *)seq->effectdata;
2753 unsigned char *rect;
2755 int x; /*= context.rectx;*/ /*UNUSED*/
2756 int y; /*= context.recty;*/ /*UNUSED*/
2759 unsigned char col0[3];
2760 unsigned char col1[3];
2762 col0[0] = facf0 * cv->col[0] * 255;
2763 col0[1] = facf0 * cv->col[1] * 255;
2764 col0[2] = facf0 * cv->col[2] * 255;
2766 col1[0] = facf1 * cv->col[0] * 255;
2767 col1[1] = facf1 * cv->col[1] * 255;
2768 col1[2] = facf1 * cv->col[2] * 255;
2770 rect = (unsigned char *)out->rect;
2772 for (y = 0; y < out->y; y++) {
2773 for (x = 0; x < out->x; x++, rect += 4) {
2781 for (x = 0; x < out->x; x++, rect += 4) {
2791 else if (out->rect_float) {
2795 col0[0] = facf0 * cv->col[0];
2796 col0[1] = facf0 * cv->col[1];
2797 col0[2] = facf0 * cv->col[2];
2799 col1[0] = facf1 * cv->col[0];
2800 col1[1] = facf1 * cv->col[1];
2801 col1[2] = facf1 * cv->col[2];
2803 rect_float = out->rect_float;
2805 for (y = 0; y < out->y; y++) {
2806 for (x = 0; x < out->x; x++, rect_float += 4) {
2807 rect_float[0] = col0[0];
2808 rect_float[1] = col0[1];
2809 rect_float[2] = col0[2];
2810 rect_float[3] = 1.0;
2814 for (x = 0; x < out->x; x++, rect_float += 4) {
2815 rect_float[0] = col1[0];
2816 rect_float[1] = col1[1];
2817 rect_float[2] = col1[2];
2818 rect_float[3] = 1.0;
2826 /* **********************************************************************
2828 * ********************************************************************** */
2830 /* no effect inputs for multicam, we use give_ibuf_seq */
2831 static int num_inputs_multicam(void)
2836 static int early_out_multicam(struct Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
2841 static ImBuf *do_multicam(
2842 SeqRenderData context, Sequence *seq, float cfra,
2843 float UNUSED(facf0), float UNUSED(facf1),
2844 struct ImBuf *UNUSED(ibuf1), struct ImBuf *UNUSED(ibuf2),
2845 struct ImBuf *UNUSED(ibuf3))
2852 if (seq->multicam_source == 0 || seq->multicam_source >= seq->machine) {
2856 ed = context.scene->ed;
2860 seqbasep = seq_seqbase(&ed->seqbase, seq);
2865 i = give_ibuf_seqbase(context, cfra, seq->multicam_source, seqbasep);
2870 if (input_have_to_preprocess(context, seq, cfra)) {
2871 out = IMB_dupImBuf(i);
2881 /* **********************************************************************
2883 * ********************************************************************** */
2885 /* no effect inputs for adjustment, we use give_ibuf_seq */
2886 static int num_inputs_adjustment(void)
2891 static int early_out_adjustment(struct Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
2896 static ImBuf *do_adjustment_impl(SeqRenderData context, Sequence *seq, float cfra)
2900 struct ImBuf *i = NULL;
2902 ed = context.scene->ed;
2904 seqbasep = seq_seqbase(&ed->seqbase, seq);
2906 if (seq->machine > 0) {
2907 i = give_ibuf_seqbase(context, cfra,
2908 seq->machine - 1, seqbasep);
2911 /* found nothing? so let's work the way up the metastrip stack, so
2912 * that it is possible to group a bunch of adjustment strips into
2913 * a metastrip and have that work on everything below the metastrip
2919 meta = seq_metastrip(&ed->seqbase, NULL, seq);
2922 i = do_adjustment_impl(context, meta, cfra);
2929 static ImBuf *do_adjustment(
2930 SeqRenderData context, Sequence *seq, float cfra,
2931 float UNUSED(facf0), float UNUSED(facf1),
2932 struct ImBuf *UNUSED(ibuf1), struct ImBuf *UNUSED(ibuf2),
2933 struct ImBuf *UNUSED(ibuf3))
2935 struct ImBuf *i = NULL;
2939 ed = context.scene->ed;
2945 i = do_adjustment_impl(context, seq, cfra);
2947 if (input_have_to_preprocess(context, seq, cfra)) {
2948 out = IMB_dupImBuf(i);
2958 /* **********************************************************************
2960 * ********************************************************************** */
2961 static void init_speed_effect(Sequence *seq)
2963 SpeedControlVars *v;
2965 if (seq->effectdata) MEM_freeN(seq->effectdata);
2966 seq->effectdata = MEM_callocN(sizeof(struct SpeedControlVars),
2967 "speedcontrolvars");
2969 v = (SpeedControlVars *)seq->effectdata;
2970 v->globalSpeed = 1.0;
2972 v->flags |= SEQ_SPEED_INTEGRATE; /* should be default behavior */
2976 static void load_speed_effect(Sequence *seq)
2978 SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
2984 static int num_inputs_speed(void)
2989 static void free_speed_effect(Sequence *seq)
2991 SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
2992 if (v->frameMap) MEM_freeN(v->frameMap);
2993 if (seq->effectdata) MEM_freeN(seq->effectdata);
2994 seq->effectdata = NULL;