Blender  V2.93
effects.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  *
19  * - Blender Foundation, 2003-2009
20  * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
21  */
22 
27 #include <math.h>
28 #include <stdlib.h>
29 #include <string.h>
30 
31 #include "MEM_guardedalloc.h"
32 
33 #include "BLI_listbase.h"
34 #include "BLI_math.h" /* windows needs for M_PI */
35 #include "BLI_path_util.h"
36 #include "BLI_rect.h"
37 #include "BLI_string.h"
38 #include "BLI_threads.h"
39 #include "BLI_utildefines.h"
40 
41 #include "DNA_anim_types.h"
42 #include "DNA_scene_types.h"
43 #include "DNA_sequence_types.h"
44 #include "DNA_space_types.h"
45 #include "DNA_vfont_types.h"
46 
47 #include "BKE_fcurve.h"
48 #include "BKE_lib_id.h"
49 #include "BKE_main.h"
50 
51 #include "IMB_colormanagement.h"
52 #include "IMB_imbuf.h"
53 #include "IMB_imbuf_types.h"
54 #include "IMB_metadata.h"
55 
56 #include "BLI_math_color_blend.h"
57 
58 #include "RNA_access.h"
59 
60 #include "RE_pipeline.h"
61 
62 #include "SEQ_effects.h"
63 #include "SEQ_proxy.h"
64 #include "SEQ_render.h"
65 #include "SEQ_utils.h"
66 
67 #include "BLF_api.h"
68 
69 #include "effects.h"
70 #include "render.h"
71 #include "strip_time.h"
72 #include "utils.h"
73 
74 static struct SeqEffectHandle get_sequence_effect_impl(int seq_type);
75 
77  const ImBuf *ibuf1,
78  const ImBuf *ibuf2,
79  const ImBuf *ibuf3,
80  const ImBuf *out,
81  int start_line,
82  unsigned char **rect1,
83  unsigned char **rect2,
84  unsigned char **rect3,
85  unsigned char **rect_out)
86 {
87  int offset = 4 * start_line * context->rectx;
88 
89  *rect1 = (unsigned char *)ibuf1->rect + offset;
90  *rect_out = (unsigned char *)out->rect + offset;
91 
92  if (ibuf2) {
93  *rect2 = (unsigned char *)ibuf2->rect + offset;
94  }
95 
96  if (ibuf3) {
97  *rect3 = (unsigned char *)ibuf3->rect + offset;
98  }
99 }
100 
102  const ImBuf *ibuf1,
103  const ImBuf *ibuf2,
104  const ImBuf *ibuf3,
105  const ImBuf *out,
106  int start_line,
107  float **rect1,
108  float **rect2,
109  float **rect3,
110  float **rect_out)
111 {
112  int offset = 4 * start_line * context->rectx;
113 
114  *rect1 = ibuf1->rect_float + offset;
115  *rect_out = out->rect_float + offset;
116 
117  if (ibuf2) {
118  *rect2 = ibuf2->rect_float + offset;
119  }
120 
121  if (ibuf3) {
122  *rect3 = ibuf3->rect_float + offset;
123  }
124 }
125 
126 /*********************** Glow effect *************************/
127 
128 enum {
129  GlowR = 0,
130  GlowG = 1,
131  GlowB = 2,
132  GlowA = 3,
133 };
134 
136  ImBuf *ibuf1,
137  ImBuf *ibuf2,
138  ImBuf *ibuf3)
139 {
140  ImBuf *out;
141  Scene *scene = context->scene;
142  int x = context->rectx;
143  int y = context->recty;
144 
145  if (!ibuf1 && !ibuf2 && !ibuf3) {
146  /* hmmm, global float option ? */
147  out = IMB_allocImBuf(x, y, 32, IB_rect);
148  }
149  else if ((ibuf1 && ibuf1->rect_float) || (ibuf2 && ibuf2->rect_float) ||
150  (ibuf3 && ibuf3->rect_float)) {
151  /* if any inputs are rectfloat, output is float too */
152 
153  out = IMB_allocImBuf(x, y, 32, IB_rectfloat);
154  }
155  else {
156  out = IMB_allocImBuf(x, y, 32, IB_rect);
157  }
158 
159  if (out->rect_float) {
160  if (ibuf1 && !ibuf1->rect_float) {
161  seq_imbuf_to_sequencer_space(scene, ibuf1, true);
162  }
163 
164  if (ibuf2 && !ibuf2->rect_float) {
165  seq_imbuf_to_sequencer_space(scene, ibuf2, true);
166  }
167 
168  if (ibuf3 && !ibuf3->rect_float) {
169  seq_imbuf_to_sequencer_space(scene, ibuf3, true);
170  }
171 
173  }
174  else {
175  if (ibuf1 && !ibuf1->rect) {
176  IMB_rect_from_float(ibuf1);
177  }
178 
179  if (ibuf2 && !ibuf2->rect) {
180  IMB_rect_from_float(ibuf2);
181  }
182 
183  if (ibuf3 && !ibuf3->rect) {
184  IMB_rect_from_float(ibuf3);
185  }
186  }
187 
188  /* If effect only affecting a single channel, forward input's metadata to the output. */
189  if (ibuf1 != NULL && ibuf1 == ibuf2 && ibuf2 == ibuf3) {
190  IMB_metadata_copy(out, ibuf1);
191  }
192 
193  return out;
194 }
195 
196 /*********************** Alpha Over *************************/
197 
199 {
200  Sequence *seq1 = seq->seq1;
201  Sequence *seq2 = seq->seq2;
202 
203  seq->seq2 = seq1;
204  seq->seq1 = seq2;
205 }
206 
207 static void do_alphaover_effect_byte(float facf0,
208  float facf1,
209  int x,
210  int y,
211  unsigned char *rect1,
212  unsigned char *rect2,
213  unsigned char *out)
214 {
215  float fac2, mfac, fac, fac4;
216  int xo;
217  unsigned char *cp1, *cp2, *rt;
218  float tempc[4], rt1[4], rt2[4];
219 
220  xo = x;
221  cp1 = rect1;
222  cp2 = rect2;
223  rt = out;
224 
225  fac2 = facf0;
226  fac4 = facf1;
227 
228  while (y--) {
229  x = xo;
230  while (x--) {
231  /* rt = rt1 over rt2 (alpha from rt1) */
232 
235 
236  fac = fac2;
237  mfac = 1.0f - fac2 * rt1[3];
238 
239  if (fac <= 0.0f) {
240  *((unsigned int *)rt) = *((unsigned int *)cp2);
241  }
242  else if (mfac <= 0.0f) {
243  *((unsigned int *)rt) = *((unsigned int *)cp1);
244  }
245  else {
246  tempc[0] = fac * rt1[0] + mfac * rt2[0];
247  tempc[1] = fac * rt1[1] + mfac * rt2[1];
248  tempc[2] = fac * rt1[2] + mfac * rt2[2];
249  tempc[3] = fac * rt1[3] + mfac * rt2[3];
250 
252  }
253  cp1 += 4;
254  cp2 += 4;
255  rt += 4;
256  }
257 
258  if (y == 0) {
259  break;
260  }
261  y--;
262 
263  x = xo;
264  while (x--) {
267 
268  fac = fac4;
269  mfac = 1.0f - (fac4 * rt1[3]);
270 
271  if (fac <= 0.0f) {
272  *((unsigned int *)rt) = *((unsigned int *)cp2);
273  }
274  else if (mfac <= 0.0f) {
275  *((unsigned int *)rt) = *((unsigned int *)cp1);
276  }
277  else {
278  tempc[0] = fac * rt1[0] + mfac * rt2[0];
279  tempc[1] = fac * rt1[1] + mfac * rt2[1];
280  tempc[2] = fac * rt1[2] + mfac * rt2[2];
281  tempc[3] = fac * rt1[3] + mfac * rt2[3];
282 
284  }
285  cp1 += 4;
286  cp2 += 4;
287  rt += 4;
288  }
289  }
290 }
291 
293  float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out)
294 {
295  float fac2, mfac, fac, fac4;
296  int xo;
297  float *rt1, *rt2, *rt;
298 
299  xo = x;
300  rt1 = rect1;
301  rt2 = rect2;
302  rt = out;
303 
304  fac2 = facf0;
305  fac4 = facf1;
306 
307  while (y--) {
308  x = xo;
309  while (x--) {
310  /* rt = rt1 over rt2 (alpha from rt1) */
311 
312  fac = fac2;
313  mfac = 1.0f - (fac2 * rt1[3]);
314 
315  if (fac <= 0.0f) {
316  memcpy(rt, rt2, sizeof(float[4]));
317  }
318  else if (mfac <= 0) {
319  memcpy(rt, rt1, sizeof(float[4]));
320  }
321  else {
322  rt[0] = fac * rt1[0] + mfac * rt2[0];
323  rt[1] = fac * rt1[1] + mfac * rt2[1];
324  rt[2] = fac * rt1[2] + mfac * rt2[2];
325  rt[3] = fac * rt1[3] + mfac * rt2[3];
326  }
327  rt1 += 4;
328  rt2 += 4;
329  rt += 4;
330  }
331 
332  if (y == 0) {
333  break;
334  }
335  y--;
336 
337  x = xo;
338  while (x--) {
339  fac = fac4;
340  mfac = 1.0f - (fac4 * rt1[3]);
341 
342  if (fac <= 0.0f) {
343  memcpy(rt, rt2, sizeof(float[4]));
344  }
345  else if (mfac <= 0.0f) {
346  memcpy(rt, rt1, sizeof(float[4]));
347  }
348  else {
349  rt[0] = fac * rt1[0] + mfac * rt2[0];
350  rt[1] = fac * rt1[1] + mfac * rt2[1];
351  rt[2] = fac * rt1[2] + mfac * rt2[2];
352  rt[3] = fac * rt1[3] + mfac * rt2[3];
353  }
354  rt1 += 4;
355  rt2 += 4;
356  rt += 4;
357  }
358  }
359 }
360 
362  Sequence *UNUSED(seq),
363  float UNUSED(timeline_frame),
364  float facf0,
365  float facf1,
366  ImBuf *ibuf1,
367  ImBuf *ibuf2,
368  ImBuf *UNUSED(ibuf3),
369  int start_line,
370  int total_lines,
371  ImBuf *out)
372 {
373  if (out->rect_float) {
374  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
375 
377  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
378 
379  do_alphaover_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out);
380  }
381  else {
382  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
383 
385  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
386 
387  do_alphaover_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out);
388  }
389 }
390 
391 /*********************** Alpha Under *************************/
392 
393 static void do_alphaunder_effect_byte(float facf0,
394  float facf1,
395  int x,
396  int y,
397  unsigned char *rect1,
398  unsigned char *rect2,
399  unsigned char *out)
400 {
401  float fac2, fac, fac4;
402  int xo;
403  unsigned char *cp1, *cp2, *rt;
404  float tempc[4], rt1[4], rt2[4];
405 
406  xo = x;
407  cp1 = rect1;
408  cp2 = rect2;
409  rt = out;
410 
411  fac2 = facf0;
412  fac4 = facf1;
413 
414  while (y--) {
415  x = xo;
416  while (x--) {
417  /* rt = rt1 under rt2 (alpha from rt2) */
420 
421  /* this complex optimization is because the
422  * 'skybuf' can be crossed in
423  */
424  if (rt2[3] <= 0.0f && fac2 >= 1.0f) {
425  *((unsigned int *)rt) = *((unsigned int *)cp1);
426  }
427  else if (rt2[3] >= 1.0f) {
428  *((unsigned int *)rt) = *((unsigned int *)cp2);
429  }
430  else {
431  fac = (fac2 * (1.0f - rt2[3]));
432 
433  if (fac <= 0) {
434  *((unsigned int *)rt) = *((unsigned int *)cp2);
435  }
436  else {
437  tempc[0] = (fac * rt1[0] + rt2[0]);
438  tempc[1] = (fac * rt1[1] + rt2[1]);
439  tempc[2] = (fac * rt1[2] + rt2[2]);
440  tempc[3] = (fac * rt1[3] + rt2[3]);
441 
443  }
444  }
445  cp1 += 4;
446  cp2 += 4;
447  rt += 4;
448  }
449 
450  if (y == 0) {
451  break;
452  }
453  y--;
454 
455  x = xo;
456  while (x--) {
459 
460  if (rt2[3] <= 0.0f && fac4 >= 1.0f) {
461  *((unsigned int *)rt) = *((unsigned int *)cp1);
462  }
463  else if (rt2[3] >= 1.0f) {
464  *((unsigned int *)rt) = *((unsigned int *)cp2);
465  }
466  else {
467  fac = (fac4 * (1.0f - rt2[3]));
468 
469  if (fac <= 0) {
470  *((unsigned int *)rt) = *((unsigned int *)cp2);
471  }
472  else {
473  tempc[0] = (fac * rt1[0] + rt2[0]);
474  tempc[1] = (fac * rt1[1] + rt2[1]);
475  tempc[2] = (fac * rt1[2] + rt2[2]);
476  tempc[3] = (fac * rt1[3] + rt2[3]);
477 
479  }
480  }
481  cp1 += 4;
482  cp2 += 4;
483  rt += 4;
484  }
485  }
486 }
487 
489  float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out)
490 {
491  float fac2, fac, fac4;
492  int xo;
493  float *rt1, *rt2, *rt;
494 
495  xo = x;
496  rt1 = rect1;
497  rt2 = rect2;
498  rt = out;
499 
500  fac2 = facf0;
501  fac4 = facf1;
502 
503  while (y--) {
504  x = xo;
505  while (x--) {
506  /* rt = rt1 under rt2 (alpha from rt2) */
507 
508  /* this complex optimization is because the
509  * 'skybuf' can be crossed in
510  */
511  if (rt2[3] <= 0 && fac2 >= 1.0f) {
512  memcpy(rt, rt1, sizeof(float[4]));
513  }
514  else if (rt2[3] >= 1.0f) {
515  memcpy(rt, rt2, sizeof(float[4]));
516  }
517  else {
518  fac = fac2 * (1.0f - rt2[3]);
519 
520  if (fac == 0) {
521  memcpy(rt, rt2, sizeof(float[4]));
522  }
523  else {
524  rt[0] = fac * rt1[0] + rt2[0];
525  rt[1] = fac * rt1[1] + rt2[1];
526  rt[2] = fac * rt1[2] + rt2[2];
527  rt[3] = fac * rt1[3] + rt2[3];
528  }
529  }
530  rt1 += 4;
531  rt2 += 4;
532  rt += 4;
533  }
534 
535  if (y == 0) {
536  break;
537  }
538  y--;
539 
540  x = xo;
541  while (x--) {
542  if (rt2[3] <= 0 && fac4 >= 1.0f) {
543  memcpy(rt, rt1, sizeof(float[4]));
544  }
545  else if (rt2[3] >= 1.0f) {
546  memcpy(rt, rt2, sizeof(float[4]));
547  }
548  else {
549  fac = fac4 * (1.0f - rt2[3]);
550 
551  if (fac == 0) {
552  memcpy(rt, rt2, sizeof(float[4]));
553  }
554  else {
555  rt[0] = fac * rt1[0] + rt2[0];
556  rt[1] = fac * rt1[1] + rt2[1];
557  rt[2] = fac * rt1[2] + rt2[2];
558  rt[3] = fac * rt1[3] + rt2[3];
559  }
560  }
561  rt1 += 4;
562  rt2 += 4;
563  rt += 4;
564  }
565  }
566 }
567 
569  Sequence *UNUSED(seq),
570  float UNUSED(timeline_frame),
571  float facf0,
572  float facf1,
573  ImBuf *ibuf1,
574  ImBuf *ibuf2,
575  ImBuf *UNUSED(ibuf3),
576  int start_line,
577  int total_lines,
578  ImBuf *out)
579 {
580  if (out->rect_float) {
581  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
582 
584  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
585 
586  do_alphaunder_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out);
587  }
588  else {
589  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
590 
592  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
593 
594  do_alphaunder_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out);
595  }
596 }
597 
598 /*********************** Cross *************************/
599 
600 static void do_cross_effect_byte(float facf0,
601  float facf1,
602  int x,
603  int y,
604  unsigned char *rect1,
605  unsigned char *rect2,
606  unsigned char *out)
607 {
608  int fac1, fac2, fac3, fac4;
609  int xo;
610  unsigned char *rt1, *rt2, *rt;
611 
612  xo = x;
613  rt1 = rect1;
614  rt2 = rect2;
615  rt = out;
616 
617  fac2 = (int)(256.0f * facf0);
618  fac1 = 256 - fac2;
619  fac4 = (int)(256.0f * facf1);
620  fac3 = 256 - fac4;
621 
622  while (y--) {
623  x = xo;
624  while (x--) {
625  rt[0] = (fac1 * rt1[0] + fac2 * rt2[0]) >> 8;
626  rt[1] = (fac1 * rt1[1] + fac2 * rt2[1]) >> 8;
627  rt[2] = (fac1 * rt1[2] + fac2 * rt2[2]) >> 8;
628  rt[3] = (fac1 * rt1[3] + fac2 * rt2[3]) >> 8;
629 
630  rt1 += 4;
631  rt2 += 4;
632  rt += 4;
633  }
634 
635  if (y == 0) {
636  break;
637  }
638  y--;
639 
640  x = xo;
641  while (x--) {
642  rt[0] = (fac3 * rt1[0] + fac4 * rt2[0]) >> 8;
643  rt[1] = (fac3 * rt1[1] + fac4 * rt2[1]) >> 8;
644  rt[2] = (fac3 * rt1[2] + fac4 * rt2[2]) >> 8;
645  rt[3] = (fac3 * rt1[3] + fac4 * rt2[3]) >> 8;
646 
647  rt1 += 4;
648  rt2 += 4;
649  rt += 4;
650  }
651  }
652 }
653 
655  float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out)
656 {
657  float fac1, fac2, fac3, fac4;
658  int xo;
659  float *rt1, *rt2, *rt;
660 
661  xo = x;
662  rt1 = rect1;
663  rt2 = rect2;
664  rt = out;
665 
666  fac2 = facf0;
667  fac1 = 1.0f - fac2;
668  fac4 = facf1;
669  fac3 = 1.0f - fac4;
670 
671  while (y--) {
672  x = xo;
673  while (x--) {
674  rt[0] = fac1 * rt1[0] + fac2 * rt2[0];
675  rt[1] = fac1 * rt1[1] + fac2 * rt2[1];
676  rt[2] = fac1 * rt1[2] + fac2 * rt2[2];
677  rt[3] = fac1 * rt1[3] + fac2 * rt2[3];
678 
679  rt1 += 4;
680  rt2 += 4;
681  rt += 4;
682  }
683 
684  if (y == 0) {
685  break;
686  }
687  y--;
688 
689  x = xo;
690  while (x--) {
691  rt[0] = fac3 * rt1[0] + fac4 * rt2[0];
692  rt[1] = fac3 * rt1[1] + fac4 * rt2[1];
693  rt[2] = fac3 * rt1[2] + fac4 * rt2[2];
694  rt[3] = fac3 * rt1[3] + fac4 * rt2[3];
695 
696  rt1 += 4;
697  rt2 += 4;
698  rt += 4;
699  }
700  }
701 }
702 
704  Sequence *UNUSED(seq),
705  float UNUSED(timeline_frame),
706  float facf0,
707  float facf1,
708  ImBuf *ibuf1,
709  ImBuf *ibuf2,
710  ImBuf *UNUSED(ibuf3),
711  int start_line,
712  int total_lines,
713  ImBuf *out)
714 {
715  if (out->rect_float) {
716  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
717 
719  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
720 
721  do_cross_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out);
722  }
723  else {
724  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
725 
727  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
728 
729  do_cross_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out);
730  }
731 }
732 
733 /*********************** Gamma Cross *************************/
734 
735 /* copied code from initrender.c */
736 static unsigned short gamtab[65536];
737 static unsigned short igamtab1[256];
738 static bool gamma_tabs_init = false;
739 
740 #define RE_GAMMA_TABLE_SIZE 400
741 
747 static float color_step;
748 static float inv_color_step;
749 static float valid_gamma;
750 static float valid_inv_gamma;
751 
752 static void makeGammaTables(float gamma)
753 {
754  /* we need two tables: one forward, one backward */
755  int i;
756 
757  valid_gamma = gamma;
758  valid_inv_gamma = 1.0f / gamma;
761 
762  /* We could squeeze out the two range tables to gain some memory */
763  for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++) {
767  }
768 
769  /* The end of the table should match 1.0 carefully. In order to avoid
770  * rounding errors, we just set this explicitly. The last segment may
771  * have a different length than the other segments, but our
772  * interpolation is insensitive to that
773  */
777 
778  /* To speed up calculations, we make these calc factor tables. They are
779  * multiplication factors used in scaling the interpolation
780  */
781  for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++) {
785  }
786 }
787 
788 static float gammaCorrect(float c)
789 {
790  int i;
791  float res;
792 
793  i = floorf(c * inv_color_step);
794  /* Clip to range [0, 1]: outside, just do the complete calculation.
795  * We may have some performance problems here. Stretching up the LUT
796  * may help solve that, by exchanging LUT size for the interpolation.
797  * Negative colors are explicitly handled.
798  */
799  if (UNLIKELY(i < 0)) {
800  res = -powf(-c, valid_gamma);
801  }
802  else if (i >= RE_GAMMA_TABLE_SIZE) {
803  res = powf(c, valid_gamma);
804  }
805  else {
806  res = gamma_range_table[i] + ((c - color_domain_table[i]) * gamfactor_table[i]);
807  }
808 
809  return res;
810 }
811 
812 /* ------------------------------------------------------------------------- */
813 
814 static float invGammaCorrect(float c)
815 {
816  int i;
817  float res = 0.0;
818 
819  i = floorf(c * inv_color_step);
820  /* Negative colors are explicitly handled */
821  if (UNLIKELY(i < 0)) {
822  res = -powf(-c, valid_inv_gamma);
823  }
824  else if (i >= RE_GAMMA_TABLE_SIZE) {
825  res = powf(c, valid_inv_gamma);
826  }
827  else {
829  }
830 
831  return res;
832 }
833 
834 static void gamtabs(float gamma)
835 {
836  float val, igamma = 1.0f / gamma;
837  int a;
838 
839  /* gamtab: in short, out short */
840  for (a = 0; a < 65536; a++) {
841  val = a;
842  val /= 65535.0f;
843 
844  if (gamma == 2.0f) {
845  val = sqrtf(val);
846  }
847  else if (gamma != 1.0f) {
848  val = powf(val, igamma);
849  }
850 
851  gamtab[a] = (65535.99f * val);
852  }
853  /* inverse gamtab1 : in byte, out short */
854  for (a = 1; a <= 256; a++) {
855  if (gamma == 2.0f) {
856  igamtab1[a - 1] = a * a - 1;
857  }
858  else if (gamma == 1.0f) {
859  igamtab1[a - 1] = 256 * a - 1;
860  }
861  else {
862  val = a / 256.0f;
863  igamtab1[a - 1] = (65535.0 * pow(val, gamma)) - 1;
864  }
865  }
866 }
867 
868 static void build_gammatabs(void)
869 {
870  if (gamma_tabs_init == false) {
871  gamtabs(2.0f);
872  makeGammaTables(2.0f);
873  gamma_tabs_init = true;
874  }
875 }
876 
877 static void init_gammacross(Sequence *UNUSED(seq))
878 {
879 }
880 
881 static void load_gammacross(Sequence *UNUSED(seq))
882 {
883 }
884 
885 static void free_gammacross(Sequence *UNUSED(seq), const bool UNUSED(do_id_user))
886 {
887 }
888 
889 static void do_gammacross_effect_byte(float facf0,
890  float UNUSED(facf1),
891  int x,
892  int y,
893  unsigned char *rect1,
894  unsigned char *rect2,
895  unsigned char *out)
896 {
897  float fac1, fac2;
898  int xo;
899  unsigned char *cp1, *cp2, *rt;
900  float rt1[4], rt2[4], tempc[4];
901 
902  xo = x;
903  cp1 = rect1;
904  cp2 = rect2;
905  rt = out;
906 
907  fac2 = facf0;
908  fac1 = 1.0f - fac2;
909 
910  while (y--) {
911  x = xo;
912  while (x--) {
915 
916  tempc[0] = gammaCorrect(fac1 * invGammaCorrect(rt1[0]) + fac2 * invGammaCorrect(rt2[0]));
917  tempc[1] = gammaCorrect(fac1 * invGammaCorrect(rt1[1]) + fac2 * invGammaCorrect(rt2[1]));
918  tempc[2] = gammaCorrect(fac1 * invGammaCorrect(rt1[2]) + fac2 * invGammaCorrect(rt2[2]));
919  tempc[3] = gammaCorrect(fac1 * invGammaCorrect(rt1[3]) + fac2 * invGammaCorrect(rt2[3]));
920 
922  cp1 += 4;
923  cp2 += 4;
924  rt += 4;
925  }
926 
927  if (y == 0) {
928  break;
929  }
930  y--;
931 
932  x = xo;
933  while (x--) {
936 
937  tempc[0] = gammaCorrect(fac1 * invGammaCorrect(rt1[0]) + fac2 * invGammaCorrect(rt2[0]));
938  tempc[1] = gammaCorrect(fac1 * invGammaCorrect(rt1[1]) + fac2 * invGammaCorrect(rt2[1]));
939  tempc[2] = gammaCorrect(fac1 * invGammaCorrect(rt1[2]) + fac2 * invGammaCorrect(rt2[2]));
940  tempc[3] = gammaCorrect(fac1 * invGammaCorrect(rt1[3]) + fac2 * invGammaCorrect(rt2[3]));
941 
943  cp1 += 4;
944  cp2 += 4;
945  rt += 4;
946  }
947  }
948 }
949 
951  float facf0, float UNUSED(facf1), int x, int y, float *rect1, float *rect2, float *out)
952 {
953  float fac1, fac2;
954  int xo;
955  float *rt1, *rt2, *rt;
956 
957  xo = x;
958  rt1 = rect1;
959  rt2 = rect2;
960  rt = out;
961 
962  fac2 = facf0;
963  fac1 = 1.0f - fac2;
964 
965  while (y--) {
966  x = xo * 4;
967  while (x--) {
968  *rt = gammaCorrect(fac1 * invGammaCorrect(*rt1) + fac2 * invGammaCorrect(*rt2));
969  rt1++;
970  rt2++;
971  rt++;
972  }
973 
974  if (y == 0) {
975  break;
976  }
977  y--;
978 
979  x = xo * 4;
980  while (x--) {
981  *rt = gammaCorrect(fac1 * invGammaCorrect(*rt1) + fac2 * invGammaCorrect(*rt2));
982 
983  rt1++;
984  rt2++;
985  rt++;
986  }
987  }
988 }
989 
991  ImBuf *ibuf1,
992  ImBuf *ibuf2,
993  ImBuf *ibuf3)
994 {
995  ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
996  build_gammatabs();
997 
998  return out;
999 }
1000 
1002  Sequence *UNUSED(seq),
1003  float UNUSED(timeline_frame),
1004  float facf0,
1005  float facf1,
1006  ImBuf *ibuf1,
1007  ImBuf *ibuf2,
1008  ImBuf *UNUSED(ibuf3),
1009  int start_line,
1010  int total_lines,
1011  ImBuf *out)
1012 {
1013  if (out->rect_float) {
1014  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
1015 
1017  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1018 
1019  do_gammacross_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out);
1020  }
1021  else {
1022  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
1023 
1025  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1026 
1027  do_gammacross_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out);
1028  }
1029 }
1030 
1031 /*********************** Add *************************/
1032 
1033 static void do_add_effect_byte(float facf0,
1034  float facf1,
1035  int x,
1036  int y,
1037  unsigned char *rect1,
1038  unsigned char *rect2,
1039  unsigned char *out)
1040 {
1041  int xo, fac1, fac3;
1042  unsigned char *cp1, *cp2, *rt;
1043 
1044  xo = x;
1045  cp1 = rect1;
1046  cp2 = rect2;
1047  rt = out;
1048 
1049  fac1 = (int)(256.0f * facf0);
1050  fac3 = (int)(256.0f * facf1);
1051 
1052  while (y--) {
1053  x = xo;
1054 
1055  while (x--) {
1056  const int m = fac1 * (int)cp2[3];
1057  rt[0] = min_ii(cp1[0] + ((m * cp2[0]) >> 16), 255);
1058  rt[1] = min_ii(cp1[1] + ((m * cp2[1]) >> 16), 255);
1059  rt[2] = min_ii(cp1[2] + ((m * cp2[2]) >> 16), 255);
1060  rt[3] = cp1[3];
1061 
1062  cp1 += 4;
1063  cp2 += 4;
1064  rt += 4;
1065  }
1066 
1067  if (y == 0) {
1068  break;
1069  }
1070  y--;
1071 
1072  x = xo;
1073  while (x--) {
1074  const int m = fac3 * (int)cp2[3];
1075  rt[0] = min_ii(cp1[0] + ((m * cp2[0]) >> 16), 255);
1076  rt[1] = min_ii(cp1[1] + ((m * cp2[1]) >> 16), 255);
1077  rt[2] = min_ii(cp1[2] + ((m * cp2[2]) >> 16), 255);
1078  rt[3] = cp1[3];
1079 
1080  cp1 += 4;
1081  cp2 += 4;
1082  rt += 4;
1083  }
1084  }
1085 }
1086 
1088  float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out)
1089 {
1090  int xo;
1091  float fac1, fac3;
1092  float *rt1, *rt2, *rt;
1093 
1094  xo = x;
1095  rt1 = rect1;
1096  rt2 = rect2;
1097  rt = out;
1098 
1099  fac1 = facf0;
1100  fac3 = facf1;
1101 
1102  while (y--) {
1103  x = xo;
1104  while (x--) {
1105  const float m = (1.0f - (rt1[3] * (1.0f - fac1))) * rt2[3];
1106  rt[0] = rt1[0] + m * rt2[0];
1107  rt[1] = rt1[1] + m * rt2[1];
1108  rt[2] = rt1[2] + m * rt2[2];
1109  rt[3] = rt1[3];
1110 
1111  rt1 += 4;
1112  rt2 += 4;
1113  rt += 4;
1114  }
1115 
1116  if (y == 0) {
1117  break;
1118  }
1119  y--;
1120 
1121  x = xo;
1122  while (x--) {
1123  const float m = (1.0f - (rt1[3] * (1.0f - fac3))) * rt2[3];
1124  rt[0] = rt1[0] + m * rt2[0];
1125  rt[1] = rt1[1] + m * rt2[1];
1126  rt[2] = rt1[2] + m * rt2[2];
1127  rt[3] = rt1[3];
1128 
1129  rt1 += 4;
1130  rt2 += 4;
1131  rt += 4;
1132  }
1133  }
1134 }
1135 
1137  Sequence *UNUSED(seq),
1138  float UNUSED(timeline_frame),
1139  float facf0,
1140  float facf1,
1141  ImBuf *ibuf1,
1142  ImBuf *ibuf2,
1143  ImBuf *UNUSED(ibuf3),
1144  int start_line,
1145  int total_lines,
1146  ImBuf *out)
1147 {
1148  if (out->rect_float) {
1149  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
1150 
1152  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1153 
1154  do_add_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out);
1155  }
1156  else {
1157  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
1158 
1160  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1161 
1162  do_add_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out);
1163  }
1164 }
1165 
1166 /*********************** Sub *************************/
1167 
1168 static void do_sub_effect_byte(float facf0,
1169  float facf1,
1170  int x,
1171  int y,
1172  unsigned char *rect1,
1173  unsigned char *rect2,
1174  unsigned char *out)
1175 {
1176  int xo, fac1, fac3;
1177  unsigned char *cp1, *cp2, *rt;
1178 
1179  xo = x;
1180  cp1 = rect1;
1181  cp2 = rect2;
1182  rt = out;
1183 
1184  fac1 = (int)(256.0f * facf0);
1185  fac3 = (int)(256.0f * facf1);
1186 
1187  while (y--) {
1188  x = xo;
1189  while (x--) {
1190  const int m = fac1 * (int)cp2[3];
1191  rt[0] = max_ii(cp1[0] - ((m * cp2[0]) >> 16), 0);
1192  rt[1] = max_ii(cp1[1] - ((m * cp2[1]) >> 16), 0);
1193  rt[2] = max_ii(cp1[2] - ((m * cp2[2]) >> 16), 0);
1194  rt[3] = cp1[3];
1195 
1196  cp1 += 4;
1197  cp2 += 4;
1198  rt += 4;
1199  }
1200 
1201  if (y == 0) {
1202  break;
1203  }
1204  y--;
1205 
1206  x = xo;
1207  while (x--) {
1208  const int m = fac3 * (int)cp2[3];
1209  rt[0] = max_ii(cp1[0] - ((m * cp2[0]) >> 16), 0);
1210  rt[1] = max_ii(cp1[1] - ((m * cp2[1]) >> 16), 0);
1211  rt[2] = max_ii(cp1[2] - ((m * cp2[2]) >> 16), 0);
1212  rt[3] = cp1[3];
1213 
1214  cp1 += 4;
1215  cp2 += 4;
1216  rt += 4;
1217  }
1218  }
1219 }
1220 
1222  float UNUSED(facf0), float facf1, int x, int y, float *rect1, float *rect2, float *out)
1223 {
1224  int xo;
1225  float /* fac1, */ fac3_inv;
1226  float *rt1, *rt2, *rt;
1227 
1228  xo = x;
1229  rt1 = rect1;
1230  rt2 = rect2;
1231  rt = out;
1232 
1233  /* UNUSED */
1234  // fac1 = facf0;
1235  fac3_inv = 1.0f - facf1;
1236 
1237  while (y--) {
1238  x = xo;
1239  while (x--) {
1240  const float m = (1.0f - (rt1[3] * fac3_inv)) * rt2[3];
1241  rt[0] = max_ff(rt1[0] - m * rt2[0], 0.0f);
1242  rt[1] = max_ff(rt1[1] - m * rt2[1], 0.0f);
1243  rt[2] = max_ff(rt1[2] - m * rt2[2], 0.0f);
1244  rt[3] = rt1[3];
1245 
1246  rt1 += 4;
1247  rt2 += 4;
1248  rt += 4;
1249  }
1250 
1251  if (y == 0) {
1252  break;
1253  }
1254  y--;
1255 
1256  x = xo;
1257  while (x--) {
1258  const float m = (1.0f - (rt1[3] * fac3_inv)) * rt2[3];
1259  rt[0] = max_ff(rt1[0] - m * rt2[0], 0.0f);
1260  rt[1] = max_ff(rt1[1] - m * rt2[1], 0.0f);
1261  rt[2] = max_ff(rt1[2] - m * rt2[2], 0.0f);
1262  rt[3] = rt1[3];
1263 
1264  rt1 += 4;
1265  rt2 += 4;
1266  rt += 4;
1267  }
1268  }
1269 }
1270 
1272  Sequence *UNUSED(seq),
1273  float UNUSED(timeline_frame),
1274  float facf0,
1275  float facf1,
1276  ImBuf *ibuf1,
1277  ImBuf *ibuf2,
1278  ImBuf *UNUSED(ibuf3),
1279  int start_line,
1280  int total_lines,
1281  ImBuf *out)
1282 {
1283  if (out->rect_float) {
1284  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
1285 
1287  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1288 
1289  do_sub_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out);
1290  }
1291  else {
1292  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
1293 
1295  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1296 
1297  do_sub_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out);
1298  }
1299 }
1300 
1301 /*********************** Drop *************************/
1302 
1303 /* Must be > 0 or add precopy, etc to the function */
1304 #define XOFF 8
1305 #define YOFF 8
1306 
1307 static void do_drop_effect_byte(float facf0,
1308  float facf1,
1309  int x,
1310  int y,
1311  unsigned char *rect2i,
1312  unsigned char *rect1i,
1313  unsigned char *outi)
1314 {
1315  int temp, fac, fac1, fac2;
1316  unsigned char *rt1, *rt2, *out;
1317  int field = 1;
1318 
1319  const int width = x;
1320  const int height = y;
1321  const int xoff = min_ii(XOFF, width);
1322  const int yoff = min_ii(YOFF, height);
1323 
1324  fac1 = (int)(70.0f * facf0);
1325  fac2 = (int)(70.0f * facf1);
1326 
1327  rt2 = rect2i + yoff * 4 * width;
1328  rt1 = rect1i;
1329  out = outi;
1330  for (y = 0; y < height - yoff; y++) {
1331  if (field) {
1332  fac = fac1;
1333  }
1334  else {
1335  fac = fac2;
1336  }
1337  field = !field;
1338 
1339  memcpy(out, rt1, sizeof(*out) * xoff * 4);
1340  rt1 += xoff * 4;
1341  out += xoff * 4;
1342 
1343  for (x = xoff; x < width; x++) {
1344  temp = ((fac * rt2[3]) >> 8);
1345 
1346  *(out++) = MAX2(0, *rt1 - temp);
1347  rt1++;
1348  *(out++) = MAX2(0, *rt1 - temp);
1349  rt1++;
1350  *(out++) = MAX2(0, *rt1 - temp);
1351  rt1++;
1352  *(out++) = MAX2(0, *rt1 - temp);
1353  rt1++;
1354  rt2 += 4;
1355  }
1356  rt2 += xoff * 4;
1357  }
1358  memcpy(out, rt1, sizeof(*out) * yoff * 4 * width);
1359 }
1360 
1362  float facf0, float facf1, int x, int y, float *rect2i, float *rect1i, float *outi)
1363 {
1364  float temp, fac, fac1, fac2;
1365  float *rt1, *rt2, *out;
1366  int field = 1;
1367 
1368  const int width = x;
1369  const int height = y;
1370  const int xoff = min_ii(XOFF, width);
1371  const int yoff = min_ii(YOFF, height);
1372 
1373  fac1 = 70.0f * facf0;
1374  fac2 = 70.0f * facf1;
1375 
1376  rt2 = rect2i + yoff * 4 * width;
1377  rt1 = rect1i;
1378  out = outi;
1379  for (y = 0; y < height - yoff; y++) {
1380  if (field) {
1381  fac = fac1;
1382  }
1383  else {
1384  fac = fac2;
1385  }
1386  field = !field;
1387 
1388  memcpy(out, rt1, sizeof(*out) * xoff * 4);
1389  rt1 += xoff * 4;
1390  out += xoff * 4;
1391 
1392  for (x = xoff; x < width; x++) {
1393  temp = fac * rt2[3];
1394 
1395  *(out++) = MAX2(0.0f, *rt1 - temp);
1396  rt1++;
1397  *(out++) = MAX2(0.0f, *rt1 - temp);
1398  rt1++;
1399  *(out++) = MAX2(0.0f, *rt1 - temp);
1400  rt1++;
1401  *(out++) = MAX2(0.0f, *rt1 - temp);
1402  rt1++;
1403  rt2 += 4;
1404  }
1405  rt2 += xoff * 4;
1406  }
1407  memcpy(out, rt1, sizeof(*out) * yoff * 4 * width);
1408 }
1409 
1410 /*********************** Mul *************************/
1411 
1412 static void do_mul_effect_byte(float facf0,
1413  float facf1,
1414  int x,
1415  int y,
1416  unsigned char *rect1,
1417  unsigned char *rect2,
1418  unsigned char *out)
1419 {
1420  int xo, fac1, fac3;
1421  unsigned char *rt1, *rt2, *rt;
1422 
1423  xo = x;
1424  rt1 = rect1;
1425  rt2 = rect2;
1426  rt = out;
1427 
1428  fac1 = (int)(256.0f * facf0);
1429  fac3 = (int)(256.0f * facf1);
1430 
1431  /* formula:
1432  * fac * (a * b) + (1 - fac) * a => fac * a * (b - 1) + axaux = c * px + py * s; //+centx
1433  * yaux = -s * px + c * py; //+centy
1434  */
1435 
1436  while (y--) {
1437 
1438  x = xo;
1439  while (x--) {
1440 
1441  rt[0] = rt1[0] + ((fac1 * rt1[0] * (rt2[0] - 255)) >> 16);
1442  rt[1] = rt1[1] + ((fac1 * rt1[1] * (rt2[1] - 255)) >> 16);
1443  rt[2] = rt1[2] + ((fac1 * rt1[2] * (rt2[2] - 255)) >> 16);
1444  rt[3] = rt1[3] + ((fac1 * rt1[3] * (rt2[3] - 255)) >> 16);
1445 
1446  rt1 += 4;
1447  rt2 += 4;
1448  rt += 4;
1449  }
1450 
1451  if (y == 0) {
1452  break;
1453  }
1454  y--;
1455 
1456  x = xo;
1457  while (x--) {
1458 
1459  rt[0] = rt1[0] + ((fac3 * rt1[0] * (rt2[0] - 255)) >> 16);
1460  rt[1] = rt1[1] + ((fac3 * rt1[1] * (rt2[1] - 255)) >> 16);
1461  rt[2] = rt1[2] + ((fac3 * rt1[2] * (rt2[2] - 255)) >> 16);
1462  rt[3] = rt1[3] + ((fac3 * rt1[3] * (rt2[3] - 255)) >> 16);
1463 
1464  rt1 += 4;
1465  rt2 += 4;
1466  rt += 4;
1467  }
1468  }
1469 }
1470 
1472  float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out)
1473 {
1474  int xo;
1475  float fac1, fac3;
1476  float *rt1, *rt2, *rt;
1477 
1478  xo = x;
1479  rt1 = rect1;
1480  rt2 = rect2;
1481  rt = out;
1482 
1483  fac1 = facf0;
1484  fac3 = facf1;
1485 
1486  /* formula:
1487  * fac * (a * b) + (1 - fac) * a => fac * a * (b - 1) + a
1488  */
1489 
1490  while (y--) {
1491  x = xo;
1492  while (x--) {
1493  rt[0] = rt1[0] + fac1 * rt1[0] * (rt2[0] - 1.0f);
1494  rt[1] = rt1[1] + fac1 * rt1[1] * (rt2[1] - 1.0f);
1495  rt[2] = rt1[2] + fac1 * rt1[2] * (rt2[2] - 1.0f);
1496  rt[3] = rt1[3] + fac1 * rt1[3] * (rt2[3] - 1.0f);
1497 
1498  rt1 += 4;
1499  rt2 += 4;
1500  rt += 4;
1501  }
1502 
1503  if (y == 0) {
1504  break;
1505  }
1506  y--;
1507 
1508  x = xo;
1509  while (x--) {
1510  rt[0] = rt1[0] + fac3 * rt1[0] * (rt2[0] - 1.0f);
1511  rt[1] = rt1[1] + fac3 * rt1[1] * (rt2[1] - 1.0f);
1512  rt[2] = rt1[2] + fac3 * rt1[2] * (rt2[2] - 1.0f);
1513  rt[3] = rt1[3] + fac3 * rt1[3] * (rt2[3] - 1.0f);
1514 
1515  rt1 += 4;
1516  rt2 += 4;
1517  rt += 4;
1518  }
1519  }
1520 }
1521 
1523  Sequence *UNUSED(seq),
1524  float UNUSED(timeline_frame),
1525  float facf0,
1526  float facf1,
1527  ImBuf *ibuf1,
1528  ImBuf *ibuf2,
1529  ImBuf *UNUSED(ibuf3),
1530  int start_line,
1531  int total_lines,
1532  ImBuf *out)
1533 {
1534  if (out->rect_float) {
1535  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
1536 
1538  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1539 
1540  do_mul_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out);
1541  }
1542  else {
1543  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
1544 
1546  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1547 
1548  do_mul_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out);
1549  }
1550 }
1551 
1552 /*********************** Blend Mode ***************************************/
1553 typedef void (*IMB_blend_func_byte)(unsigned char *dst,
1554  const unsigned char *src1,
1555  const unsigned char *src2);
1556 typedef void (*IMB_blend_func_float)(float *dst, const float *src1, const float *src2);
1557 
1559  float facf1,
1560  int x,
1561  int y,
1562  unsigned char *rect1,
1563  unsigned char *rect2,
1564  unsigned char *out,
1565  IMB_blend_func_byte blend_function)
1566 {
1567  int xo;
1568  unsigned char *rt1, *rt2, *rt;
1569  unsigned int achannel;
1570  xo = x;
1571  rt1 = rect1;
1572  rt2 = rect2;
1573  rt = out;
1574  while (y--) {
1575  for (x = xo; x > 0; x--) {
1576  achannel = rt1[3];
1577  rt1[3] = (unsigned int)achannel * facf0;
1578  blend_function(rt, rt1, rt2);
1579  rt1[3] = achannel;
1580  rt[3] = rt1[3];
1581  rt1 += 4;
1582  rt2 += 4;
1583  rt += 4;
1584  }
1585  if (y == 0) {
1586  break;
1587  }
1588  y--;
1589  for (x = xo; x > 0; x--) {
1590  achannel = rt1[3];
1591  rt1[3] = (unsigned int)achannel * facf1;
1592  blend_function(rt, rt1, rt2);
1593  rt1[3] = achannel;
1594  rt[3] = rt1[3];
1595  rt1 += 4;
1596  rt2 += 4;
1597  rt += 4;
1598  }
1599  }
1600 }
1601 
1603  float facf1,
1604  int x,
1605  int y,
1606  float *rect1,
1607  float *rect2,
1608  float *out,
1609  IMB_blend_func_float blend_function)
1610 {
1611  int xo;
1612  float *rt1, *rt2, *rt;
1613  float achannel;
1614  xo = x;
1615  rt1 = rect1;
1616  rt2 = rect2;
1617  rt = out;
1618  while (y--) {
1619  for (x = xo; x > 0; x--) {
1620  achannel = rt1[3];
1621  rt1[3] = achannel * facf0;
1622  blend_function(rt, rt1, rt2);
1623  rt1[3] = achannel;
1624  rt[3] = rt1[3];
1625  rt1 += 4;
1626  rt2 += 4;
1627  rt += 4;
1628  }
1629  if (y == 0) {
1630  break;
1631  }
1632  y--;
1633  for (x = xo; x > 0; x--) {
1634  achannel = rt1[3];
1635  rt1[3] = achannel * facf1;
1636  blend_function(rt, rt1, rt2);
1637  rt1[3] = achannel;
1638  rt[3] = rt1[3];
1639  rt1 += 4;
1640  rt2 += 4;
1641  rt += 4;
1642  }
1643  }
1644 }
1645 
1647  float facf0, float facf1, int x, int y, float *rect1, float *rect2, int btype, float *out)
1648 {
1649  switch (btype) {
1650  case SEQ_TYPE_ADD:
1651  apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_add_float);
1652  break;
1653  case SEQ_TYPE_SUB:
1654  apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_sub_float);
1655  break;
1656  case SEQ_TYPE_MUL:
1657  apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_mul_float);
1658  break;
1659  case SEQ_TYPE_DARKEN:
1660  apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_darken_float);
1661  break;
1662  case SEQ_TYPE_COLOR_BURN:
1663  apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_burn_float);
1664  break;
1665  case SEQ_TYPE_LINEAR_BURN:
1667  facf0, facf1, x, y, rect1, rect2, out, blend_color_linearburn_float);
1668  break;
1669  case SEQ_TYPE_SCREEN:
1670  apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_screen_float);
1671  break;
1672  case SEQ_TYPE_LIGHTEN:
1673  apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_lighten_float);
1674  break;
1675  case SEQ_TYPE_DODGE:
1676  apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_dodge_float);
1677  break;
1678  case SEQ_TYPE_OVERLAY:
1679  apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_overlay_float);
1680  break;
1681  case SEQ_TYPE_SOFT_LIGHT:
1683  facf0, facf1, x, y, rect1, rect2, out, blend_color_softlight_float);
1684  break;
1685  case SEQ_TYPE_HARD_LIGHT:
1687  facf0, facf1, x, y, rect1, rect2, out, blend_color_hardlight_float);
1688  break;
1689  case SEQ_TYPE_PIN_LIGHT:
1691  facf0, facf1, x, y, rect1, rect2, out, blend_color_pinlight_float);
1692  break;
1693  case SEQ_TYPE_LIN_LIGHT:
1695  facf0, facf1, x, y, rect1, rect2, out, blend_color_linearlight_float);
1696  break;
1697  case SEQ_TYPE_VIVID_LIGHT:
1699  facf0, facf1, x, y, rect1, rect2, out, blend_color_vividlight_float);
1700  break;
1701  case SEQ_TYPE_BLEND_COLOR:
1702  apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_color_float);
1703  break;
1704  case SEQ_TYPE_HUE:
1705  apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_hue_float);
1706  break;
1707  case SEQ_TYPE_SATURATION:
1709  facf0, facf1, x, y, rect1, rect2, out, blend_color_saturation_float);
1710  break;
1711  case SEQ_TYPE_VALUE:
1713  facf0, facf1, x, y, rect1, rect2, out, blend_color_luminosity_float);
1714  break;
1715  case SEQ_TYPE_DIFFERENCE:
1717  facf0, facf1, x, y, rect1, rect2, out, blend_color_difference_float);
1718  break;
1719  case SEQ_TYPE_EXCLUSION:
1721  facf0, facf1, x, y, rect1, rect2, out, blend_color_exclusion_float);
1722  break;
1723  default:
1724  break;
1725  }
1726 }
1727 
1728 static void do_blend_effect_byte(float facf0,
1729  float facf1,
1730  int x,
1731  int y,
1732  unsigned char *rect1,
1733  unsigned char *rect2,
1734  int btype,
1735  unsigned char *out)
1736 {
1737  switch (btype) {
1738  case SEQ_TYPE_ADD:
1739  apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_add_byte);
1740  break;
1741  case SEQ_TYPE_SUB:
1742  apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_sub_byte);
1743  break;
1744  case SEQ_TYPE_MUL:
1745  apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_mul_byte);
1746  break;
1747  case SEQ_TYPE_DARKEN:
1748  apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_darken_byte);
1749  break;
1750  case SEQ_TYPE_COLOR_BURN:
1751  apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_burn_byte);
1752  break;
1753  case SEQ_TYPE_LINEAR_BURN:
1755  facf0, facf1, x, y, rect1, rect2, out, blend_color_linearburn_byte);
1756  break;
1757  case SEQ_TYPE_SCREEN:
1758  apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_screen_byte);
1759  break;
1760  case SEQ_TYPE_LIGHTEN:
1761  apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_lighten_byte);
1762  break;
1763  case SEQ_TYPE_DODGE:
1764  apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_dodge_byte);
1765  break;
1766  case SEQ_TYPE_OVERLAY:
1767  apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_overlay_byte);
1768  break;
1769  case SEQ_TYPE_SOFT_LIGHT:
1770  apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_softlight_byte);
1771  break;
1772  case SEQ_TYPE_HARD_LIGHT:
1773  apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_hardlight_byte);
1774  break;
1775  case SEQ_TYPE_PIN_LIGHT:
1776  apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_pinlight_byte);
1777  break;
1778  case SEQ_TYPE_LIN_LIGHT:
1780  facf0, facf1, x, y, rect1, rect2, out, blend_color_linearlight_byte);
1781  break;
1782  case SEQ_TYPE_VIVID_LIGHT:
1784  facf0, facf1, x, y, rect1, rect2, out, blend_color_vividlight_byte);
1785  break;
1786  case SEQ_TYPE_BLEND_COLOR:
1787  apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_color_byte);
1788  break;
1789  case SEQ_TYPE_HUE:
1790  apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_hue_byte);
1791  break;
1792  case SEQ_TYPE_SATURATION:
1794  facf0, facf1, x, y, rect1, rect2, out, blend_color_saturation_byte);
1795  break;
1796  case SEQ_TYPE_VALUE:
1798  facf0, facf1, x, y, rect1, rect2, out, blend_color_luminosity_byte);
1799  break;
1800  case SEQ_TYPE_DIFFERENCE:
1802  facf0, facf1, x, y, rect1, rect2, out, blend_color_difference_byte);
1803  break;
1804  case SEQ_TYPE_EXCLUSION:
1805  apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_exclusion_byte);
1806  break;
1807  default:
1808  break;
1809  }
1810 }
1811 
1813  Sequence *seq,
1814  float UNUSED(timeline_frame),
1815  float facf0,
1816  float facf1,
1817  ImBuf *ibuf1,
1818  ImBuf *ibuf2,
1819  ImBuf *UNUSED(ibuf3),
1820  int start_line,
1821  int total_lines,
1822  ImBuf *out)
1823 {
1824  if (out->rect_float) {
1825  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
1827  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1829  facf0, facf1, context->rectx, total_lines, rect1, rect2, seq->blend_mode, rect_out);
1830  }
1831  else {
1832  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
1834  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1836  facf0, facf1, context->rectx, total_lines, rect1, rect2, seq->blend_mode, rect_out);
1837  }
1838 }
1839 /*********************** Color Mix Effect *************************/
1841 {
1842  ColorMixVars *data;
1843 
1844  if (seq->effectdata) {
1845  MEM_freeN(seq->effectdata);
1846  }
1847  seq->effectdata = MEM_callocN(sizeof(ColorMixVars), "colormixvars");
1848  data = (ColorMixVars *)seq->effectdata;
1849  data->blend_effect = SEQ_TYPE_OVERLAY;
1850  data->factor = 1.0f;
1851 }
1852 
1854  Sequence *seq,
1855  float UNUSED(timeline_frame),
1856  float UNUSED(facf0),
1857  float UNUSED(facf1),
1858  ImBuf *ibuf1,
1859  ImBuf *ibuf2,
1860  ImBuf *UNUSED(ibuf3),
1861  int start_line,
1862  int total_lines,
1863  ImBuf *out)
1864 {
1865  float facf;
1866 
1867  ColorMixVars *data = seq->effectdata;
1868  facf = data->factor;
1869 
1870  if (out->rect_float) {
1871  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
1873  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1875  facf, facf, context->rectx, total_lines, rect1, rect2, data->blend_effect, rect_out);
1876  }
1877  else {
1878  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
1880  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1882  facf, facf, context->rectx, total_lines, rect1, rect2, data->blend_effect, rect_out);
1883  }
1884 }
1885 
1886 /*********************** Wipe *************************/
1887 
1888 typedef struct WipeZone {
1889  float angle;
1890  int flip;
1891  int xo, yo;
1892  int width;
1893  float pythangle;
1895 
1896 static void precalc_wipe_zone(WipeZone *wipezone, WipeVars *wipe, int xo, int yo)
1897 {
1898  wipezone->flip = (wipe->angle < 0.0f);
1899  wipezone->angle = tanf(fabsf(wipe->angle));
1900  wipezone->xo = xo;
1901  wipezone->yo = yo;
1902  wipezone->width = (int)(wipe->edgeWidth * ((xo + yo) / 2.0f));
1903  wipezone->pythangle = 1.0f / sqrtf(wipezone->angle * wipezone->angle + 1.0f);
1904 }
1905 
1906 /* This function calculates the blur band for the wipe effects */
1907 static float in_band(float width, float dist, int side, int dir)
1908 {
1909  float alpha;
1910 
1911  if (width == 0) {
1912  return (float)side;
1913  }
1914 
1915  if (width < dist) {
1916  return (float)side;
1917  }
1918 
1919  if (side == 1) {
1920  alpha = (dist + 0.5f * width) / (width);
1921  }
1922  else {
1923  alpha = (0.5f * width - dist) / (width);
1924  }
1925 
1926  if (dir == 0) {
1927  alpha = 1 - alpha;
1928  }
1929 
1930  return alpha;
1931 }
1932 
1933 static float check_zone(WipeZone *wipezone, int x, int y, Sequence *seq, float facf0)
1934 {
1935  float posx, posy, hyp, hyp2, angle, hwidth, b1, b2, b3, pointdist;
1936  /* some future stuff */
1937  /* float hyp3, hyp4, b4, b5 */
1938  float temp1, temp2, temp3, temp4; /* some placeholder variables */
1939  int xo = wipezone->xo;
1940  int yo = wipezone->yo;
1941  float halfx = xo * 0.5f;
1942  float halfy = yo * 0.5f;
1943  float widthf, output = 0;
1944  WipeVars *wipe = (WipeVars *)seq->effectdata;
1945  int width;
1946 
1947  if (wipezone->flip) {
1948  x = xo - x;
1949  }
1950  angle = wipezone->angle;
1951 
1952  if (wipe->forward) {
1953  posx = facf0 * xo;
1954  posy = facf0 * yo;
1955  }
1956  else {
1957  posx = xo - facf0 * xo;
1958  posy = yo - facf0 * yo;
1959  }
1960 
1961  switch (wipe->wipetype) {
1962  case DO_SINGLE_WIPE:
1963  width = min_ii(wipezone->width, facf0 * yo);
1964  width = min_ii(width, yo - facf0 * yo);
1965 
1966  if (angle == 0.0f) {
1967  b1 = posy;
1968  b2 = y;
1969  hyp = fabsf(y - posy);
1970  }
1971  else {
1972  b1 = posy - (-angle) * posx;
1973  b2 = y - (-angle) * x;
1974  hyp = fabsf(angle * x + y + (-posy - angle * posx)) * wipezone->pythangle;
1975  }
1976 
1977  if (angle < 0) {
1978  temp1 = b1;
1979  b1 = b2;
1980  b2 = temp1;
1981  }
1982 
1983  if (wipe->forward) {
1984  if (b1 < b2) {
1985  output = in_band(width, hyp, 1, 1);
1986  }
1987  else {
1988  output = in_band(width, hyp, 0, 1);
1989  }
1990  }
1991  else {
1992  if (b1 < b2) {
1993  output = in_band(width, hyp, 0, 1);
1994  }
1995  else {
1996  output = in_band(width, hyp, 1, 1);
1997  }
1998  }
1999  break;
2000 
2001  case DO_DOUBLE_WIPE:
2002  if (!wipe->forward) {
2003  facf0 = 1.0f - facf0; /* Go the other direction */
2004  }
2005 
2006  width = wipezone->width; /* calculate the blur width */
2007  hwidth = width * 0.5f;
2008  if (angle == 0) {
2009  b1 = posy * 0.5f;
2010  b3 = yo - posy * 0.5f;
2011  b2 = y;
2012 
2013  hyp = fabsf(y - posy * 0.5f);
2014  hyp2 = fabsf(y - (yo - posy * 0.5f));
2015  }
2016  else {
2017  b1 = posy * 0.5f - (-angle) * posx * 0.5f;
2018  b3 = (yo - posy * 0.5f) - (-angle) * (xo - posx * 0.5f);
2019  b2 = y - (-angle) * x;
2020 
2021  hyp = fabsf(angle * x + y + (-posy * 0.5f - angle * posx * 0.5f)) * wipezone->pythangle;
2022  hyp2 = fabsf(angle * x + y + (-(yo - posy * 0.5f) - angle * (xo - posx * 0.5f))) *
2023  wipezone->pythangle;
2024  }
2025 
2026  hwidth = min_ff(hwidth, fabsf(b3 - b1) / 2.0f);
2027 
2028  if (b2 < b1 && b2 < b3) {
2029  output = in_band(hwidth, hyp, 0, 1);
2030  }
2031  else if (b2 > b1 && b2 > b3) {
2032  output = in_band(hwidth, hyp2, 0, 1);
2033  }
2034  else {
2035  if (hyp < hwidth && hyp2 > hwidth) {
2036  output = in_band(hwidth, hyp, 1, 1);
2037  }
2038  else if (hyp > hwidth && hyp2 < hwidth) {
2039  output = in_band(hwidth, hyp2, 1, 1);
2040  }
2041  else {
2042  output = in_band(hwidth, hyp2, 1, 1) * in_band(hwidth, hyp, 1, 1);
2043  }
2044  }
2045  if (!wipe->forward) {
2046  output = 1 - output;
2047  }
2048  break;
2049  case DO_CLOCK_WIPE:
2050  /*
2051  * temp1: angle of effect center in rads
2052  * temp2: angle of line through (halfx, halfy) and (x, y) in rads
2053  * temp3: angle of low side of blur
2054  * temp4: angle of high side of blur
2055  */
2056  output = 1.0f - facf0;
2057  widthf = wipe->edgeWidth * 2.0f * (float)M_PI;
2058  temp1 = 2.0f * (float)M_PI * facf0;
2059 
2060  if (wipe->forward) {
2061  temp1 = 2.0f * (float)M_PI - temp1;
2062  }
2063 
2064  x = x - halfx;
2065  y = y - halfy;
2066 
2067  temp2 = asin(abs(y) / hypot(x, y));
2068  if (x <= 0 && y >= 0) {
2069  temp2 = (float)M_PI - temp2;
2070  }
2071  else if (x <= 0 && y <= 0) {
2072  temp2 += (float)M_PI;
2073  }
2074  else if (x >= 0 && y <= 0) {
2075  temp2 = 2.0f * (float)M_PI - temp2;
2076  }
2077 
2078  if (wipe->forward) {
2079  temp3 = temp1 - (widthf * 0.5f) * facf0;
2080  temp4 = temp1 + (widthf * 0.5f) * (1 - facf0);
2081  }
2082  else {
2083  temp3 = temp1 - (widthf * 0.5f) * (1 - facf0);
2084  temp4 = temp1 + (widthf * 0.5f) * facf0;
2085  }
2086  if (temp3 < 0) {
2087  temp3 = 0;
2088  }
2089  if (temp4 > 2.0f * (float)M_PI) {
2090  temp4 = 2.0f * (float)M_PI;
2091  }
2092 
2093  if (temp2 < temp3) {
2094  output = 0;
2095  }
2096  else if (temp2 > temp4) {
2097  output = 1;
2098  }
2099  else {
2100  output = (temp2 - temp3) / (temp4 - temp3);
2101  }
2102  if (x == 0 && y == 0) {
2103  output = 1;
2104  }
2105  if (output != output) {
2106  output = 1;
2107  }
2108  if (wipe->forward) {
2109  output = 1 - output;
2110  }
2111  break;
2112  case DO_IRIS_WIPE:
2113  if (xo > yo) {
2114  yo = xo;
2115  }
2116  else {
2117  xo = yo;
2118  }
2119 
2120  if (!wipe->forward) {
2121  facf0 = 1 - facf0;
2122  }
2123 
2124  width = wipezone->width;
2125  hwidth = width * 0.5f;
2126 
2127  temp1 = (halfx - (halfx)*facf0);
2128  pointdist = hypotf(temp1, temp1);
2129 
2130  temp2 = hypotf(halfx - x, halfy - y);
2131  if (temp2 > pointdist) {
2132  output = in_band(hwidth, fabsf(temp2 - pointdist), 0, 1);
2133  }
2134  else {
2135  output = in_band(hwidth, fabsf(temp2 - pointdist), 1, 1);
2136  }
2137 
2138  if (!wipe->forward) {
2139  output = 1 - output;
2140  }
2141 
2142  break;
2143  }
2144  if (output < 0) {
2145  output = 0;
2146  }
2147  else if (output > 1) {
2148  output = 1;
2149  }
2150  return output;
2151 }
2152 
2153 static void init_wipe_effect(Sequence *seq)
2154 {
2155  if (seq->effectdata) {
2156  MEM_freeN(seq->effectdata);
2157  }
2158 
2159  seq->effectdata = MEM_callocN(sizeof(WipeVars), "wipevars");
2160 }
2161 
2162 static int num_inputs_wipe(void)
2163 {
2164  return 2;
2165 }
2166 
2167 static void free_wipe_effect(Sequence *seq, const bool UNUSED(do_id_user))
2168 {
2169  if (seq->effectdata) {
2170  MEM_freeN(seq->effectdata);
2171  }
2172 
2173  seq->effectdata = NULL;
2174 }
2175 
2176 static void copy_wipe_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
2177 {
2178  dst->effectdata = MEM_dupallocN(src->effectdata);
2179 }
2180 
2182  float facf0,
2183  float UNUSED(facf1),
2184  int x,
2185  int y,
2186  unsigned char *rect1,
2187  unsigned char *rect2,
2188  unsigned char *out)
2189 {
2190  WipeZone wipezone;
2191  WipeVars *wipe = (WipeVars *)seq->effectdata;
2192  int xo, yo;
2193  unsigned char *cp1, *cp2, *rt;
2194 
2195  precalc_wipe_zone(&wipezone, wipe, x, y);
2196 
2197  cp1 = rect1;
2198  cp2 = rect2;
2199  rt = out;
2200 
2201  xo = x;
2202  yo = y;
2203  for (y = 0; y < yo; y++) {
2204  for (x = 0; x < xo; x++) {
2205  float check = check_zone(&wipezone, x, y, seq, facf0);
2206  if (check) {
2207  if (cp1) {
2208  float rt1[4], rt2[4], tempc[4];
2209 
2212 
2213  tempc[0] = rt1[0] * check + rt2[0] * (1 - check);
2214  tempc[1] = rt1[1] * check + rt2[1] * (1 - check);
2215  tempc[2] = rt1[2] * check + rt2[2] * (1 - check);
2216  tempc[3] = rt1[3] * check + rt2[3] * (1 - check);
2217 
2218  premul_float_to_straight_uchar(rt, tempc);
2219  }
2220  else {
2221  rt[0] = 0;
2222  rt[1] = 0;
2223  rt[2] = 0;
2224  rt[3] = 255;
2225  }
2226  }
2227  else {
2228  if (cp2) {
2229  rt[0] = cp2[0];
2230  rt[1] = cp2[1];
2231  rt[2] = cp2[2];
2232  rt[3] = cp2[3];
2233  }
2234  else {
2235  rt[0] = 0;
2236  rt[1] = 0;
2237  rt[2] = 0;
2238  rt[3] = 255;
2239  }
2240  }
2241 
2242  rt += 4;
2243  if (cp1 != NULL) {
2244  cp1 += 4;
2245  }
2246  if (cp2 != NULL) {
2247  cp2 += 4;
2248  }
2249  }
2250  }
2251 }
2252 
2254  float facf0,
2255  float UNUSED(facf1),
2256  int x,
2257  int y,
2258  float *rect1,
2259  float *rect2,
2260  float *out)
2261 {
2262  WipeZone wipezone;
2263  WipeVars *wipe = (WipeVars *)seq->effectdata;
2264  int xo, yo;
2265  float *rt1, *rt2, *rt;
2266 
2267  precalc_wipe_zone(&wipezone, wipe, x, y);
2268 
2269  rt1 = rect1;
2270  rt2 = rect2;
2271  rt = out;
2272 
2273  xo = x;
2274  yo = y;
2275  for (y = 0; y < yo; y++) {
2276  for (x = 0; x < xo; x++) {
2277  float check = check_zone(&wipezone, x, y, seq, facf0);
2278  if (check) {
2279  if (rt1) {
2280  rt[0] = rt1[0] * check + rt2[0] * (1 - check);
2281  rt[1] = rt1[1] * check + rt2[1] * (1 - check);
2282  rt[2] = rt1[2] * check + rt2[2] * (1 - check);
2283  rt[3] = rt1[3] * check + rt2[3] * (1 - check);
2284  }
2285  else {
2286  rt[0] = 0;
2287  rt[1] = 0;
2288  rt[2] = 0;
2289  rt[3] = 1.0;
2290  }
2291  }
2292  else {
2293  if (rt2) {
2294  rt[0] = rt2[0];
2295  rt[1] = rt2[1];
2296  rt[2] = rt2[2];
2297  rt[3] = rt2[3];
2298  }
2299  else {
2300  rt[0] = 0;
2301  rt[1] = 0;
2302  rt[2] = 0;
2303  rt[3] = 1.0;
2304  }
2305  }
2306 
2307  rt += 4;
2308  if (rt1 != NULL) {
2309  rt1 += 4;
2310  }
2311  if (rt2 != NULL) {
2312  rt2 += 4;
2313  }
2314  }
2315  }
2316 }
2317 
2319  Sequence *seq,
2320  float UNUSED(timeline_frame),
2321  float facf0,
2322  float facf1,
2323  ImBuf *ibuf1,
2324  ImBuf *ibuf2,
2325  ImBuf *ibuf3)
2326 {
2327  ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2328 
2329  if (out->rect_float) {
2331  facf0,
2332  facf1,
2333  context->rectx,
2334  context->recty,
2335  ibuf1->rect_float,
2336  ibuf2->rect_float,
2337  out->rect_float);
2338  }
2339  else {
2340  do_wipe_effect_byte(seq,
2341  facf0,
2342  facf1,
2343  context->rectx,
2344  context->recty,
2345  (unsigned char *)ibuf1->rect,
2346  (unsigned char *)ibuf2->rect,
2347  (unsigned char *)out->rect);
2348  }
2349 
2350  return out;
2351 }
2352 
2353 /*********************** Transform *************************/
2354 
2356 {
2358 
2359  if (seq->effectdata) {
2360  MEM_freeN(seq->effectdata);
2361  }
2362 
2363  seq->effectdata = MEM_callocN(sizeof(TransformVars), "transformvars");
2364 
2366 
2367  transform->ScalexIni = 1.0f;
2368  transform->ScaleyIni = 1.0f;
2369 
2370  transform->xIni = 0.0f;
2371  transform->yIni = 0.0f;
2372 
2373  transform->rotIni = 0.0f;
2374 
2375  transform->interpolation = 1;
2376  transform->percent = 1;
2377  transform->uniform_scale = 0;
2378 }
2379 
2380 static int num_inputs_transform(void)
2381 {
2382  return 1;
2383 }
2384 
2385 static void free_transform_effect(Sequence *seq, const bool UNUSED(do_id_user))
2386 {
2387  if (seq->effectdata) {
2388  MEM_freeN(seq->effectdata);
2389  }
2390  seq->effectdata = NULL;
2391 }
2392 
2393 static void copy_transform_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
2394 {
2395  dst->effectdata = MEM_dupallocN(src->effectdata);
2396 }
2397 
2398 static void transform_image(int x,
2399  int y,
2400  int start_line,
2401  int total_lines,
2402  ImBuf *ibuf1,
2403  ImBuf *out,
2404  float scale_x,
2405  float scale_y,
2406  float translate_x,
2407  float translate_y,
2408  float rotate,
2409  int interpolation)
2410 {
2411  /* Rotate */
2412  float s = sinf(rotate);
2413  float c = cosf(rotate);
2414 
2415  for (int yi = start_line; yi < start_line + total_lines; yi++) {
2416  for (int xi = 0; xi < x; xi++) {
2417  /* translate point */
2418  float xt = xi - translate_x;
2419  float yt = yi - translate_y;
2420 
2421  /* rotate point with center ref */
2422  float xr = c * xt + s * yt;
2423  float yr = -s * xt + c * yt;
2424 
2425  /* scale point with center ref */
2426  xt = xr / scale_x;
2427  yt = yr / scale_y;
2428 
2429  /* undo reference center point */
2430  xt += (x / 2.0f);
2431  yt += (y / 2.0f);
2432 
2433  /* interpolate */
2434  switch (interpolation) {
2435  case 0:
2436  nearest_interpolation(ibuf1, out, xt, yt, xi, yi);
2437  break;
2438  case 1:
2439  bilinear_interpolation(ibuf1, out, xt, yt, xi, yi);
2440  break;
2441  case 2:
2442  bicubic_interpolation(ibuf1, out, xt, yt, xi, yi);
2443  break;
2444  }
2445  }
2446  }
2447 }
2448 
2450  Sequence *seq,
2451  float UNUSED(timeline_frame),
2452  float UNUSED(facf0),
2453  float UNUSED(facf1),
2454  ImBuf *ibuf1,
2455  ImBuf *UNUSED(ibuf2),
2456  ImBuf *UNUSED(ibuf3),
2457  int start_line,
2458  int total_lines,
2459  ImBuf *out)
2460 {
2461  Scene *scene = context->scene;
2463  float scale_x, scale_y, translate_x, translate_y, rotate_radians;
2464 
2465  /* Scale */
2466  if (transform->uniform_scale) {
2467  scale_x = scale_y = transform->ScalexIni;
2468  }
2469  else {
2470  scale_x = transform->ScalexIni;
2471  scale_y = transform->ScaleyIni;
2472  }
2473 
2474  int x = context->rectx;
2475  int y = context->recty;
2476 
2477  /* Translate */
2478  if (!transform->percent) {
2479  float rd_s = (scene->r.size / 100.0f);
2480 
2481  translate_x = transform->xIni * rd_s + (x / 2.0f);
2482  translate_y = transform->yIni * rd_s + (y / 2.0f);
2483  }
2484  else {
2485  translate_x = x * (transform->xIni / 100.0f) + (x / 2.0f);
2486  translate_y = y * (transform->yIni / 100.0f) + (y / 2.0f);
2487  }
2488 
2489  /* Rotate */
2490  rotate_radians = DEG2RADF(transform->rotIni);
2491 
2493  y,
2494  start_line,
2495  total_lines,
2496  ibuf1,
2497  out,
2498  scale_x,
2499  scale_y,
2500  translate_x,
2501  translate_y,
2502  rotate_radians,
2503  transform->interpolation);
2504 }
2505 
2506 /*********************** Glow *************************/
2507 
2508 static void RVBlurBitmap2_float(float *map, int width, int height, float blur, int quality)
2509 {
2510  /* Much better than the previous blur!
2511  * We do the blurring in two passes which is a whole lot faster.
2512  * I changed the math around to implement an actual Gaussian distribution.
2513  *
2514  * Watch out though, it tends to misbehave with large blur values on
2515  * a small bitmap. Avoid avoid! */
2516 
2517  float *temp = NULL, *swap;
2518  float *filter = NULL;
2519  int x, y, i, fx, fy;
2520  int index, ix, halfWidth;
2521  float fval, k, curColor[4], curColor2[4], weight = 0;
2522 
2523  /* If we're not really blurring, bail out */
2524  if (blur <= 0) {
2525  return;
2526  }
2527 
2528  /* Allocate memory for the tempmap and the blur filter matrix */
2529  temp = MEM_mallocN(sizeof(float[4]) * width * height, "blurbitmaptemp");
2530  if (!temp) {
2531  return;
2532  }
2533 
2534  /* Allocate memory for the filter elements */
2535  halfWidth = ((quality + 1) * blur);
2536  filter = (float *)MEM_mallocN(sizeof(float) * halfWidth * 2, "blurbitmapfilter");
2537  if (!filter) {
2538  MEM_freeN(temp);
2539  return;
2540  }
2541 
2542  /* Apparently we're calculating a bell curve based on the standard deviation (or radius)
2543  * This code is based on an example posted to comp.graphics.algorithms by
2544  * Blancmange <bmange@airdmhor.gen.nz>
2545  */
2546 
2547  k = -1.0f / (2.0f * (float)M_PI * blur * blur);
2548 
2549  for (ix = 0; ix < halfWidth; ix++) {
2550  weight = (float)exp(k * (ix * ix));
2551  filter[halfWidth - ix] = weight;
2552  filter[halfWidth + ix] = weight;
2553  }
2554  filter[0] = weight;
2555 
2556  /* Normalize the array */
2557  fval = 0;
2558  for (ix = 0; ix < halfWidth * 2; ix++) {
2559  fval += filter[ix];
2560  }
2561 
2562  for (ix = 0; ix < halfWidth * 2; ix++) {
2563  filter[ix] /= fval;
2564  }
2565 
2566  /* Blur the rows */
2567  for (y = 0; y < height; y++) {
2568  /* Do the left & right strips */
2569  for (x = 0; x < halfWidth; x++) {
2570  fx = 0;
2571  zero_v4(curColor);
2572  zero_v4(curColor2);
2573 
2574  for (i = x - halfWidth; i < x + halfWidth; i++) {
2575  if ((i >= 0) && (i < width)) {
2576  index = (i + y * width) * 4;
2577  madd_v4_v4fl(curColor, map + index, filter[fx]);
2578 
2579  index = (width - 1 - i + y * width) * 4;
2580  madd_v4_v4fl(curColor2, map + index, filter[fx]);
2581  }
2582  fx++;
2583  }
2584  index = (x + y * width) * 4;
2585  copy_v4_v4(temp + index, curColor);
2586 
2587  index = (width - 1 - x + y * width) * 4;
2588  copy_v4_v4(temp + index, curColor2);
2589  }
2590 
2591  /* Do the main body */
2592  for (x = halfWidth; x < width - halfWidth; x++) {
2593  fx = 0;
2594  zero_v4(curColor);
2595  for (i = x - halfWidth; i < x + halfWidth; i++) {
2596  index = (i + y * width) * 4;
2597  madd_v4_v4fl(curColor, map + index, filter[fx]);
2598  fx++;
2599  }
2600  index = (x + y * width) * 4;
2601  copy_v4_v4(temp + index, curColor);
2602  }
2603  }
2604 
2605  /* Swap buffers */
2606  swap = temp;
2607  temp = map;
2608  map = swap;
2609 
2610  /* Blur the columns */
2611  for (x = 0; x < width; x++) {
2612  /* Do the top & bottom strips */
2613  for (y = 0; y < halfWidth; y++) {
2614  fy = 0;
2615  zero_v4(curColor);
2616  zero_v4(curColor2);
2617  for (i = y - halfWidth; i < y + halfWidth; i++) {
2618  if ((i >= 0) && (i < height)) {
2619  /* Bottom */
2620  index = (x + i * width) * 4;
2621  madd_v4_v4fl(curColor, map + index, filter[fy]);
2622 
2623  /* Top */
2624  index = (x + (height - 1 - i) * width) * 4;
2625  madd_v4_v4fl(curColor2, map + index, filter[fy]);
2626  }
2627  fy++;
2628  }
2629  index = (x + y * width) * 4;
2630  copy_v4_v4(temp + index, curColor);
2631 
2632  index = (x + (height - 1 - y) * width) * 4;
2633  copy_v4_v4(temp + index, curColor2);
2634  }
2635 
2636  /* Do the main body */
2637  for (y = halfWidth; y < height - halfWidth; y++) {
2638  fy = 0;
2639  zero_v4(curColor);
2640  for (i = y - halfWidth; i < y + halfWidth; i++) {
2641  index = (x + i * width) * 4;
2642  madd_v4_v4fl(curColor, map + index, filter[fy]);
2643  fy++;
2644  }
2645  index = (x + y * width) * 4;
2646  copy_v4_v4(temp + index, curColor);
2647  }
2648  }
2649 
2650  /* Swap buffers */
2651  swap = temp;
2652  temp = map; /* map = swap; */ /* UNUSED */
2653 
2654  /* Tidy up */
2655  MEM_freeN(filter);
2656  MEM_freeN(temp);
2657 }
2658 
2659 static void RVAddBitmaps_float(float *a, float *b, float *c, int width, int height)
2660 {
2661  int x, y, index;
2662 
2663  for (y = 0; y < height; y++) {
2664  for (x = 0; x < width; x++) {
2665  index = (x + y * width) * 4;
2666  c[index + GlowR] = min_ff(1.0f, a[index + GlowR] + b[index + GlowR]);
2667  c[index + GlowG] = min_ff(1.0f, a[index + GlowG] + b[index + GlowG]);
2668  c[index + GlowB] = min_ff(1.0f, a[index + GlowB] + b[index + GlowB]);
2669  c[index + GlowA] = min_ff(1.0f, a[index + GlowA] + b[index + GlowA]);
2670  }
2671  }
2672 }
2673 
2675  const float *in, float *out, int width, int height, float threshold, float boost, float clamp)
2676 {
2677  int x, y, index;
2678  float intensity;
2679 
2680  for (y = 0; y < height; y++) {
2681  for (x = 0; x < width; x++) {
2682  index = (x + y * width) * 4;
2683 
2684  /* Isolate the intensity */
2685  intensity = (in[index + GlowR] + in[index + GlowG] + in[index + GlowB] - threshold);
2686  if (intensity > 0) {
2687  out[index + GlowR] = min_ff(clamp, (in[index + GlowR] * boost * intensity));
2688  out[index + GlowG] = min_ff(clamp, (in[index + GlowG] * boost * intensity));
2689  out[index + GlowB] = min_ff(clamp, (in[index + GlowB] * boost * intensity));
2690  out[index + GlowA] = min_ff(clamp, (in[index + GlowA] * boost * intensity));
2691  }
2692  else {
2693  out[index + GlowR] = 0;
2694  out[index + GlowG] = 0;
2695  out[index + GlowB] = 0;
2696  out[index + GlowA] = 0;
2697  }
2698  }
2699  }
2700 }
2701 
2702 static void init_glow_effect(Sequence *seq)
2703 {
2704  GlowVars *glow;
2705 
2706  if (seq->effectdata) {
2707  MEM_freeN(seq->effectdata);
2708  }
2709 
2710  seq->effectdata = MEM_callocN(sizeof(GlowVars), "glowvars");
2711 
2712  glow = (GlowVars *)seq->effectdata;
2713  glow->fMini = 0.25;
2714  glow->fClamp = 1.0;
2715  glow->fBoost = 0.5;
2716  glow->dDist = 3.0;
2717  glow->dQuality = 3;
2718  glow->bNoComp = 0;
2719 }
2720 
2721 static int num_inputs_glow(void)
2722 {
2723  return 1;
2724 }
2725 
2726 static void free_glow_effect(Sequence *seq, const bool UNUSED(do_id_user))
2727 {
2728  if (seq->effectdata) {
2729  MEM_freeN(seq->effectdata);
2730  }
2731 
2732  seq->effectdata = NULL;
2733 }
2734 
2735 static void copy_glow_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
2736 {
2737  dst->effectdata = MEM_dupallocN(src->effectdata);
2738 }
2739 
2741  int render_size,
2742  float facf0,
2743  float UNUSED(facf1),
2744  int x,
2745  int y,
2746  unsigned char *rect1,
2747  unsigned char *UNUSED(rect2),
2748  unsigned char *out)
2749 {
2750  float *outbuf, *inbuf;
2751  GlowVars *glow = (GlowVars *)seq->effectdata;
2752 
2753  inbuf = MEM_mallocN(sizeof(float[4]) * x * y, "glow effect input");
2754  outbuf = MEM_mallocN(sizeof(float[4]) * x * y, "glow effect output");
2755 
2756  IMB_buffer_float_from_byte(inbuf, rect1, IB_PROFILE_SRGB, IB_PROFILE_SRGB, false, x, y, x, x);
2757  IMB_buffer_float_premultiply(inbuf, x, y);
2758 
2760  inbuf, outbuf, x, y, glow->fMini * 3.0f, glow->fBoost * facf0, glow->fClamp);
2761  RVBlurBitmap2_float(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality);
2762  if (!glow->bNoComp) {
2763  RVAddBitmaps_float(inbuf, outbuf, outbuf, x, y);
2764  }
2765 
2768  out, outbuf, 4, 0.0f, IB_PROFILE_SRGB, IB_PROFILE_SRGB, false, x, y, x, x);
2769 
2770  MEM_freeN(inbuf);
2771  MEM_freeN(outbuf);
2772 }
2773 
2775  int render_size,
2776  float facf0,
2777  float UNUSED(facf1),
2778  int x,
2779  int y,
2780  float *rect1,
2781  float *UNUSED(rect2),
2782  float *out)
2783 {
2784  float *outbuf = out;
2785  float *inbuf = rect1;
2786  GlowVars *glow = (GlowVars *)seq->effectdata;
2787 
2789  inbuf, outbuf, x, y, glow->fMini * 3.0f, glow->fBoost * facf0, glow->fClamp);
2790  RVBlurBitmap2_float(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality);
2791  if (!glow->bNoComp) {
2792  RVAddBitmaps_float(inbuf, outbuf, outbuf, x, y);
2793  }
2794 }
2795 
2797  Sequence *seq,
2798  float UNUSED(timeline_frame),
2799  float facf0,
2800  float facf1,
2801  ImBuf *ibuf1,
2802  ImBuf *ibuf2,
2803  ImBuf *ibuf3)
2804 {
2805  ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2806 
2807  int render_size = 100 * context->rectx / context->scene->r.xsch;
2808 
2809  if (out->rect_float) {
2811  render_size,
2812  facf0,
2813  facf1,
2814  context->rectx,
2815  context->recty,
2816  ibuf1->rect_float,
2817  NULL,
2818  out->rect_float);
2819  }
2820  else {
2821  do_glow_effect_byte(seq,
2822  render_size,
2823  facf0,
2824  facf1,
2825  context->rectx,
2826  context->recty,
2827  (unsigned char *)ibuf1->rect,
2828  NULL,
2829  (unsigned char *)out->rect);
2830  }
2831 
2832  return out;
2833 }
2834 
2835 /*********************** Solid color *************************/
2836 
2837 static void init_solid_color(Sequence *seq)
2838 {
2839  SolidColorVars *cv;
2840 
2841  if (seq->effectdata) {
2842  MEM_freeN(seq->effectdata);
2843  }
2844 
2845  seq->effectdata = MEM_callocN(sizeof(SolidColorVars), "solidcolor");
2846 
2847  cv = (SolidColorVars *)seq->effectdata;
2848  cv->col[0] = cv->col[1] = cv->col[2] = 0.5;
2849 }
2850 
2851 static int num_inputs_color(void)
2852 {
2853  return 0;
2854 }
2855 
2856 static void free_solid_color(Sequence *seq, const bool UNUSED(do_id_user))
2857 {
2858  if (seq->effectdata) {
2859  MEM_freeN(seq->effectdata);
2860  }
2861 
2862  seq->effectdata = NULL;
2863 }
2864 
2865 static void copy_solid_color(Sequence *dst, Sequence *src, const int UNUSED(flag))
2866 {
2867  dst->effectdata = MEM_dupallocN(src->effectdata);
2868 }
2869 
2870 static int early_out_color(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
2871 {
2872  return EARLY_NO_INPUT;
2873 }
2874 
2876  Sequence *seq,
2877  float UNUSED(timeline_frame),
2878  float facf0,
2879  float facf1,
2880  ImBuf *ibuf1,
2881  ImBuf *ibuf2,
2882  ImBuf *ibuf3)
2883 {
2884  ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2885 
2887 
2888  unsigned char *rect;
2889  float *rect_float;
2890  int x; /*= context->rectx;*/ /*UNUSED*/
2891  int y; /*= context->recty;*/ /*UNUSED*/
2892 
2893  if (out->rect) {
2894  unsigned char col0[3];
2895  unsigned char col1[3];
2896 
2897  col0[0] = facf0 * cv->col[0] * 255;
2898  col0[1] = facf0 * cv->col[1] * 255;
2899  col0[2] = facf0 * cv->col[2] * 255;
2900 
2901  col1[0] = facf1 * cv->col[0] * 255;
2902  col1[1] = facf1 * cv->col[1] * 255;
2903  col1[2] = facf1 * cv->col[2] * 255;
2904 
2905  rect = (unsigned char *)out->rect;
2906 
2907  for (y = 0; y < out->y; y++) {
2908  for (x = 0; x < out->x; x++, rect += 4) {
2909  rect[0] = col0[0];
2910  rect[1] = col0[1];
2911  rect[2] = col0[2];
2912  rect[3] = 255;
2913  }
2914  y++;
2915  if (y < out->y) {
2916  for (x = 0; x < out->x; x++, rect += 4) {
2917  rect[0] = col1[0];
2918  rect[1] = col1[1];
2919  rect[2] = col1[2];
2920  rect[3] = 255;
2921  }
2922  }
2923  }
2924  }
2925  else if (out->rect_float) {
2926  float col0[3];
2927  float col1[3];
2928 
2929  col0[0] = facf0 * cv->col[0];
2930  col0[1] = facf0 * cv->col[1];
2931  col0[2] = facf0 * cv->col[2];
2932 
2933  col1[0] = facf1 * cv->col[0];
2934  col1[1] = facf1 * cv->col[1];
2935  col1[2] = facf1 * cv->col[2];
2936 
2937  rect_float = out->rect_float;
2938 
2939  for (y = 0; y < out->y; y++) {
2940  for (x = 0; x < out->x; x++, rect_float += 4) {
2941  rect_float[0] = col0[0];
2942  rect_float[1] = col0[1];
2943  rect_float[2] = col0[2];
2944  rect_float[3] = 1.0;
2945  }
2946  y++;
2947  if (y < out->y) {
2948  for (x = 0; x < out->x; x++, rect_float += 4) {
2949  rect_float[0] = col1[0];
2950  rect_float[1] = col1[1];
2951  rect_float[2] = col1[2];
2952  rect_float[3] = 1.0;
2953  }
2954  }
2955  }
2956  }
2957  return out;
2958 }
2959 
2960 /*********************** Mulitcam *************************/
2961 
2962 /* no effect inputs for multicam, we use give_ibuf_seq */
2963 static int num_inputs_multicam(void)
2964 {
2965  return 0;
2966 }
2967 
2968 static int early_out_multicam(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
2969 {
2970  return EARLY_NO_INPUT;
2971 }
2972 
2974  Sequence *seq,
2975  float timeline_frame,
2976  float UNUSED(facf0),
2977  float UNUSED(facf1),
2978  ImBuf *UNUSED(ibuf1),
2979  ImBuf *UNUSED(ibuf2),
2980  ImBuf *UNUSED(ibuf3))
2981 {
2982  ImBuf *out;
2983  Editing *ed;
2984  ListBase *seqbasep;
2985 
2986  if (seq->multicam_source == 0 || seq->multicam_source >= seq->machine) {
2987  return NULL;
2988  }
2989 
2990  ed = context->scene->ed;
2991  if (!ed) {
2992  return NULL;
2993  }
2994  seqbasep = SEQ_get_seqbase_by_seq(&ed->seqbase, seq);
2995  if (!seqbasep) {
2996  return NULL;
2997  }
2998 
2999  out = seq_render_give_ibuf_seqbase(context, timeline_frame, seq->multicam_source, seqbasep);
3000 
3001  return out;
3002 }
3003 
3004 /*********************** Adjustment *************************/
3005 
3006 /* no effect inputs for adjustment, we use give_ibuf_seq */
3007 static int num_inputs_adjustment(void)
3008 {
3009  return 0;
3010 }
3011 
3012 static int early_out_adjustment(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
3013 {
3014  return EARLY_NO_INPUT;
3015 }
3016 
3017 static ImBuf *do_adjustment_impl(const SeqRenderData *context, Sequence *seq, float timeline_frame)
3018 {
3019  Editing *ed;
3020  ListBase *seqbasep;
3021  ImBuf *i = NULL;
3022 
3023  ed = context->scene->ed;
3024 
3025  seqbasep = SEQ_get_seqbase_by_seq(&ed->seqbase, seq);
3026 
3027  /* Clamp timeline_frame to strip range so it behaves as if it had "still frame" offset (last
3028  * frame is static after end of strip). This is how most strips behave. This way transition
3029  * effects that doesn't overlap or speed effect can't fail rendering outside of strip range. */
3030  timeline_frame = clamp_i(timeline_frame, seq->startdisp, seq->enddisp - 1);
3031 
3032  if (seq->machine > 1) {
3033  i = seq_render_give_ibuf_seqbase(context, timeline_frame, seq->machine - 1, seqbasep);
3034  }
3035 
3036  /* found nothing? so let's work the way up the metastrip stack, so
3037  * that it is possible to group a bunch of adjustment strips into
3038  * a metastrip and have that work on everything below the metastrip
3039  */
3040 
3041  if (!i) {
3042  Sequence *meta;
3043 
3044  meta = seq_find_metastrip_by_sequence(&ed->seqbase, NULL, seq);
3045 
3046  if (meta) {
3047  i = do_adjustment_impl(context, meta, timeline_frame);
3048  }
3049  }
3050 
3051  return i;
3052 }
3053 
3055  Sequence *seq,
3056  float timeline_frame,
3057  float UNUSED(facf0),
3058  float UNUSED(facf1),
3059  ImBuf *UNUSED(ibuf1),
3060  ImBuf *UNUSED(ibuf2),
3061  ImBuf *UNUSED(ibuf3))
3062 {
3063  ImBuf *out;
3064  Editing *ed;
3065 
3066  ed = context->scene->ed;
3067 
3068  if (!ed) {
3069  return NULL;
3070  }
3071 
3072  out = do_adjustment_impl(context, seq, timeline_frame);
3073 
3074  return out;
3075 }
3076 
3077 /*********************** Speed *************************/
3078 
3079 static void init_speed_effect(Sequence *seq)
3080 {
3082 
3083  if (seq->effectdata) {
3084  MEM_freeN(seq->effectdata);
3085  }
3086 
3087  seq->effectdata = MEM_callocN(sizeof(SpeedControlVars), "speedcontrolvars");
3088 
3089  v = (SpeedControlVars *)seq->effectdata;
3090  v->globalSpeed = 1.0;
3091  v->frameMap = NULL;
3092  v->flags |= SEQ_SPEED_INTEGRATE; /* should be default behavior */
3093  v->length = 0;
3094 }
3095 
3096 static void load_speed_effect(Sequence *seq)
3097 {
3099 
3100  v->frameMap = NULL;
3101  v->length = 0;
3102 }
3103 
3104 static int num_inputs_speed(void)
3105 {
3106  return 1;
3107 }
3108 
3109 static void free_speed_effect(Sequence *seq, const bool UNUSED(do_id_user))
3110 {
3112  if (v->frameMap) {
3113  MEM_freeN(v->frameMap);
3114  }
3115  if (seq->effectdata) {
3116  MEM_freeN(seq->effectdata);
3117  }
3118  seq->effectdata = NULL;
3119 }
3120 
3121 static void copy_speed_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
3122 {
3124  dst->effectdata = MEM_dupallocN(src->effectdata);
3125  v = (SpeedControlVars *)dst->effectdata;
3126  v->frameMap = NULL;
3127  v->length = 0;
3128 }
3129 
3130 static int early_out_speed(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
3131 {
3132  return EARLY_DO_EFFECT;
3133 }
3134 
3135 static void store_icu_yrange_speed(Sequence *seq, short UNUSED(adrcode), float *ymin, float *ymax)
3136 {
3138 
3139  /* if not already done, load / initialize data */
3140  SEQ_effect_handle_get(seq);
3141 
3142  if ((v->flags & SEQ_SPEED_INTEGRATE) != 0) {
3143  *ymin = -100.0;
3144  *ymax = 100.0;
3145  }
3146  else {
3147  if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
3148  *ymin = 0.0;
3149  *ymax = 1.0;
3150  }
3151  else {
3152  *ymin = 0.0;
3153  *ymax = seq->len;
3154  }
3155  }
3156 }
3157 
3164 {
3165  if ((seq->type & SEQ_TYPE_EFFECT) != 0 && SEQ_effect_get_num_inputs(seq->type) == 0) {
3166  return seq->enddisp - seq->startdisp;
3167  }
3168 
3169  return seq->len;
3170 }
3171 
3173 {
3174  int timeline_frame;
3175  float fallback_fac = 1.0f;
3177  FCurve *fcu = NULL;
3178  int flags = v->flags;
3179 
3180  /* if not already done, load / initialize data */
3181  SEQ_effect_handle_get(seq);
3182 
3183  if ((force == false) && (seq->len == v->length) && (v->frameMap != NULL)) {
3184  return;
3185  }
3186  if ((seq->seq1 == NULL) || (seq->len < 1)) {
3187  /* make coverity happy and check for (CID 598) input strip ... */
3188  return;
3189  }
3190 
3191  /* XXX - new in 2.5x. should we use the animation system this way?
3192  * The fcurve is needed because many frames need evaluating at once - campbell */
3193  fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0, NULL);
3194  if (!v->frameMap || v->length != seq->len) {
3195  if (v->frameMap) {
3196  MEM_freeN(v->frameMap);
3197  }
3198 
3199  v->length = seq->len;
3200 
3201  v->frameMap = MEM_callocN(sizeof(float) * v->length, "speedcontrol frameMap");
3202  }
3203 
3204  fallback_fac = 1.0;
3205 
3206  const int target_strip_length = seq_effect_speed_get_strip_content_length(seq->seq1);
3207 
3208  if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) {
3209  if ((seq->seq1->enddisp != seq->seq1->start) && (target_strip_length != 0)) {
3210  fallback_fac = (float)target_strip_length / (float)(seq->seq1->enddisp - seq->seq1->start);
3211  flags = SEQ_SPEED_INTEGRATE;
3212  fcu = NULL;
3213  }
3214  }
3215  else {
3216  /* if there is no fcurve, use value as simple multiplier */
3217  if (!fcu) {
3218  fallback_fac = seq->speed_fader; /* same as speed_factor in rna*/
3219  }
3220  }
3221 
3222  if (flags & SEQ_SPEED_INTEGRATE) {
3223  float cursor = 0;
3224  float facf;
3225 
3226  v->frameMap[0] = 0;
3227  v->lastValidFrame = 0;
3228 
3229  for (timeline_frame = 1; timeline_frame < v->length; timeline_frame++) {
3230  if (fcu) {
3231  facf = evaluate_fcurve(fcu, seq->startdisp + timeline_frame);
3232  }
3233  else {
3234  facf = fallback_fac;
3235  }
3236  facf *= v->globalSpeed;
3237 
3238  cursor += facf;
3239 
3240  if (cursor >= target_strip_length) {
3241  v->frameMap[timeline_frame] = target_strip_length - 1;
3242  }
3243  else {
3244  v->frameMap[timeline_frame] = cursor;
3245  v->lastValidFrame = timeline_frame;
3246  }
3247  }
3248  }
3249  else {
3250  float facf;
3251 
3252  v->lastValidFrame = 0;
3253  for (timeline_frame = 0; timeline_frame < v->length; timeline_frame++) {
3254 
3255  if (fcu) {
3256  facf = evaluate_fcurve(fcu, seq->startdisp + timeline_frame);
3257  }
3258  else {
3259  facf = fallback_fac;
3260  }
3261 
3262  if (flags & SEQ_SPEED_COMPRESS_IPO_Y) {
3263  facf *= target_strip_length;
3264  }
3265  facf *= v->globalSpeed;
3266 
3267  if (facf >= target_strip_length) {
3268  facf = target_strip_length - 1;
3269  }
3270  else {
3271  v->lastValidFrame = timeline_frame;
3272  }
3273  v->frameMap[timeline_frame] = facf;
3274  }
3275  }
3276 }
3277 
3278 /* Override timeline_frame when rendering speed effect input. */
3280  Sequence *seq,
3281  float timeline_frame,
3282  int input)
3283 {
3284  int frame_index = seq_give_frame_index(seq, timeline_frame);
3286  seq_effect_speed_rebuild_map(context->scene, seq, false);
3287 
3288  /* No interpolation. */
3289  if ((s->flags & SEQ_SPEED_USE_INTERPOLATION) == 0) {
3290  return seq->start + s->frameMap[frame_index];
3291  }
3292 
3293  /* We need to provide current and next image for interpolation. */
3294  if (input == 0) { /* Current frame. */
3295  return floor(seq->start + s->frameMap[frame_index]);
3296  }
3297  /* Next frame. */
3298  return ceil(seq->start + s->frameMap[frame_index]);
3299 }
3300 
3302  Sequence *seq,
3303  float timeline_frame)
3304 {
3305  int frame_index = seq_give_frame_index(seq, timeline_frame);
3306  return s->frameMap[frame_index] - floor(s->frameMap[frame_index]);
3307 }
3308 
3310  Sequence *seq,
3311  float timeline_frame,
3312  float facf0,
3313  float facf1,
3314  ImBuf *ibuf1,
3315  ImBuf *ibuf2,
3316  ImBuf *ibuf3)
3317 {
3320  ImBuf *out;
3321 
3323  out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
3324  facf0 = facf1 = speed_effect_interpolation_ratio_get(s, seq, timeline_frame);
3325  /* Current frame is ibuf1, next frame is ibuf2. */
3327  &cross_effect, context, NULL, timeline_frame, facf0, facf1, ibuf1, ibuf2, ibuf3);
3328  return out;
3329  }
3330 
3331  /* No interpolation. */
3332  return IMB_dupImBuf(ibuf1);
3333 }
3334 
3335 /*********************** overdrop *************************/
3336 
3338  Sequence *UNUSED(seq),
3339  float UNUSED(timeline_frame),
3340  float facf0,
3341  float facf1,
3342  ImBuf *ibuf1,
3343  ImBuf *ibuf2,
3344  ImBuf *UNUSED(ibuf3),
3345  int start_line,
3346  int total_lines,
3347  ImBuf *out)
3348 {
3349  int x = context->rectx;
3350  int y = total_lines;
3351 
3352  if (out->rect_float) {
3353  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
3354 
3356  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
3357 
3358  do_drop_effect_float(facf0, facf1, x, y, rect1, rect2, rect_out);
3359  do_alphaover_effect_float(facf0, facf1, x, y, rect1, rect2, rect_out);
3360  }
3361  else {
3362  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
3363 
3365  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
3366 
3367  do_drop_effect_byte(facf0, facf1, x, y, rect1, rect2, rect_out);
3368  do_alphaover_effect_byte(facf0, facf1, x, y, rect1, rect2, rect_out);
3369  }
3370 }
3371 
3372 /*********************** Gaussian Blur *************************/
3373 
3374 /* NOTE: This gaussian blur implementation accumulates values in the square
3375  * kernel rather that doing X direction and then Y direction because of the
3376  * lack of using multiple-staged filters.
3377  *
3378  * Once we can we'll implement a way to apply filter as multiple stages we
3379  * can optimize hell of a lot in here.
3380  */
3381 
3383 {
3384  if (seq->effectdata) {
3385  MEM_freeN(seq->effectdata);
3386  }
3387 
3388  seq->effectdata = MEM_callocN(sizeof(WipeVars), "wipevars");
3389 }
3390 
3392 {
3393  return 1;
3394 }
3395 
3396 static void free_gaussian_blur_effect(Sequence *seq, const bool UNUSED(do_id_user))
3397 {
3398  if (seq->effectdata) {
3399  MEM_freeN(seq->effectdata);
3400  }
3401 
3402  seq->effectdata = NULL;
3403 }
3404 
3405 static void copy_gaussian_blur_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
3406 {
3407  dst->effectdata = MEM_dupallocN(src->effectdata);
3408 }
3409 
3410 static int early_out_gaussian_blur(Sequence *seq, float UNUSED(facf0), float UNUSED(facf1))
3411 {
3413  if (data->size_x == 0.0f && data->size_y == 0) {
3414  return EARLY_USE_INPUT_1;
3415  }
3416  return EARLY_DO_EFFECT;
3417 }
3418 
3419 /* TODO(sergey): De-duplicate with compositor. */
3420 static float *make_gaussian_blur_kernel(float rad, int size)
3421 {
3422  float *gausstab, sum, val;
3423  float fac;
3424  int i, n;
3425 
3426  n = 2 * size + 1;
3427 
3428  gausstab = (float *)MEM_mallocN(sizeof(float) * n, __func__);
3429 
3430  sum = 0.0f;
3431  fac = (rad > 0.0f ? 1.0f / rad : 0.0f);
3432  for (i = -size; i <= size; i++) {
3433  val = RE_filter_value(R_FILTER_GAUSS, (float)i * fac);
3434  sum += val;
3435  gausstab[i + size] = val;
3436  }
3437 
3438  sum = 1.0f / sum;
3439  for (i = 0; i < n; i++) {
3440  gausstab[i] *= sum;
3441  }
3442 
3443  return gausstab;
3444 }
3445 
3447  int start_line,
3448  int x,
3449  int y,
3450  int frame_width,
3451  int UNUSED(frame_height),
3452  const unsigned char *rect,
3453  unsigned char *out)
3454 {
3455 #define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
3457  const int size_x = (int)(data->size_x + 0.5f);
3458  int i, j;
3459 
3460  /* Make gaussian weight table. */
3461  float *gausstab_x;
3462  gausstab_x = make_gaussian_blur_kernel(data->size_x, size_x);
3463 
3464  for (i = 0; i < y; i++) {
3465  for (j = 0; j < x; j++) {
3466  int out_index = INDEX(j, i);
3467  float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f};
3468  float accum_weight = 0.0f;
3469 
3470  for (int current_x = j - size_x; current_x <= j + size_x; current_x++) {
3471  if (current_x < 0 || current_x >= frame_width) {
3472  /* Out of bounds. */
3473  continue;
3474  }
3475  int index = INDEX(current_x, i + start_line);
3476  float weight = gausstab_x[current_x - j + size_x];
3477  accum[0] += rect[index] * weight;
3478  accum[1] += rect[index + 1] * weight;
3479  accum[2] += rect[index + 2] * weight;
3480  accum[3] += rect[index + 3] * weight;
3481  accum_weight += weight;
3482  }
3483 
3484  float inv_accum_weight = 1.0f / accum_weight;
3485  out[out_index + 0] = accum[0] * inv_accum_weight;
3486  out[out_index + 1] = accum[1] * inv_accum_weight;
3487  out[out_index + 2] = accum[2] * inv_accum_weight;
3488  out[out_index + 3] = accum[3] * inv_accum_weight;
3489  }
3490  }
3491 
3492  MEM_freeN(gausstab_x);
3493 #undef INDEX
3494 }
3495 
3497  int start_line,
3498  int x,
3499  int y,
3500  int UNUSED(frame_width),
3501  int frame_height,
3502  const unsigned char *rect,
3503  unsigned char *out)
3504 {
3505 #define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
3507  const int size_y = (int)(data->size_y + 0.5f);
3508  int i, j;
3509 
3510  /* Make gaussian weight table. */
3511  float *gausstab_y;
3512  gausstab_y = make_gaussian_blur_kernel(data->size_y, size_y);
3513 
3514  for (i = 0; i < y; i++) {
3515  for (j = 0; j < x; j++) {
3516  int out_index = INDEX(j, i);
3517  float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f};
3518  float accum_weight = 0.0f;
3519  for (int current_y = i - size_y; current_y <= i + size_y; current_y++) {
3520  if (current_y < -start_line || current_y + start_line >= frame_height) {
3521  /* Out of bounds. */
3522  continue;
3523  }
3524  int index = INDEX(j, current_y + start_line);
3525  float weight = gausstab_y[current_y - i + size_y];
3526  accum[0] += rect[index] * weight;
3527  accum[1] += rect[index + 1] * weight;
3528  accum[2] += rect[index + 2] * weight;
3529  accum[3] += rect[index + 3] * weight;
3530  accum_weight += weight;
3531  }
3532  float inv_accum_weight = 1.0f / accum_weight;
3533  out[out_index + 0] = accum[0] * inv_accum_weight;
3534  out[out_index + 1] = accum[1] * inv_accum_weight;
3535  out[out_index + 2] = accum[2] * inv_accum_weight;
3536  out[out_index + 3] = accum[3] * inv_accum_weight;
3537  }
3538  }
3539 
3540  MEM_freeN(gausstab_y);
3541 #undef INDEX
3542 }
3543 
3545  int start_line,
3546  int x,
3547  int y,
3548  int frame_width,
3549  int UNUSED(frame_height),
3550  float *rect,
3551  float *out)
3552 {
3553 #define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
3555  const int size_x = (int)(data->size_x + 0.5f);
3556  int i, j;
3557 
3558  /* Make gaussian weight table. */
3559  float *gausstab_x;
3560  gausstab_x = make_gaussian_blur_kernel(data->size_x, size_x);
3561 
3562  for (i = 0; i < y; i++) {
3563  for (j = 0; j < x; j++) {
3564  int out_index = INDEX(j, i);
3565  float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f};
3566  float accum_weight = 0.0f;
3567  for (int current_x = j - size_x; current_x <= j + size_x; current_x++) {
3568  if (current_x < 0 || current_x >= frame_width) {
3569  /* Out of bounds. */
3570  continue;
3571  }
3572  int index = INDEX(current_x, i + start_line);
3573  float weight = gausstab_x[current_x - j + size_x];
3574  madd_v4_v4fl(accum, &rect[index], weight);
3575  accum_weight += weight;
3576  }
3577  mul_v4_v4fl(&out[out_index], accum, 1.0f / accum_weight);
3578  }
3579  }
3580 
3581  MEM_freeN(gausstab_x);
3582 #undef INDEX
3583 }
3584 
3586  int start_line,
3587  int x,
3588  int y,
3589  int UNUSED(frame_width),
3590  int frame_height,
3591  float *rect,
3592  float *out)
3593 {
3594 #define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
3596  const int size_y = (int)(data->size_y + 0.5f);
3597  int i, j;
3598 
3599  /* Make gaussian weight table. */
3600  float *gausstab_y;
3601  gausstab_y = make_gaussian_blur_kernel(data->size_y, size_y);
3602 
3603  for (i = 0; i < y; i++) {
3604  for (j = 0; j < x; j++) {
3605  int out_index = INDEX(j, i);
3606  float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f};
3607  float accum_weight = 0.0f;
3608  for (int current_y = i - size_y; current_y <= i + size_y; current_y++) {
3609  if (current_y < -start_line || current_y + start_line >= frame_height) {
3610  /* Out of bounds. */
3611  continue;
3612  }
3613  int index = INDEX(j, current_y + start_line);
3614  float weight = gausstab_y[current_y - i + size_y];
3615  madd_v4_v4fl(accum, &rect[index], weight);
3616  accum_weight += weight;
3617  }
3618  mul_v4_v4fl(&out[out_index], accum, 1.0f / accum_weight);
3619  }
3620  }
3621 
3622  MEM_freeN(gausstab_y);
3623 #undef INDEX
3624 }
3625 
3627  Sequence *seq,
3628  ImBuf *ibuf,
3629  int start_line,
3630  int total_lines,
3631  ImBuf *out)
3632 {
3633  if (out->rect_float) {
3634  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
3635 
3637  context, ibuf, NULL, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
3638 
3640  start_line,
3641  context->rectx,
3642  total_lines,
3643  context->rectx,
3644  context->recty,
3645  ibuf->rect_float,
3646  rect_out);
3647  }
3648  else {
3649  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
3650 
3652  context, ibuf, NULL, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
3653 
3655  start_line,
3656  context->rectx,
3657  total_lines,
3658  context->rectx,
3659  context->recty,
3660  (unsigned char *)ibuf->rect,
3661  rect_out);
3662  }
3663 }
3664 
3666  Sequence *seq,
3667  ImBuf *ibuf,
3668  int start_line,
3669  int total_lines,
3670  ImBuf *out)
3671 {
3672  if (out->rect_float) {
3673  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
3674 
3676  context, ibuf, NULL, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
3677 
3679  start_line,
3680  context->rectx,
3681  total_lines,
3682  context->rectx,
3683  context->recty,
3684  ibuf->rect_float,
3685  rect_out);
3686  }
3687  else {
3688  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
3689 
3691  context, ibuf, NULL, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
3692 
3694  start_line,
3695  context->rectx,
3696  total_lines,
3697  context->rectx,
3698  context->recty,
3699  (unsigned char *)ibuf->rect,
3700  rect_out);
3701  }
3702 }
3703 
3710 
3718 
3719 static void render_effect_execute_init_handle(void *handle_v,
3720  int start_line,
3721  int tot_line,
3722  void *init_data_v)
3723 {
3726 
3727  handle->context = init_data->context;
3728  handle->seq = init_data->seq;
3729  handle->ibuf = init_data->ibuf;
3730  handle->out = init_data->out;
3731 
3732  handle->start_line = start_line;
3733  handle->tot_line = tot_line;
3734 }
3735 
3736 static void *render_effect_execute_do_x_thread(void *thread_data_v)
3737 {
3738  RenderGaussianBlurEffectThread *thread_data = (RenderGaussianBlurEffectThread *)thread_data_v;
3740  thread_data->seq,
3741  thread_data->ibuf,
3742  thread_data->start_line,
3743  thread_data->tot_line,
3744  thread_data->out);
3745  return NULL;
3746 }
3747 
3748 static void *render_effect_execute_do_y_thread(void *thread_data_v)
3749 {
3750  RenderGaussianBlurEffectThread *thread_data = (RenderGaussianBlurEffectThread *)thread_data_v;
3752  thread_data->seq,
3753  thread_data->ibuf,
3754  thread_data->start_line,
3755  thread_data->tot_line,
3756  thread_data->out);
3757 
3758  return NULL;
3759 }
3760 
3762  Sequence *seq,
3763  float UNUSED(timeline_frame),
3764  float UNUSED(facf0),
3765  float UNUSED(facf1),
3766  ImBuf *ibuf1,
3767  ImBuf *UNUSED(ibuf2),
3768  ImBuf *UNUSED(ibuf3))
3769 {
3770  ImBuf *out = prepare_effect_imbufs(context, ibuf1, NULL, NULL);
3771 
3773 
3774  init_data.context = context;
3775  init_data.seq = seq;
3776  init_data.ibuf = ibuf1;
3777  init_data.out = out;
3778 
3781  &init_data,
3784 
3785  ibuf1 = out;
3786  init_data.ibuf = ibuf1;
3787  out = prepare_effect_imbufs(context, ibuf1, NULL, NULL);
3788  init_data.out = out;
3789 
3792  &init_data,
3795 
3796  IMB_freeImBuf(ibuf1);
3797 
3798  return out;
3799 }
3800 
3801 /*********************** text *************************/
3802 
3803 static void init_text_effect(Sequence *seq)
3804 {
3805  TextVars *data;
3806 
3807  if (seq->effectdata) {
3808  MEM_freeN(seq->effectdata);
3809  }
3810 
3811  data = seq->effectdata = MEM_callocN(sizeof(TextVars), "textvars");
3812  data->text_font = NULL;
3813  data->text_blf_id = -1;
3814  data->text_size = 60;
3815 
3816  copy_v4_fl(data->color, 1.0f);
3817  data->shadow_color[3] = 0.7f;
3818  data->box_color[0] = 0.2f;
3819  data->box_color[1] = 0.2f;
3820  data->box_color[2] = 0.2f;
3821  data->box_color[3] = 0.7f;
3822  data->box_margin = 0.01f;
3823 
3824  BLI_strncpy(data->text, "Text", sizeof(data->text));
3825 
3826  data->loc[0] = 0.5f;
3827  data->loc[1] = 0.5f;
3828  data->align = SEQ_TEXT_ALIGN_X_CENTER;
3829  data->align_y = SEQ_TEXT_ALIGN_Y_CENTER;
3830  data->wrap_width = 1.0f;
3831 }
3832 
3833 void SEQ_effect_text_font_unload(TextVars *data, const bool do_id_user)
3834 {
3835  if (data) {
3836  /* Unlink the VFont */
3837  if (do_id_user && data->text_font != NULL) {
3838  id_us_min(&data->text_font->id);
3839  data->text_font = NULL;
3840  }
3841 
3842  /* Unload the BLF font. */
3843  if (data->text_blf_id >= 0) {
3844  BLF_unload_id(data->text_blf_id);
3845  }
3846  }
3847 }
3848 
3849 void SEQ_effect_text_font_load(TextVars *data, const bool do_id_user)
3850 {
3851  if (data->text_font != NULL) {
3852  if (do_id_user) {
3853  id_us_plus(&data->text_font->id);
3854  }
3855 
3856  char path[FILE_MAX];
3857  STRNCPY(path, data->text_font->filepath);
3859  BLI_path_abs(path, ID_BLEND_PATH_FROM_GLOBAL(&data->text_font->id));
3860 
3861  data->text_blf_id = BLF_load(path);
3862  }
3863 }
3864 
3865 static void free_text_effect(Sequence *seq, const bool do_id_user)
3866 {
3867  TextVars *data = seq->effectdata;
3868  SEQ_effect_text_font_unload(data, do_id_user);
3869 
3870  if (data) {
3871  MEM_freeN(data);
3872  seq->effectdata = NULL;
3873  }
3874 }
3875 
3876 static void load_text_effect(Sequence *seq)
3877 {
3878  TextVars *data = seq->effectdata;
3880 }
3881 
3882 static void copy_text_effect(Sequence *dst, Sequence *src, const int flag)
3883 {
3884  dst->effectdata = MEM_dupallocN(src->effectdata);
3885  TextVars *data = dst->effectdata;
3886 
3887  data->text_blf_id = -1;
3889 }
3890 
3891 static int num_inputs_text(void)
3892 {
3893  return 0;
3894 }
3895 
3896 static int early_out_text(Sequence *seq, float UNUSED(facf0), float UNUSED(facf1))
3897 {
3898  TextVars *data = seq->effectdata;
3899  if (data->text[0] == 0 || data->text_size < 1 ||
3900  ((data->color[3] == 0.0f) &&
3901  (data->shadow_color[3] == 0.0f || (data->flag & SEQ_TEXT_SHADOW) == 0))) {
3902  return EARLY_USE_INPUT_1;
3903  }
3904  return EARLY_NO_INPUT;
3905 }
3906 
3908  Sequence *seq,
3909  float UNUSED(timeline_frame),
3910  float UNUSED(facf0),
3911  float UNUSED(facf1),
3912  ImBuf *ibuf1,
3913  ImBuf *ibuf2,
3914  ImBuf *ibuf3)
3915 {
3916  ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
3917  TextVars *data = seq->effectdata;
3918  int width = out->x;
3919  int height = out->y;
3920  struct ColorManagedDisplay *display;
3921  const char *display_device;
3922  int font = blf_mono_font_render;
3923  int line_height;
3924  int y_ofs, x, y;
3925  double proxy_size_comp;
3926 
3927  if (data->text_blf_id == SEQ_FONT_NOT_LOADED) {
3928  data->text_blf_id = -1;
3929 
3930  if (data->text_font) {
3931  data->text_blf_id = BLF_load(data->text_font->filepath);
3932  }
3933  }
3934 
3935  if (data->text_blf_id >= 0) {
3936  font = data->text_blf_id;
3937  }
3938 
3939  display_device = context->scene->display_settings.display_device;
3940  display = IMB_colormanagement_display_get_named(display_device);
3941 
3942  /* Compensate text size for preview render size. */
3943  proxy_size_comp = context->scene->r.size / 100.0;
3944  if (context->preview_render_size != SEQ_RENDER_SIZE_SCENE) {
3945  proxy_size_comp = SEQ_rendersize_to_scale_factor(context->preview_render_size);
3946  }
3947 
3948  /* set before return */
3949  BLF_size(font, proxy_size_comp * data->text_size, 72);
3950 
3951  const int font_flags = BLF_WORD_WRAP | /* Always allow wrapping. */
3952  ((data->flag & SEQ_TEXT_BOLD) ? BLF_BOLD : 0) |
3953  ((data->flag & SEQ_TEXT_ITALIC) ? BLF_ITALIC : 0);
3954  BLF_enable(font, font_flags);
3955 
3956  /* use max width to enable newlines only */
3957  BLF_wordwrap(font, (data->wrap_width != 0.0f) ? data->wrap_width * width : -1);
3958 
3959  BLF_buffer(
3960  font, out->rect_float, (unsigned char *)out->rect, width, height, out->channels, display);
3961 
3962  line_height = BLF_height_max(font);
3963 
3964  y_ofs = -BLF_descender(font);
3965 
3966  x = (data->loc[0] * width);
3967  y = (data->loc[1] * height) + y_ofs;
3968 
3969  /* vars for calculating wordwrap and optional box */
3970  struct {
3971  struct ResultBLF info;
3972  rctf rect;
3973  } wrap;
3974 
3975  BLF_boundbox_ex(font, data->text, sizeof(data->text), &wrap.rect, &wrap.info);
3976 
3977  if ((data->align == SEQ_TEXT_ALIGN_X_LEFT) && (data->align_y == SEQ_TEXT_ALIGN_Y_TOP)) {
3978  y -= line_height;
3979  }
3980  else {
3981  if (data->align == SEQ_TEXT_ALIGN_X_RIGHT) {
3982  x -= BLI_rctf_size_x(&wrap.rect);
3983  }
3984  else if (data->align == SEQ_TEXT_ALIGN_X_CENTER) {
3985  x -= BLI_rctf_size_x(&wrap.rect) / 2;
3986  }
3987 
3988  if (data->align_y == SEQ_TEXT_ALIGN_Y_TOP) {
3989  y -= line_height;
3990  }
3991  else if (data->align_y == SEQ_TEXT_ALIGN_Y_BOTTOM) {
3992  y += (wrap.info.lines - 1) * line_height;
3993  }
3994  else if (data->align_y == SEQ_TEXT_ALIGN_Y_CENTER) {
3995  y += (((wrap.info.lines - 1) / 2) * line_height) - (line_height / 2);
3996  }
3997  }
3998 
3999  if (data->flag & SEQ_TEXT_BOX) {
4000  if (out->rect) {
4001  const int margin = data->box_margin * width;
4002  const int minx = x + wrap.rect.xmin - margin;
4003  const int maxx = x + wrap.rect.xmax + margin;
4004  const int miny = y + wrap.rect.ymin - margin;
4005  const int maxy = y + wrap.rect.ymax + margin;
4006  IMB_rectfill_area_replace(out, data->box_color, minx, miny, maxx, maxy);
4007  }
4008  }
4009  /* BLF_SHADOW won't work with buffers, instead use cheap shadow trick */
4010  if (data->flag & SEQ_TEXT_SHADOW) {
4011  int fontx, fonty;
4012  fontx = BLF_width_max(font);
4013  fonty = line_height;
4014  BLF_position(font, x + max_ii(fontx / 55, 1), y - max_ii(fonty / 30, 1), 0.0f);
4015  BLF_buffer_col(font, data->shadow_color);
4017  }
4018 
4019  BLF_position(font, x, y, 0.0f);
4020  BLF_buffer_col(font, data->color);
4022 
4023  BLF_buffer(font, NULL, NULL, 0, 0, 0, NULL);
4024 
4025  BLF_disable(font, font_flags);
4026 
4027  return out;
4028 }
4029 
4030 /*********************** sequence effect factory *************************/
4031 
4032 static void init_noop(Sequence *UNUSED(seq))
4033 {
4034 }
4035 
4036 static void load_noop(Sequence *UNUSED(seq))
4037 {
4038 }
4039 
4040 static void free_noop(Sequence *UNUSED(seq), const bool UNUSED(do_id_user))
4041 {
4042 }
4043 
4044 static int num_inputs_default(void)
4045 {
4046  return 2;
4047 }
4048 
4049 static void copy_effect_default(Sequence *dst, Sequence *src, const int UNUSED(flag))
4050 {
4051  dst->effectdata = MEM_dupallocN(src->effectdata);
4052 }
4053 
4054 static void free_effect_default(Sequence *seq, const bool UNUSED(do_id_user))
4055 {
4056  if (seq->effectdata) {
4057  MEM_freeN(seq->effectdata);
4058  }
4059 
4060  seq->effectdata = NULL;
4061 }
4062 
4063 static int early_out_noop(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
4064 {
4065  return EARLY_DO_EFFECT;
4066 }
4067 
4068 static int early_out_fade(Sequence *UNUSED(seq), float facf0, float facf1)
4069 {
4070  if (facf0 == 0.0f && facf1 == 0.0f) {
4071  return EARLY_USE_INPUT_1;
4072  }
4073  if (facf0 == 1.0f && facf1 == 1.0f) {
4074  return EARLY_USE_INPUT_2;
4075  }
4076  return EARLY_DO_EFFECT;
4077 }
4078 
4079 static int early_out_mul_input2(Sequence *UNUSED(seq), float facf0, float facf1)
4080 {
4081  if (facf0 == 0.0f && facf1 == 0.0f) {
4082  return EARLY_USE_INPUT_1;
4083  }
4084  return EARLY_DO_EFFECT;
4085 }
4086 
4088  short UNUSED(adrcode),
4089  float *UNUSED(ymin),
4090  float *UNUSED(ymax))
4091 {
4092  /* defaults are fine */
4093 }
4094 
4096  float UNUSED(timeline_frame),
4097  float *facf0,
4098  float *facf1)
4099 {
4100  *facf0 = *facf1 = 1.0;
4101 }
4102 
4103 static void get_default_fac_fade(Sequence *seq, float timeline_frame, float *facf0, float *facf1)
4104 {
4105  *facf0 = (float)(timeline_frame - seq->startdisp);
4106  *facf1 = (float)(*facf0 + 0.5f);
4107  *facf0 /= seq->len;
4108  *facf1 /= seq->len;
4109 }
4110 
4112  ImBuf *ibuf1,
4113  ImBuf *ibuf2,
4114  ImBuf *ibuf3)
4115 {
4116  ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
4117 
4118  return out;
4119 }
4120 
4121 static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
4122 {
4123  struct SeqEffectHandle rval;
4124  int sequence_type = seq_type;
4125 
4126  rval.multithreaded = false;
4127  rval.supports_mask = false;
4128  rval.init = init_noop;
4129  rval.num_inputs = num_inputs_default;
4130  rval.load = load_noop;
4131  rval.free = free_noop;
4132  rval.early_out = early_out_noop;
4133  rval.get_default_fac = get_default_fac_noop;
4134  rval.store_icu_yrange = store_icu_yrange_noop;
4135  rval.execute = NULL;
4136  rval.init_execution = init_execution;
4137  rval.execute_slice = NULL;
4138  rval.copy = NULL;
4139 
4140  switch (sequence_type) {
4141  case SEQ_TYPE_CROSS:
4142  rval.multithreaded = true;
4143  rval.execute_slice = do_cross_effect;
4144  rval.early_out = early_out_fade;
4145  rval.get_default_fac = get_default_fac_fade;
4146  break;
4147  case SEQ_TYPE_GAMCROSS:
4148  rval.multithreaded = true;
4149  rval.init = init_gammacross;
4150  rval.load = load_gammacross;
4151  rval.free = free_gammacross;
4152  rval.early_out = early_out_fade;
4153  rval.get_default_fac = get_default_fac_fade;
4154  rval.init_execution = gammacross_init_execution;
4155  rval.execute_slice = do_gammacross_effect;
4156  break;
4157  case SEQ_TYPE_ADD:
4158  rval.multithreaded = true;
4159  rval.execute_slice = do_add_effect;
4160  rval.early_out = early_out_mul_input2;
4161  break;
4162  case SEQ_TYPE_SUB:
4163  rval.multithreaded = true;
4164  rval.execute_slice = do_sub_effect;
4165  rval.early_out = early_out_mul_input2;
4166  break;
4167  case SEQ_TYPE_MUL:
4168  rval.multithreaded = true;
4169  rval.execute_slice = do_mul_effect;
4170  rval.early_out = early_out_mul_input2;
4171  break;
4172  case SEQ_TYPE_SCREEN:
4173  case SEQ_TYPE_OVERLAY:
4174  case SEQ_TYPE_COLOR_BURN:
4175  case SEQ_TYPE_LINEAR_BURN:
4176  case SEQ_TYPE_DARKEN:
4177  case SEQ_TYPE_LIGHTEN:
4178  case SEQ_TYPE_DODGE:
4179  case SEQ_TYPE_SOFT_LIGHT:
4180  case SEQ_TYPE_HARD_LIGHT:
4181  case SEQ_TYPE_PIN_LIGHT:
4182  case SEQ_TYPE_LIN_LIGHT:
4183  case SEQ_TYPE_VIVID_LIGHT:
4184  case SEQ_TYPE_BLEND_COLOR:
4185  case SEQ_TYPE_HUE:
4186  case SEQ_TYPE_SATURATION:
4187  case SEQ_TYPE_VALUE:
4188  case SEQ_TYPE_DIFFERENCE:
4189  case SEQ_TYPE_EXCLUSION:
4190  rval.multithreaded = true;
4191  rval.execute_slice = do_blend_mode_effect;
4192  rval.early_out = early_out_mul_input2;
4193  break;
4194  case SEQ_TYPE_COLORMIX:
4195  rval.multithreaded = true;
4196  rval.init = init_colormix_effect;
4197  rval.free = free_effect_default;
4198  rval.copy = copy_effect_default;
4199  rval.execute_slice = do_colormix_effect;
4200  rval.early_out = early_out_mul_input2;
4201  break;
4202  case SEQ_TYPE_ALPHAOVER:
4203  rval.multithreaded = true;
4204  rval.init = init_alpha_over_or_under;
4205  rval.execute_slice = do_alphaover_effect;
4206  break;
4207  case SEQ_TYPE_OVERDROP:
4208  rval.multithreaded = true;
4209  rval.execute_slice = do_overdrop_effect;
4210  break;
4211  case SEQ_TYPE_ALPHAUNDER:
4212  rval.multithreaded = true;
4213  rval.init = init_alpha_over_or_under;
4214  rval.execute_slice = do_alphaunder_effect;
4215  break;
4216  case SEQ_TYPE_WIPE:
4217  rval.init = init_wipe_effect;
4218  rval.num_inputs = num_inputs_wipe;
4219  rval.free = free_wipe_effect;
4220  rval.copy = copy_wipe_effect;
4221  rval.early_out = early_out_fade;
4222  rval.get_default_fac = get_default_fac_fade;
4223  rval.execute = do_wipe_effect;
4224  break;
4225  case SEQ_TYPE_GLOW:
4226  rval.init = init_glow_effect;
4227  rval.num_inputs = num_inputs_glow;
4228  rval.free = free_glow_effect;
4229  rval.copy = copy_glow_effect;
4230  rval.execute = do_glow_effect;
4231  break;
4232  case SEQ_TYPE_TRANSFORM:
4233  rval.multithreaded = true;
4234  rval.init = init_transform_effect;
4235  rval.num_inputs = num_inputs_transform;
4236  rval.free = free_transform_effect;
4237  rval.copy = copy_transform_effect;
4238  rval.execute_slice = do_transform_effect;
4239  break;
4240  case SEQ_TYPE_SPEED:
4241  rval.init = init_speed_effect;
4242  rval.num_inputs = num_inputs_speed;
4243  rval.load = load_speed_effect;
4244  rval.free = free_speed_effect;
4245  rval.copy = copy_speed_effect;
4246  rval.execute = do_speed_effect;
4247  rval.early_out = early_out_speed;
4248  rval.store_icu_yrange = store_icu_yrange_speed;
4249  break;
4250  case SEQ_TYPE_COLOR:
4251  rval.init = init_solid_color;
4252  rval.num_inputs = num_inputs_color;
4253  rval.early_out = early_out_color;
4254  rval.free = free_solid_color;
4255  rval.copy = copy_solid_color;
4256  rval.execute = do_solid_color;
4257  break;
4258  case SEQ_TYPE_MULTICAM:
4259  rval.num_inputs = num_inputs_multicam;
4260  rval.early_out = early_out_multicam;
4261  rval.execute = do_multicam;
4262  break;
4263  case SEQ_TYPE_ADJUSTMENT:
4264  rval.supports_mask = true;
4265  rval.num_inputs = num_inputs_adjustment;
4266  rval.early_out = early_out_adjustment;
4267  rval.execute = do_adjustment;
4268  break;
4270  rval.init = init_gaussian_blur_effect;
4271  rval.num_inputs = num_inputs_gaussian_blur;
4272  rval.free = free_gaussian_blur_effect;
4273  rval.copy = copy_gaussian_blur_effect;
4274  rval.early_out = early_out_gaussian_blur;
4275  rval.execute = do_gaussian_blur_effect;
4276  break;
4277  case SEQ_TYPE_TEXT:
4278  rval.num_inputs = num_inputs_text;
4279  rval.init = init_text_effect;
4280  rval.free = free_text_effect;
4281  rval.load = load_text_effect;
4282  rval.copy = copy_text_effect;
4283  rval.early_out = early_out_text;
4284  rval.execute = do_text_effect;
4285  break;
4286  }
4287 
4288  return rval;
4289 }
4290 
4292 {
4293  struct SeqEffectHandle rval = {false, false, NULL};
4294 
4295  if (seq->type & SEQ_TYPE_EFFECT) {
4296  rval = get_sequence_effect_impl(seq->type);
4297  if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) {
4298  rval.load(seq);
4299  seq->flag &= ~SEQ_EFFECT_NOT_LOADED;
4300  }
4301  }
4302 
4303  return rval;
4304 }
4305 
4307 {
4308  struct SeqEffectHandle rval = {false, false, NULL};
4309 
4310  if (seq->blend_mode != 0) {
4311  if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) {
4312  /* load the effect first */
4313  rval = get_sequence_effect_impl(seq->type);
4314  rval.load(seq);
4315  }
4316 
4317  rval = get_sequence_effect_impl(seq->blend_mode);
4318  if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) {
4319  /* now load the blend and unset unloaded flag */
4320  rval.load(seq);
4321  seq->flag &= ~SEQ_EFFECT_NOT_LOADED;
4322  }
4323  }
4324 
4325  return rval;
4326 }
4327 
4328 int SEQ_effect_get_num_inputs(int seq_type)
4329 {
4330  struct SeqEffectHandle rval = get_sequence_effect_impl(seq_type);
4331 
4332  int cnt = rval.num_inputs();
4333  if (rval.execute || (rval.execute_slice && rval.init_execution)) {
4334  return cnt;
4335  }
4336  return 0;
4337 }
typedef float(TangentPoint)[2]
float evaluate_fcurve(struct FCurve *fcu, float evaltime)
Definition: fcurve.c:2186
struct FCurve * id_data_find_fcurve(ID *id, void *data, struct StructRNA *type, const char *prop_name, int index, bool *r_driven)
Definition: fcurve.c:221
void id_us_min(struct ID *id)
Definition: lib_id.c:297
@ LIB_ID_CREATE_NO_USER_REFCOUNT
Definition: BKE_lib_id.h:92
void id_us_plus(struct ID *id)
Definition: lib_id.c:288
float BLF_width_max(int fontid) ATTR_WARN_UNUSED_RESULT
Definition: blf.c:768
void BLF_draw_buffer(int fontid, const char *str, size_t len) ATTR_NONNULL(2)
Definition: blf.c:913
int blf_mono_font_render
Definition: blf.c:71
#define BLF_BOLD
Definition: BLF_api.h:280
#define BLF_DRAW_STR_DUMMY_MAX
Definition: BLF_api.h:283
#define BLF_ITALIC
Definition: BLF_api.h:281
void BLF_disable(int fontid, int option)
Definition: blf.c:283
void BLF_buffer_col(int fontid, const float rgba[4]) ATTR_NONNULL(2)
Definition: blf.c:871
float BLF_descender(int fontid) ATTR_WARN_UNUSED_RESULT
Definition: blf.c:779
void BLF_unload_id(int fontid)
Definition: blf.c:260
void BLF_buffer(int fontid, float *fbuf, unsigned char *cbuf, int w, int h, int nch, struct ColorManagedDisplay *display)
Definition: blf.c:851
void BLF_boundbox_ex(int fontid, const char *str, size_t len, struct rctf *box, struct ResultBLF *r_info) ATTR_NONNULL(2)
Definition: blf.c:676
void BLF_size(int fontid, int size, int dpi)
Definition: blf.c:367
void BLF_enable(int fontid, int option)
Definition: blf.c:274
int BLF_load(const char *name) ATTR_NONNULL()
Definition: blf.c:153
int BLF_height_max(int fontid) ATTR_WARN_UNUSED_RESULT
Definition: blf.c:757
#define BLF_WORD_WRAP
Definition: BLF_api.h:275
void BLF_wordwrap(int fontid, int wrap_width)
Definition: blf.c:822
void BLF_position(int fontid, float x, float y, float z)
Definition: blf.c:312
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define BLI_INLINE
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
MINLINE int clamp_i(int value, int min, int max)
#define M_PI
Definition: BLI_math_base.h:38
MINLINE void straight_uchar_to_premul_float(float result[4], const unsigned char color[4])
MINLINE void premul_float_to_straight_uchar(unsigned char *result, const float color[4])
MINLINE void blend_color_add_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_exclusion_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_linearburn_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_overlay_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_saturation_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_burn_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_color_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_linearlight_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_sub_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
MINLINE void blend_color_saturation_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_hue_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_difference_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_dodge_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_luminosity_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_pinlight_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_mul_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_pinlight_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_screen_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_screen_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_vividlight_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_linearburn_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_mul_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
MINLINE void blend_color_vividlight_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_darken_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
MINLINE void blend_color_luminosity_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_difference_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_burn_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_color_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_overlay_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_dodge_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_hardlight_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_sub_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_darken_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_softlight_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_add_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
MINLINE void blend_color_hue_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_lighten_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
MINLINE void blend_color_exclusion_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_hardlight_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_linearlight_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_lighten_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_softlight_float(float dst[4], const float src1[4], const float src2[4])
#define DEG2RADF(_deg)
MINLINE void mul_v4_v4fl(float r[3], const float a[4], float f)
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void zero_v4(float r[4])
MINLINE void madd_v4_v4fl(float r[4], const float a[4], float f)
MINLINE void copy_v4_fl(float r[4], float f)
#define FILE_MAX
bool BLI_path_abs(char *path, const char *basepath) ATTR_NONNULL()
Definition: path_util.c:1016
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition: BLI_rect.h:161
#define STRNCPY(dst, src)
Definition: BLI_string.h:163
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
int BLI_thread_is_main(void)
Definition: threads.cc:234
#define UNUSED(x)
#define MAX2(a, b)
#define UNLIKELY(x)
void swap(T &a, T &b)
Definition: Common.h:33
#define ID_BLEND_PATH_FROM_GLOBAL(_id)
Definition: DNA_ID.h:421
#define R_FILTER_GAUSS
#define SEQ_SPEED_INTEGRATE
@ SEQ_EFFECT_NOT_LOADED
@ SEQ_USE_EFFECT_DEFAULT_FADE
#define SEQ_FONT_NOT_LOADED
#define SEQ_SPEED_COMPRESS_IPO_Y
@ SEQ_TEXT_ITALIC
@ SEQ_TEXT_SHADOW
@ SEQ_TEXT_BOLD
@ SEQ_TEXT_BOX
#define SEQ_SPEED_USE_INTERPOLATION
@ SEQ_TEXT_ALIGN_X_RIGHT
@ SEQ_TEXT_ALIGN_X_CENTER
@ SEQ_TEXT_ALIGN_X_LEFT
@ SEQ_TYPE_TRANSFORM
@ SEQ_TYPE_COLOR_BURN
@ SEQ_TYPE_HARD_LIGHT
@ SEQ_TYPE_EXCLUSION
@ SEQ_TYPE_CROSS
@ SEQ_TYPE_GLOW
@ SEQ_TYPE_VALUE
@ SEQ_TYPE_COLORMIX
@ SEQ_TYPE_WIPE
@ SEQ_TYPE_OVERDROP
@ SEQ_TYPE_PIN_LIGHT
@ SEQ_TYPE_ALPHAUNDER
@ SEQ_TYPE_DODGE
@ SEQ_TYPE_HUE
@ SEQ_TYPE_LINEAR_BURN
@ SEQ_TYPE_GAMCROSS
@ SEQ_TYPE_MULTICAM
@ SEQ_TYPE_BLEND_COLOR
@ SEQ_TYPE_DARKEN
@ SEQ_TYPE_MUL
@ SEQ_TYPE_GAUSSIAN_BLUR
@ SEQ_TYPE_ADD
@ SEQ_TYPE_ALPHAOVER
@ SEQ_TYPE_TEXT
@ SEQ_TYPE_SCREEN
@ SEQ_TYPE_SOFT_LIGHT
@ SEQ_TYPE_SUB
@ SEQ_TYPE_VIVID_LIGHT
@ SEQ_TYPE_OVERLAY
@ SEQ_TYPE_SPEED
@ SEQ_TYPE_COLOR
@ SEQ_TYPE_SATURATION
@ SEQ_TYPE_LIN_LIGHT
@ SEQ_TYPE_EFFECT
@ SEQ_TYPE_DIFFERENCE
@ SEQ_TYPE_ADJUSTMENT
@ SEQ_TYPE_LIGHTEN
@ SEQ_TEXT_ALIGN_Y_BOTTOM
@ SEQ_TEXT_ALIGN_Y_TOP
@ SEQ_TEXT_ALIGN_Y_CENTER
@ SEQ_RENDER_SIZE_SCENE
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
void IMB_colormanagement_assign_float_colorspace(struct ImBuf *ibuf, const char *name)
struct ColorManagedDisplay * IMB_colormanagement_display_get_named(const char *name)
void nearest_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout)
Definition: imageprocess.c:337
void IMB_rectfill_area_replace(const struct ImBuf *ibuf, const float col[4], int x1, int y1, int x2, int y2)
struct ImBuf * IMB_allocImBuf(unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
Definition: allocimbuf.c:478
struct ImBuf * IMB_dupImBuf(const struct ImBuf *ibuf1)
void IMB_rect_from_float(struct ImBuf *ibuf)
Definition: divers.c:720
void IMB_freeImBuf(struct ImBuf *ibuf)
Definition: allocimbuf.c:211
void IMB_processor_apply_threaded(int buffer_lines, int handle_size, void *init_customdata, void(init_handle)(void *handle, int start_line, int tot_line, void *customdata), void *(do_thread)(void *))
Definition: imageprocess.c:362
void IMB_buffer_float_from_byte(float *rect_to, const unsigned char *rect_from, int profile_to, int profile_from, bool predivide, int width, int height, int stride_to, int stride_from)
Definition: divers.c:370
void IMB_buffer_float_premultiply(float *buf, int width, int height)
Definition: divers.c:871
void IMB_buffer_byte_from_float(unsigned char *rect_to, const float *rect_from, int channels_from, float dither, int profile_to, int profile_from, bool predivide, int width, int height, int stride_to, int stride_from)
Definition: divers.c:112
void IMB_buffer_float_unpremultiply(float *buf, int width, int height)
Definition: divers.c:861
Contains defines and structs used throughout the imbuf module.
#define IB_PROFILE_SRGB
@ IB_rectfloat
@ IB_rect
void IMB_metadata_copy(struct ImBuf *dimb, struct ImBuf *simb)
Definition: metadata.c:80
Read Guarded memory(de)allocation.
static void init_data(ModifierData *md)
StructRNA RNA_Sequence
@ DO_IRIS_WIPE
Definition: SEQ_effects.h:41
@ DO_CLOCK_WIPE
Definition: SEQ_effects.h:42
@ DO_DOUBLE_WIPE
Definition: SEQ_effects.h:38
@ DO_SINGLE_WIPE
Definition: SEQ_effects.h:37
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
#define output
static T sum(const btAlignedObjectArray< T > &items)
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
SIMD_FORCE_INLINE btVector3 rotate(const btVector3 &wAxis, const btScalar angle) const
Return a rotated version of this vector.
Scene scene
static CCL_NAMESPACE_BEGIN const double alpha
static void copy_speed_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
Definition: effects.c:3121
struct SeqEffectHandle SEQ_effect_handle_get(Sequence *seq)
Definition: effects.c:4291
static int early_out_text(Sequence *seq, float UNUSED(facf0), float UNUSED(facf1))
Definition: effects.c:3896
static int early_out_noop(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
Definition: effects.c:4063
static void init_text_effect(Sequence *seq)
Definition: effects.c:3803
static void do_drop_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect2i, unsigned char *rect1i, unsigned char *outi)
Definition: effects.c:1307
#define RE_GAMMA_TABLE_SIZE
Definition: effects.c:740
static void do_drop_effect_float(float facf0, float facf1, int x, int y, float *rect2i, float *rect1i, float *outi)
Definition: effects.c:1361
static void do_colormix_effect(const SeqRenderData *context, Sequence *seq, float UNUSED(timeline_frame), float UNUSED(facf0), float UNUSED(facf1), ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:1853
static void do_gaussian_blur_effect_x_cb(const SeqRenderData *context, Sequence *seq, ImBuf *ibuf, int start_line, int total_lines, ImBuf *out)
Definition: effects.c:3626
static ImBuf * do_multicam(const SeqRenderData *context, Sequence *seq, float timeline_frame, float UNUSED(facf0), float UNUSED(facf1), ImBuf *UNUSED(ibuf1), ImBuf *UNUSED(ibuf2), ImBuf *UNUSED(ibuf3))
Definition: effects.c:2973
struct WipeZone WipeZone
static void do_blend_mode_effect(const SeqRenderData *context, Sequence *seq, float UNUSED(timeline_frame), float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:1812
static void makeGammaTables(float gamma)
Definition: effects.c:752
static void do_gammacross_effect_float(float facf0, float UNUSED(facf1), int x, int y, float *rect1, float *rect2, float *out)
Definition: effects.c:950
static void do_gammacross_effect(const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(timeline_frame), float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:1001
static struct ImBuf * init_execution(const SeqRenderData *context, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
Definition: effects.c:4111
static float in_band(float width, float dist, int side, int dir)
Definition: effects.c:1907
static void free_noop(Sequence *UNUSED(seq), const bool UNUSED(do_id_user))
Definition: effects.c:4040
static ImBuf * do_gaussian_blur_effect(const SeqRenderData *context, Sequence *seq, float UNUSED(timeline_frame), float UNUSED(facf0), float UNUSED(facf1), ImBuf *ibuf1, ImBuf *UNUSED(ibuf2), ImBuf *UNUSED(ibuf3))
Definition: effects.c:3761
static int early_out_speed(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
Definition: effects.c:3130
static int num_inputs_color(void)
Definition: effects.c:2851
static void do_blend_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2, int btype, unsigned char *out)
Definition: effects.c:1728
static bool gamma_tabs_init
Definition: effects.c:738
static void init_speed_effect(Sequence *seq)
Definition: effects.c:3079
static void build_gammatabs(void)
Definition: effects.c:868
static float inv_gamfactor_table[RE_GAMMA_TABLE_SIZE]
Definition: effects.c:745
static void copy_wipe_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
Definition: effects.c:2176
static void do_sub_effect_float(float UNUSED(facf0), float facf1, int x, int y, float *rect1, float *rect2, float *out)
Definition: effects.c:1221
static void free_solid_color(Sequence *seq, const bool UNUSED(do_id_user))
Definition: effects.c:2856
static void free_gammacross(Sequence *UNUSED(seq), const bool UNUSED(do_id_user))
Definition: effects.c:885
static int seq_effect_speed_get_strip_content_length(const Sequence *seq)
Definition: effects.c:3163
static void init_colormix_effect(Sequence *seq)
Definition: effects.c:1840
static float gamfactor_table[RE_GAMMA_TABLE_SIZE]
Definition: effects.c:743
static void do_glow_effect_byte(Sequence *seq, int render_size, float facf0, float UNUSED(facf1), int x, int y, unsigned char *rect1, unsigned char *UNUSED(rect2), unsigned char *out)
Definition: effects.c:2740
static void copy_solid_color(Sequence *dst, Sequence *src, const int UNUSED(flag))
Definition: effects.c:2865
static void init_alpha_over_or_under(Sequence *seq)
Definition: effects.c:198
static int num_inputs_speed(void)
Definition: effects.c:3104
static void RVAddBitmaps_float(float *a, float *b, float *c, int width, int height)
Definition: effects.c:2659
static void free_glow_effect(Sequence *seq, const bool UNUSED(do_id_user))
Definition: effects.c:2726
@ GlowR
Definition: effects.c:129
@ GlowB
Definition: effects.c:131
@ GlowG
Definition: effects.c:130
@ GlowA
Definition: effects.c:132
struct RenderGaussianBlurEffectInitData RenderGaussianBlurEffectInitData
static void init_glow_effect(Sequence *seq)
Definition: effects.c:2702
void SEQ_effect_text_font_unload(TextVars *data, const bool do_id_user)
Definition: effects.c:3833
void seq_effect_speed_rebuild_map(Scene *scene, Sequence *seq, bool force)
Definition: effects.c:3172
static float speed_effect_interpolation_ratio_get(SpeedControlVars *s, Sequence *seq, float timeline_frame)
Definition: effects.c:3301
BLI_INLINE void apply_blend_function_float(float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out, IMB_blend_func_float blend_function)
Definition: effects.c:1602
static int num_inputs_glow(void)
Definition: effects.c:2721
static void load_text_effect(Sequence *seq)
Definition: effects.c:3876
static int num_inputs_text(void)
Definition: effects.c:3891
int SEQ_effect_get_num_inputs(int seq_type)
Definition: effects.c:4328
static float gamma_range_table[RE_GAMMA_TABLE_SIZE+1]
Definition: effects.c:742
static void gamtabs(float gamma)
Definition: effects.c:834
static void do_alphaunder_effect_float(float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out)
Definition: effects.c:488
static void copy_transform_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
Definition: effects.c:2393
static void do_blend_effect_float(float facf0, float facf1, int x, int y, float *rect1, float *rect2, int btype, float *out)
Definition: effects.c:1646
static void free_effect_default(Sequence *seq, const bool UNUSED(do_id_user))
Definition: effects.c:4054
#define YOFF
Definition: effects.c:1305
#define XOFF
Definition: effects.c:1304
static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
Definition: effects.c:4121
static void init_gammacross(Sequence *UNUSED(seq))
Definition: effects.c:877
static void free_transform_effect(Sequence *seq, const bool UNUSED(do_id_user))
Definition: effects.c:2385
static void init_wipe_effect(Sequence *seq)
Definition: effects.c:2153
static void do_alphaunder_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
Definition: effects.c:393
static float invGammaCorrect(float c)
Definition: effects.c:814
static float check_zone(WipeZone *wipezone, int x, int y, Sequence *seq, float facf0)
Definition: effects.c:1933
static void free_gaussian_blur_effect(Sequence *seq, const bool UNUSED(do_id_user))
Definition: effects.c:3396
static void get_default_fac_fade(Sequence *seq, float timeline_frame, float *facf0, float *facf1)
Definition: effects.c:4103
static float gammaCorrect(float c)
Definition: effects.c:788
static void precalc_wipe_zone(WipeZone *wipezone, WipeVars *wipe, int xo, int yo)
Definition: effects.c:1896
static ImBuf * prepare_effect_imbufs(const SeqRenderData *context, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
Definition: effects.c:135
static float valid_gamma
Definition: effects.c:749
static float inv_color_step
Definition: effects.c:748
static void do_cross_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
Definition: effects.c:600
void(* IMB_blend_func_byte)(unsigned char *dst, const unsigned char *src1, const unsigned char *src2)
Definition: effects.c:1553
static float color_domain_table[RE_GAMMA_TABLE_SIZE+1]
Definition: effects.c:746
static int num_inputs_transform(void)
Definition: effects.c:2380
static void * render_effect_execute_do_y_thread(void *thread_data_v)
Definition: effects.c:3748
static void slice_get_byte_buffers(const SeqRenderData *context, const ImBuf *ibuf1, const ImBuf *ibuf2, const ImBuf *ibuf3, const ImBuf *out, int start_line, unsigned char **rect1, unsigned char **rect2, unsigned char **rect3, unsigned char **rect_out)
Definition: effects.c:76
static void copy_effect_default(Sequence *dst, Sequence *src, const int UNUSED(flag))
Definition: effects.c:4049
static void RVIsolateHighlights_float(const float *in, float *out, int width, int height, float threshold, float boost, float clamp)
Definition: effects.c:2674
static void do_alphaunder_effect(const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(timeline_frame), float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:568
static void do_gaussian_blur_effect_byte_y(Sequence *seq, int start_line, int x, int y, int UNUSED(frame_width), int frame_height, const unsigned char *rect, unsigned char *out)
Definition: effects.c:3496
static void transform_image(int x, int y, int start_line, int total_lines, ImBuf *ibuf1, ImBuf *out, float scale_x, float scale_y, float translate_x, float translate_y, float rotate, int interpolation)
Definition: effects.c:2398
static void do_transform_effect(const SeqRenderData *context, Sequence *seq, float UNUSED(timeline_frame), float UNUSED(facf0), float UNUSED(facf1), ImBuf *ibuf1, ImBuf *UNUSED(ibuf2), ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:2449
static void do_alphaover_effect_float(float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out)
Definition: effects.c:292
static void do_mul_effect_float(float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out)
Definition: effects.c:1471
static void do_sub_effect(const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(timeline_frame), float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:1271
static ImBuf * do_speed_effect(const SeqRenderData *context, Sequence *seq, float timeline_frame, float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
Definition: effects.c:3309
static void do_gaussian_blur_effect_float_y(Sequence *seq, int start_line, int x, int y, int UNUSED(frame_width), int frame_height, float *rect, float *out)
Definition: effects.c:3585
static void RVBlurBitmap2_float(float *map, int width, int height, float blur, int quality)
Definition: effects.c:2508
static void load_speed_effect(Sequence *seq)
Definition: effects.c:3096
static void init_noop(Sequence *UNUSED(seq))
Definition: effects.c:4032
static void do_cross_effect(const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(timeline_frame), float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:703
static void load_gammacross(Sequence *UNUSED(seq))
Definition: effects.c:881
static void copy_gaussian_blur_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
Definition: effects.c:3405
static int early_out_fade(Sequence *UNUSED(seq), float facf0, float facf1)
Definition: effects.c:4068
static float color_step
Definition: effects.c:747
static void load_noop(Sequence *UNUSED(seq))
Definition: effects.c:4036
struct SeqEffectHandle seq_effect_get_sequence_blend(Sequence *seq)
Definition: effects.c:4306
void(* IMB_blend_func_float)(float *dst, const float *src1, const float *src2)
Definition: effects.c:1556
static ImBuf * do_adjustment(const SeqRenderData *context, Sequence *seq, float timeline_frame, float UNUSED(facf0), float UNUSED(facf1), ImBuf *UNUSED(ibuf1), ImBuf *UNUSED(ibuf2), ImBuf *UNUSED(ibuf3))
Definition: effects.c:3054
static void free_wipe_effect(Sequence *seq, const bool UNUSED(do_id_user))
Definition: effects.c:2167
static int early_out_adjustment(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
Definition: effects.c:3012
static float inv_gamma_range_table[RE_GAMMA_TABLE_SIZE+1]
Definition: effects.c:744
static void do_add_effect(const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(timeline_frame), float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:1136
static void do_gaussian_blur_effect_y_cb(const SeqRenderData *context, Sequence *seq, ImBuf *ibuf, int start_line, int total_lines, ImBuf *out)
Definition: effects.c:3665
static void init_solid_color(Sequence *seq)
Definition: effects.c:2837
static void do_add_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
Definition: effects.c:1033
static void do_alphaover_effect(const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(timeline_frame), float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:361
static unsigned short gamtab[65536]
Definition: effects.c:736
static int early_out_multicam(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
Definition: effects.c:2968
static void free_text_effect(Sequence *seq, const bool do_id_user)
Definition: effects.c:3865
static int early_out_color(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
Definition: effects.c:2870
static void store_icu_yrange_noop(Sequence *UNUSED(seq), short UNUSED(adrcode), float *UNUSED(ymin), float *UNUSED(ymax))
Definition: effects.c:4087
static int num_inputs_wipe(void)
Definition: effects.c:2162
static ImBuf * do_solid_color(const SeqRenderData *context, Sequence *seq, float UNUSED(timeline_frame), float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
Definition: effects.c:2875
static void do_mul_effect(const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(timeline_frame), float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:1522
static void do_wipe_effect_byte(Sequence *seq, float facf0, float UNUSED(facf1), int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
Definition: effects.c:2181
BLI_INLINE void apply_blend_function_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out, IMB_blend_func_byte blend_function)
Definition: effects.c:1558
static ImBuf * do_text_effect(const SeqRenderData *context, Sequence *seq, float UNUSED(timeline_frame), float UNUSED(facf0), float UNUSED(facf1), ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
Definition: effects.c:3907
static float valid_inv_gamma
Definition: effects.c:750
static int early_out_mul_input2(Sequence *UNUSED(seq), float facf0, float facf1)
Definition: effects.c:4079
static float * make_gaussian_blur_kernel(float rad, int size)
Definition: effects.c:3420
static ImBuf * do_adjustment_impl(const SeqRenderData *context, Sequence *seq, float timeline_frame)
Definition: effects.c:3017
static ImBuf * do_glow_effect(const SeqRenderData *context, Sequence *seq, float UNUSED(timeline_frame), float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
Definition: effects.c:2796
static void store_icu_yrange_speed(Sequence *seq, short UNUSED(adrcode), float *ymin, float *ymax)
Definition: effects.c:3135
static void copy_text_effect(Sequence *dst, Sequence *src, const int flag)
Definition: effects.c:3882
static int num_inputs_adjustment(void)
Definition: effects.c:3007
static void do_sub_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
Definition: effects.c:1168
static void slice_get_float_buffers(const SeqRenderData *context, const ImBuf *ibuf1, const ImBuf *ibuf2, const ImBuf *ibuf3, const ImBuf *out, int start_line, float **rect1, float **rect2, float **rect3, float **rect_out)
Definition: effects.c:101
static void do_glow_effect_float(Sequence *seq, int render_size, float facf0, float UNUSED(facf1), int x, int y, float *rect1, float *UNUSED(rect2), float *out)
Definition: effects.c:2774
static void do_gammacross_effect_byte(float facf0, float UNUSED(facf1), int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
Definition: effects.c:889
static void init_transform_effect(Sequence *seq)
Definition: effects.c:2355
static int num_inputs_gaussian_blur(void)
Definition: effects.c:3391
static void init_gaussian_blur_effect(Sequence *seq)
Definition: effects.c:3382
static int early_out_gaussian_blur(Sequence *seq, float UNUSED(facf0), float UNUSED(facf1))
Definition: effects.c:3410
static void do_cross_effect_float(float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out)
Definition: effects.c:654
static void do_wipe_effect_float(Sequence *seq, float facf0, float UNUSED(facf1), int x, int y, float *rect1, float *rect2, float *out)
Definition: effects.c:2253
static ImBuf * do_wipe_effect(const SeqRenderData *context, Sequence *seq, float UNUSED(timeline_frame), float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
Definition: effects.c:2318
float seq_speed_effect_target_frame_get(const SeqRenderData *context, Sequence *seq, float timeline_frame, int input)
Definition: effects.c:3279
static void do_add_effect_float(float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out)
Definition: effects.c:1087
static struct ImBuf * gammacross_init_execution(const SeqRenderData *context, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
Definition: effects.c:990
static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
Definition: effects.c:207
#define INDEX(_x, _y)
static void free_speed_effect(Sequence *seq, const bool UNUSED(do_id_user))
Definition: effects.c:3109
static void do_gaussian_blur_effect_byte_x(Sequence *seq, int start_line, int x, int y, int frame_width, int UNUSED(frame_height), const unsigned char *rect, unsigned char *out)
Definition: effects.c:3446
static void do_overdrop_effect(const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(timeline_frame), float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:3337
static void do_mul_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
Definition: effects.c:1412
static void do_gaussian_blur_effect_float_x(Sequence *seq, int start_line, int x, int y, int frame_width, int UNUSED(frame_height), float *rect, float *out)
Definition: effects.c:3544
static void render_effect_execute_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v)
Definition: effects.c:3719
static void * render_effect_execute_do_x_thread(void *thread_data_v)
Definition: effects.c:3736
void SEQ_effect_text_font_load(TextVars *data, const bool do_id_user)
Definition: effects.c:3849
static unsigned short igamtab1[256]
Definition: effects.c:737
static int num_inputs_multicam(void)
Definition: effects.c:2963
static int num_inputs_default(void)
Definition: effects.c:4044
struct RenderGaussianBlurEffectThread RenderGaussianBlurEffectThread
static void get_default_fac_noop(Sequence *UNUSED(seq), float UNUSED(timeline_frame), float *facf0, float *facf1)
Definition: effects.c:4095
static void copy_glow_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
Definition: effects.c:2735
DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
float RE_filter_value(int type, float x)
Definition: initrender.c:128
#define sinf(x)
#define cosf(x)
#define tanf(x)
#define powf(x, y)
#define hypotf(x, y)
#define floorf(x)
#define fabsf(x)
#define sqrtf(x)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
BLI_INLINE void bilinear_interpolation(const unsigned char *byte_buffer, const float *float_buffer, unsigned char *byte_output, float *float_output, int width, int height, int components, float u, float v, bool wrap_x, bool wrap_y)
Definition: math_interp.c:264
BLI_INLINE void bicubic_interpolation(const unsigned char *byte_buffer, const float *float_buffer, unsigned char *byte_output, float *float_output, int width, int height, int components, float u, float v)
Definition: math_interp.c:94
static unsigned c
Definition: RandGen.cpp:97
static unsigned a[3]
Definition: RandGen.cpp:92
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
Definition: rall1d.h:359
INLINE Rall1d< T, V, S > asin(const Rall1d< T, V, S > &x)
Definition: rall1d.h:391
INLINE Rall1d< T, V, S > exp(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:295
INLINE Rall1d< T, V, S > hypot(const Rall1d< T, V, S > &y, const Rall1d< T, V, S > &x)
Definition: rall1d.h:383
static GPUContext * wrap(Context *ctx)
double SEQ_rendersize_to_scale_factor(int render_size)
Definition: proxy.c:99
ImBuf * seq_render_effect_execute_threaded(struct SeqEffectHandle *sh, const SeqRenderData *context, Sequence *seq, float timeline_frame, float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
Definition: render.c:808
ImBuf * seq_render_give_ibuf_seqbase(const SeqRenderData *context, float timeline_frame, int chan_shown, ListBase *seqbasep)
Definition: render.c:2016
void seq_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, bool make_float)
Definition: render.c:108
#define EARLY_USE_INPUT_2
Definition: render.h:40
#define EARLY_DO_EFFECT
Definition: render.h:38
#define EARLY_USE_INPUT_1
Definition: render.h:39
#define EARLY_NO_INPUT
Definition: render.h:37
struct SELECTID_Context context
Definition: select_engine.c:47
float seq_give_frame_index(Sequence *seq, float timeline_frame)
Definition: strip_time.c:48
ListBase seqbase
int channels
unsigned int * rect
float * rect_float
const SeqRenderData * context
Definition: effects.c:3705
const SeqRenderData * context
Definition: effects.c:3712
struct RenderData r
ColorManagedColorspaceSettings sequencer_colorspace_settings
int(* num_inputs)(void)
Definition: SEQ_effects.h:55
void(* execute_slice)(const struct SeqRenderData *context, struct Sequence *seq, float timeline_frame, float facf0, float facf1, struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf3, int start_line, int total_lines, struct ImBuf *out)
Definition: SEQ_effects.h:98
void(* load)(struct Sequence *seqconst)
Definition: SEQ_effects.h:59
struct ImBuf *(* execute)(const struct SeqRenderData *context, struct Sequence *seq, float timeline_frame, float facf0, float facf1, struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf3)
Definition: SEQ_effects.h:84
struct ImBuf *(* init_execution)(const struct SeqRenderData *context, struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf3)
Definition: SEQ_effects.h:93
struct Sequence * seq1
struct Sequence * seq2
float angle
Definition: effects.c:1889
int flip
Definition: effects.c:1890
int xo
Definition: effects.c:1891
int yo
Definition: effects.c:1891
float pythangle
Definition: effects.c:1893
int width
Definition: effects.c:1892
__forceinline const avxi abs(const avxi &a)
Definition: util_avxi.h:186
ccl_device_inline int clamp(int a, int mn, int mx)
Definition: util_math.h:283
ccl_device_inline float2 floor(const float2 &a)
ccl_device_inline float3 ceil(const float3 &a)
ListBase * SEQ_get_seqbase_by_seq(ListBase *seqbase, Sequence *seq)
Definition: utils.c:428
Sequence * seq_find_metastrip_by_sequence(ListBase *seqbase, Sequence *meta, Sequence *seq)
Definition: utils.c:445