Blender  V3.3
effects.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved.
3  * 2003-2009 Blender Foundation.
4  * 2005-2006 Peter Schlaile <peter [at] schlaile [dot] de> */
5 
10 #include <math.h>
11 #include <stdlib.h>
12 #include <string.h>
13 
14 #include "MEM_guardedalloc.h"
15 
16 #include "BLI_listbase.h"
17 #include "BLI_math.h" /* windows needs for M_PI */
18 #include "BLI_path_util.h"
19 #include "BLI_rect.h"
20 #include "BLI_string.h"
21 #include "BLI_threads.h"
22 #include "BLI_utildefines.h"
23 
24 #include "DNA_anim_types.h"
25 #include "DNA_packedFile_types.h"
26 #include "DNA_scene_types.h"
27 #include "DNA_sequence_types.h"
28 #include "DNA_space_types.h"
29 #include "DNA_vfont_types.h"
30 
31 #include "BKE_fcurve.h"
32 #include "BKE_lib_id.h"
33 #include "BKE_main.h"
34 
35 #include "IMB_colormanagement.h"
36 #include "IMB_imbuf.h"
37 #include "IMB_imbuf_types.h"
38 #include "IMB_metadata.h"
39 
40 #include "BLI_math_color_blend.h"
41 
42 #include "RNA_access.h"
43 #include "RNA_prototypes.h"
44 
45 #include "RE_pipeline.h"
46 
47 #include "SEQ_channels.h"
48 #include "SEQ_effects.h"
49 #include "SEQ_proxy.h"
50 #include "SEQ_relations.h"
51 #include "SEQ_render.h"
52 #include "SEQ_time.h"
53 #include "SEQ_utils.h"
54 
55 #include "BLF_api.h"
56 
57 #include "effects.h"
58 #include "render.h"
59 #include "strip_time.h"
60 #include "utils.h"
61 
62 static struct SeqEffectHandle get_sequence_effect_impl(int seq_type);
63 
64 /* -------------------------------------------------------------------- */
69  const ImBuf *ibuf1,
70  const ImBuf *ibuf2,
71  const ImBuf *ibuf3,
72  const ImBuf *out,
73  int start_line,
74  unsigned char **rect1,
75  unsigned char **rect2,
76  unsigned char **rect3,
77  unsigned char **rect_out)
78 {
79  int offset = 4 * start_line * context->rectx;
80 
81  *rect1 = (unsigned char *)ibuf1->rect + offset;
82  *rect_out = (unsigned char *)out->rect + offset;
83 
84  if (ibuf2) {
85  *rect2 = (unsigned char *)ibuf2->rect + offset;
86  }
87 
88  if (ibuf3) {
89  *rect3 = (unsigned char *)ibuf3->rect + offset;
90  }
91 }
92 
94  const ImBuf *ibuf1,
95  const ImBuf *ibuf2,
96  const ImBuf *ibuf3,
97  const ImBuf *out,
98  int start_line,
99  float **rect1,
100  float **rect2,
101  float **rect3,
102  float **rect_out)
103 {
104  int offset = 4 * start_line * context->rectx;
105 
106  *rect1 = ibuf1->rect_float + offset;
107  *rect_out = out->rect_float + offset;
108 
109  if (ibuf2) {
110  *rect2 = ibuf2->rect_float + offset;
111  }
112 
113  if (ibuf3) {
114  *rect3 = ibuf3->rect_float + offset;
115  }
116 }
117 
120 /* -------------------------------------------------------------------- */
124 enum {
125  GlowR = 0,
126  GlowG = 1,
127  GlowB = 2,
128  GlowA = 3,
129 };
130 
132  ImBuf *ibuf1,
133  ImBuf *ibuf2,
134  ImBuf *ibuf3)
135 {
136  ImBuf *out;
137  Scene *scene = context->scene;
138  int x = context->rectx;
139  int y = context->recty;
140 
141  if (!ibuf1 && !ibuf2 && !ibuf3) {
142  /* hmmm, global float option ? */
143  out = IMB_allocImBuf(x, y, 32, IB_rect);
144  }
145  else if ((ibuf1 && ibuf1->rect_float) || (ibuf2 && ibuf2->rect_float) ||
146  (ibuf3 && ibuf3->rect_float)) {
147  /* if any inputs are rectfloat, output is float too */
148 
149  out = IMB_allocImBuf(x, y, 32, IB_rectfloat);
150  }
151  else {
152  out = IMB_allocImBuf(x, y, 32, IB_rect);
153  }
154 
155  if (out->rect_float) {
156  if (ibuf1 && !ibuf1->rect_float) {
157  seq_imbuf_to_sequencer_space(scene, ibuf1, true);
158  }
159 
160  if (ibuf2 && !ibuf2->rect_float) {
161  seq_imbuf_to_sequencer_space(scene, ibuf2, true);
162  }
163 
164  if (ibuf3 && !ibuf3->rect_float) {
165  seq_imbuf_to_sequencer_space(scene, ibuf3, true);
166  }
167 
169  }
170  else {
171  if (ibuf1 && !ibuf1->rect) {
172  IMB_rect_from_float(ibuf1);
173  }
174 
175  if (ibuf2 && !ibuf2->rect) {
176  IMB_rect_from_float(ibuf2);
177  }
178 
179  if (ibuf3 && !ibuf3->rect) {
180  IMB_rect_from_float(ibuf3);
181  }
182  }
183 
184  /* If effect only affecting a single channel, forward input's metadata to the output. */
185  if (ibuf1 != NULL && ibuf1 == ibuf2 && ibuf2 == ibuf3) {
186  IMB_metadata_copy(out, ibuf1);
187  }
188 
189  return out;
190 }
191 
194 /* -------------------------------------------------------------------- */
199 {
200  Sequence *seq1 = seq->seq1;
201  Sequence *seq2 = seq->seq2;
202 
203  seq->seq2 = seq1;
204  seq->seq1 = seq2;
205 }
206 
208  float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
209 {
210  unsigned char *cp1 = rect1;
211  unsigned char *cp2 = rect2;
212  unsigned char *rt = out;
213 
214  for (int i = 0; i < y; i++) {
215  for (int j = 0; j < x; j++) {
216  /* rt = rt1 over rt2 (alpha from rt1) */
217 
218  float tempc[4], rt1[4], rt2[4];
221 
222  float mfac = 1.0f - fac * rt1[3];
223 
224  if (fac <= 0.0f) {
225  *((unsigned int *)rt) = *((unsigned int *)cp2);
226  }
227  else if (mfac <= 0.0f) {
228  *((unsigned int *)rt) = *((unsigned int *)cp1);
229  }
230  else {
231  tempc[0] = fac * rt1[0] + mfac * rt2[0];
232  tempc[1] = fac * rt1[1] + mfac * rt2[1];
233  tempc[2] = fac * rt1[2] + mfac * rt2[2];
234  tempc[3] = fac * rt1[3] + mfac * rt2[3];
235 
237  }
238  cp1 += 4;
239  cp2 += 4;
240  rt += 4;
241  }
242  }
243 }
244 
246  float fac, int x, int y, float *rect1, float *rect2, float *out)
247 {
248  float *rt1 = rect1;
249  float *rt2 = rect2;
250  float *rt = out;
251 
252  for (int i = 0; i < y; i++) {
253  for (int j = 0; j < x; j++) {
254  /* rt = rt1 over rt2 (alpha from rt1) */
255 
256  float mfac = 1.0f - (fac * rt1[3]);
257 
258  if (fac <= 0.0f) {
259  memcpy(rt, rt2, sizeof(float[4]));
260  }
261  else if (mfac <= 0) {
262  memcpy(rt, rt1, sizeof(float[4]));
263  }
264  else {
265  rt[0] = fac * rt1[0] + mfac * rt2[0];
266  rt[1] = fac * rt1[1] + mfac * rt2[1];
267  rt[2] = fac * rt1[2] + mfac * rt2[2];
268  rt[3] = fac * rt1[3] + mfac * rt2[3];
269  }
270  rt1 += 4;
271  rt2 += 4;
272  rt += 4;
273  }
274  }
275 }
276 
278  Sequence *UNUSED(seq),
279  float UNUSED(timeline_frame),
280  float fac,
281  ImBuf *ibuf1,
282  ImBuf *ibuf2,
283  ImBuf *UNUSED(ibuf3),
284  int start_line,
285  int total_lines,
286  ImBuf *out)
287 {
288  if (out->rect_float) {
289  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
290 
292  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
293 
294  do_alphaover_effect_float(fac, context->rectx, total_lines, rect1, rect2, rect_out);
295  }
296  else {
297  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
298 
300  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
301 
302  do_alphaover_effect_byte(fac, context->rectx, total_lines, rect1, rect2, rect_out);
303  }
304 }
305 
308 /* -------------------------------------------------------------------- */
313  float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
314 {
315  unsigned char *cp1 = rect1;
316  unsigned char *cp2 = rect2;
317  unsigned char *rt = out;
318 
319  for (int i = 0; i < y; i++) {
320  for (int j = 0; j < x; j++) {
321  /* rt = rt1 under rt2 (alpha from rt2) */
322 
323  float tempc[4], rt1[4], rt2[4];
326 
327  /* this complex optimization is because the
328  * 'skybuf' can be crossed in
329  */
330  if (rt2[3] <= 0.0f && fac >= 1.0f) {
331  *((unsigned int *)rt) = *((unsigned int *)cp1);
332  }
333  else if (rt2[3] >= 1.0f) {
334  *((unsigned int *)rt) = *((unsigned int *)cp2);
335  }
336  else {
337  float temp_fac = (fac * (1.0f - rt2[3]));
338 
339  if (fac <= 0) {
340  *((unsigned int *)rt) = *((unsigned int *)cp2);
341  }
342  else {
343  tempc[0] = (temp_fac * rt1[0] + rt2[0]);
344  tempc[1] = (temp_fac * rt1[1] + rt2[1]);
345  tempc[2] = (temp_fac * rt1[2] + rt2[2]);
346  tempc[3] = (temp_fac * rt1[3] + rt2[3]);
347 
349  }
350  }
351  cp1 += 4;
352  cp2 += 4;
353  rt += 4;
354  }
355  }
356 }
357 
359  float fac, int x, int y, float *rect1, float *rect2, float *out)
360 {
361  float *rt1 = rect1;
362  float *rt2 = rect2;
363  float *rt = out;
364 
365  for (int i = 0; i < y; i++) {
366  for (int j = 0; j < x; j++) {
367  /* rt = rt1 under rt2 (alpha from rt2) */
368 
369  /* this complex optimization is because the
370  * 'skybuf' can be crossed in
371  */
372  if (rt2[3] <= 0 && fac >= 1.0f) {
373  memcpy(rt, rt1, sizeof(float[4]));
374  }
375  else if (rt2[3] >= 1.0f) {
376  memcpy(rt, rt2, sizeof(float[4]));
377  }
378  else {
379  float temp_fac = fac * (1.0f - rt2[3]);
380 
381  if (fac == 0) {
382  memcpy(rt, rt2, sizeof(float[4]));
383  }
384  else {
385  rt[0] = temp_fac * rt1[0] + rt2[0];
386  rt[1] = temp_fac * rt1[1] + rt2[1];
387  rt[2] = temp_fac * rt1[2] + rt2[2];
388  rt[3] = temp_fac * rt1[3] + rt2[3];
389  }
390  }
391  rt1 += 4;
392  rt2 += 4;
393  rt += 4;
394  }
395  }
396 }
397 
399  Sequence *UNUSED(seq),
400  float UNUSED(timeline_frame),
401  float fac,
402  ImBuf *ibuf1,
403  ImBuf *ibuf2,
404  ImBuf *UNUSED(ibuf3),
405  int start_line,
406  int total_lines,
407  ImBuf *out)
408 {
409  if (out->rect_float) {
410  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
411 
413  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
414 
415  do_alphaunder_effect_float(fac, context->rectx, total_lines, rect1, rect2, rect_out);
416  }
417  else {
418  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
419 
421  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
422 
423  do_alphaunder_effect_byte(fac, context->rectx, total_lines, rect1, rect2, rect_out);
424  }
425 }
426 
429 /* -------------------------------------------------------------------- */
434  float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
435 {
436  unsigned char *rt1 = rect1;
437  unsigned char *rt2 = rect2;
438  unsigned char *rt = out;
439 
440  int temp_fac = (int)(256.0f * fac);
441  int temp_mfac = 256 - temp_fac;
442 
443  for (int i = 0; i < y; i++) {
444  for (int j = 0; j < x; j++) {
445  rt[0] = (temp_mfac * rt1[0] + temp_fac * rt2[0]) >> 8;
446  rt[1] = (temp_mfac * rt1[1] + temp_fac * rt2[1]) >> 8;
447  rt[2] = (temp_mfac * rt1[2] + temp_fac * rt2[2]) >> 8;
448  rt[3] = (temp_mfac * rt1[3] + temp_fac * rt2[3]) >> 8;
449 
450  rt1 += 4;
451  rt2 += 4;
452  rt += 4;
453  }
454  }
455 }
456 
457 static void do_cross_effect_float(float fac, int x, int y, float *rect1, float *rect2, float *out)
458 {
459  float *rt1 = rect1;
460  float *rt2 = rect2;
461  float *rt = out;
462 
463  float mfac = 1.0f - fac;
464 
465  for (int i = 0; i < y; i++) {
466  for (int j = 0; j < x; j++) {
467  rt[0] = mfac * rt1[0] + fac * rt2[0];
468  rt[1] = mfac * rt1[1] + fac * rt2[1];
469  rt[2] = mfac * rt1[2] + fac * rt2[2];
470  rt[3] = mfac * rt1[3] + fac * rt2[3];
471 
472  rt1 += 4;
473  rt2 += 4;
474  rt += 4;
475  }
476  }
477 }
478 
480  Sequence *UNUSED(seq),
481  float UNUSED(timeline_frame),
482  float fac,
483  ImBuf *ibuf1,
484  ImBuf *ibuf2,
485  ImBuf *UNUSED(ibuf3),
486  int start_line,
487  int total_lines,
488  ImBuf *out)
489 {
490  if (out->rect_float) {
491  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
492 
494  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
495 
496  do_cross_effect_float(fac, context->rectx, total_lines, rect1, rect2, rect_out);
497  }
498  else {
499  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
500 
502  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
503 
504  do_cross_effect_byte(fac, context->rectx, total_lines, rect1, rect2, rect_out);
505  }
506 }
507 
510 /* -------------------------------------------------------------------- */
514 /* copied code from initrender.c */
515 static unsigned short gamtab[65536];
516 static unsigned short igamtab1[256];
517 static bool gamma_tabs_init = false;
518 
519 #define RE_GAMMA_TABLE_SIZE 400
520 
526 static float color_step;
527 static float inv_color_step;
528 static float valid_gamma;
529 static float valid_inv_gamma;
530 
531 static void makeGammaTables(float gamma)
532 {
533  /* we need two tables: one forward, one backward */
534  int i;
535 
536  valid_gamma = gamma;
537  valid_inv_gamma = 1.0f / gamma;
540 
541  /* We could squeeze out the two range tables to gain some memory */
542  for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++) {
546  }
547 
548  /* The end of the table should match 1.0 carefully. In order to avoid
549  * rounding errors, we just set this explicitly. The last segment may
550  * have a different length than the other segments, but our
551  * interpolation is insensitive to that
552  */
556 
557  /* To speed up calculations, we make these calc factor tables. They are
558  * multiplication factors used in scaling the interpolation
559  */
560  for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++) {
564  }
565 }
566 
567 static float gammaCorrect(float c)
568 {
569  int i;
570  float res;
571 
572  i = floorf(c * inv_color_step);
573  /* Clip to range [0, 1]: outside, just do the complete calculation.
574  * We may have some performance problems here. Stretching up the LUT
575  * may help solve that, by exchanging LUT size for the interpolation.
576  * Negative colors are explicitly handled.
577  */
578  if (UNLIKELY(i < 0)) {
579  res = -powf(-c, valid_gamma);
580  }
581  else if (i >= RE_GAMMA_TABLE_SIZE) {
582  res = powf(c, valid_gamma);
583  }
584  else {
585  res = gamma_range_table[i] + ((c - color_domain_table[i]) * gamfactor_table[i]);
586  }
587 
588  return res;
589 }
590 
591 /* ------------------------------------------------------------------------- */
592 
593 static float invGammaCorrect(float c)
594 {
595  int i;
596  float res = 0.0;
597 
598  i = floorf(c * inv_color_step);
599  /* Negative colors are explicitly handled */
600  if (UNLIKELY(i < 0)) {
601  res = -powf(-c, valid_inv_gamma);
602  }
603  else if (i >= RE_GAMMA_TABLE_SIZE) {
604  res = powf(c, valid_inv_gamma);
605  }
606  else {
608  }
609 
610  return res;
611 }
612 
613 static void gamtabs(float gamma)
614 {
615  float val, igamma = 1.0f / gamma;
616  int a;
617 
618  /* gamtab: in short, out short */
619  for (a = 0; a < 65536; a++) {
620  val = a;
621  val /= 65535.0f;
622 
623  if (gamma == 2.0f) {
624  val = sqrtf(val);
625  }
626  else if (gamma != 1.0f) {
627  val = powf(val, igamma);
628  }
629 
630  gamtab[a] = (65535.99f * val);
631  }
632  /* inverse gamtab1 : in byte, out short */
633  for (a = 1; a <= 256; a++) {
634  if (gamma == 2.0f) {
635  igamtab1[a - 1] = a * a - 1;
636  }
637  else if (gamma == 1.0f) {
638  igamtab1[a - 1] = 256 * a - 1;
639  }
640  else {
641  val = a / 256.0f;
642  igamtab1[a - 1] = (65535.0 * pow(val, gamma)) - 1;
643  }
644  }
645 }
646 
647 static void build_gammatabs(void)
648 {
649  if (gamma_tabs_init == false) {
650  gamtabs(2.0f);
651  makeGammaTables(2.0f);
652  gamma_tabs_init = true;
653  }
654 }
655 
656 static void init_gammacross(Sequence *UNUSED(seq))
657 {
658 }
659 
660 static void load_gammacross(Sequence *UNUSED(seq))
661 {
662 }
663 
664 static void free_gammacross(Sequence *UNUSED(seq), const bool UNUSED(do_id_user))
665 {
666 }
667 
669  float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
670 {
671  unsigned char *cp1 = rect1;
672  unsigned char *cp2 = rect2;
673  unsigned char *rt = out;
674 
675  float mfac = 1.0f - fac;
676 
677  for (int i = 0; i < y; i++) {
678  for (int j = 0; j < x; j++) {
679  float rt1[4], rt2[4], tempc[4];
680 
683 
684  tempc[0] = gammaCorrect(mfac * invGammaCorrect(rt1[0]) + fac * invGammaCorrect(rt2[0]));
685  tempc[1] = gammaCorrect(mfac * invGammaCorrect(rt1[1]) + fac * invGammaCorrect(rt2[1]));
686  tempc[2] = gammaCorrect(mfac * invGammaCorrect(rt1[2]) + fac * invGammaCorrect(rt2[2]));
687  tempc[3] = gammaCorrect(mfac * invGammaCorrect(rt1[3]) + fac * invGammaCorrect(rt2[3]));
688 
690  cp1 += 4;
691  cp2 += 4;
692  rt += 4;
693  }
694  }
695 }
696 
698  float fac, int x, int y, float *rect1, float *rect2, float *out)
699 {
700  float *rt1 = rect1;
701  float *rt2 = rect2;
702  float *rt = out;
703 
704  float mfac = 1.0f - fac;
705 
706  for (int i = 0; i < y; i++) {
707  for (int j = 0; j < x; j++) {
708  *rt = gammaCorrect(mfac * invGammaCorrect(*rt1) + fac * invGammaCorrect(*rt2));
709  rt1++;
710  rt2++;
711  rt++;
712  }
713  }
714 }
715 
717  ImBuf *ibuf1,
718  ImBuf *ibuf2,
719  ImBuf *ibuf3)
720 {
721  ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
722  build_gammatabs();
723 
724  return out;
725 }
726 
728  Sequence *UNUSED(seq),
729  float UNUSED(timeline_frame),
730  float fac,
731  ImBuf *ibuf1,
732  ImBuf *ibuf2,
733  ImBuf *UNUSED(ibuf3),
734  int start_line,
735  int total_lines,
736  ImBuf *out)
737 {
738  if (out->rect_float) {
739  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
740 
742  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
743 
744  do_gammacross_effect_float(fac, context->rectx, total_lines, rect1, rect2, rect_out);
745  }
746  else {
747  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
748 
750  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
751 
752  do_gammacross_effect_byte(fac, context->rectx, total_lines, rect1, rect2, rect_out);
753  }
754 }
755 
758 /* -------------------------------------------------------------------- */
762 static void do_add_effect_byte(
763  float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
764 {
765  unsigned char *cp1 = rect1;
766  unsigned char *cp2 = rect2;
767  unsigned char *rt = out;
768 
769  int temp_fac = (int)(256.0f * fac);
770 
771  for (int i = 0; i < y; i++) {
772  for (int j = 0; j < x; j++) {
773  const int temp_fac2 = temp_fac * (int)cp2[3];
774  rt[0] = min_ii(cp1[0] + ((temp_fac2 * cp2[0]) >> 16), 255);
775  rt[1] = min_ii(cp1[1] + ((temp_fac2 * cp2[1]) >> 16), 255);
776  rt[2] = min_ii(cp1[2] + ((temp_fac2 * cp2[2]) >> 16), 255);
777  rt[3] = cp1[3];
778 
779  cp1 += 4;
780  cp2 += 4;
781  rt += 4;
782  }
783  }
784 }
785 
786 static void do_add_effect_float(float fac, int x, int y, float *rect1, float *rect2, float *out)
787 {
788  float *rt1 = rect1;
789  float *rt2 = rect2;
790  float *rt = out;
791 
792  for (int i = 0; i < y; i++) {
793  for (int j = 0; j < x; j++) {
794  const float temp_fac = (1.0f - (rt1[3] * (1.0f - fac))) * rt2[3];
795  rt[0] = rt1[0] + temp_fac * rt2[0];
796  rt[1] = rt1[1] + temp_fac * rt2[1];
797  rt[2] = rt1[2] + temp_fac * rt2[2];
798  rt[3] = rt1[3];
799 
800  rt1 += 4;
801  rt2 += 4;
802  rt += 4;
803  }
804  }
805 }
806 
808  Sequence *UNUSED(seq),
809  float UNUSED(timeline_frame),
810  float fac,
811  ImBuf *ibuf1,
812  ImBuf *ibuf2,
813  ImBuf *UNUSED(ibuf3),
814  int start_line,
815  int total_lines,
816  ImBuf *out)
817 {
818  if (out->rect_float) {
819  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
820 
822  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
823 
824  do_add_effect_float(fac, context->rectx, total_lines, rect1, rect2, rect_out);
825  }
826  else {
827  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
828 
830  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
831 
832  do_add_effect_byte(fac, context->rectx, total_lines, rect1, rect2, rect_out);
833  }
834 }
835 
838 /* -------------------------------------------------------------------- */
842 static void do_sub_effect_byte(
843  float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
844 {
845  unsigned char *cp1 = rect1;
846  unsigned char *cp2 = rect2;
847  unsigned char *rt = out;
848 
849  int temp_fac = (int)(256.0f * fac);
850 
851  for (int i = 0; i < y; i++) {
852  for (int j = 0; j < x; j++) {
853  const int temp_fac2 = temp_fac * (int)cp2[3];
854  rt[0] = max_ii(cp1[0] - ((temp_fac2 * cp2[0]) >> 16), 0);
855  rt[1] = max_ii(cp1[1] - ((temp_fac2 * cp2[1]) >> 16), 0);
856  rt[2] = max_ii(cp1[2] - ((temp_fac2 * cp2[2]) >> 16), 0);
857  rt[3] = cp1[3];
858 
859  cp1 += 4;
860  cp2 += 4;
861  rt += 4;
862  }
863  }
864 }
865 
866 static void do_sub_effect_float(float fac, int x, int y, float *rect1, float *rect2, float *out)
867 {
868  float *rt1 = rect1;
869  float *rt2 = rect2;
870  float *rt = out;
871 
872  float mfac = 1.0f - fac;
873 
874  for (int i = 0; i < y; i++) {
875  for (int j = 0; j < x; j++) {
876  const float temp_fac = (1.0f - (rt1[3] * mfac)) * rt2[3];
877  rt[0] = max_ff(rt1[0] - temp_fac * rt2[0], 0.0f);
878  rt[1] = max_ff(rt1[1] - temp_fac * rt2[1], 0.0f);
879  rt[2] = max_ff(rt1[2] - temp_fac * rt2[2], 0.0f);
880  rt[3] = rt1[3];
881 
882  rt1 += 4;
883  rt2 += 4;
884  rt += 4;
885  }
886  }
887 }
888 
890  Sequence *UNUSED(seq),
891  float UNUSED(timeline_frame),
892  float fac,
893  ImBuf *ibuf1,
894  ImBuf *ibuf2,
895  ImBuf *UNUSED(ibuf3),
896  int start_line,
897  int total_lines,
898  ImBuf *out)
899 {
900  if (out->rect_float) {
901  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
902 
904  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
905 
906  do_sub_effect_float(fac, context->rectx, total_lines, rect1, rect2, rect_out);
907  }
908  else {
909  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
910 
912  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
913 
914  do_sub_effect_byte(fac, context->rectx, total_lines, rect1, rect2, rect_out);
915  }
916 }
917 
920 /* -------------------------------------------------------------------- */
924 /* Must be > 0 or add precopy, etc to the function */
925 #define XOFF 8
926 #define YOFF 8
927 
929  float fac, int x, int y, unsigned char *rect2i, unsigned char *rect1i, unsigned char *outi)
930 {
931  const int xoff = min_ii(XOFF, x);
932  const int yoff = min_ii(YOFF, y);
933 
934  int temp_fac = (int)(70.0f * fac);
935 
936  unsigned char *rt2 = rect2i + yoff * 4 * x;
937  unsigned char *rt1 = rect1i;
938  unsigned char *out = outi;
939  for (int i = 0; i < y - yoff; i++) {
940  memcpy(out, rt1, sizeof(*out) * xoff * 4);
941  rt1 += xoff * 4;
942  out += xoff * 4;
943 
944  for (int j = xoff; j < x; j++) {
945  int temp_fac2 = ((temp_fac * rt2[3]) >> 8);
946 
947  *(out++) = MAX2(0, *rt1 - temp_fac2);
948  rt1++;
949  *(out++) = MAX2(0, *rt1 - temp_fac2);
950  rt1++;
951  *(out++) = MAX2(0, *rt1 - temp_fac2);
952  rt1++;
953  *(out++) = MAX2(0, *rt1 - temp_fac2);
954  rt1++;
955  rt2 += 4;
956  }
957  rt2 += xoff * 4;
958  }
959  memcpy(out, rt1, sizeof(*out) * yoff * 4 * x);
960 }
961 
963  float fac, int x, int y, float *rect2i, float *rect1i, float *outi)
964 {
965  const int xoff = min_ii(XOFF, x);
966  const int yoff = min_ii(YOFF, y);
967 
968  float temp_fac = 70.0f * fac;
969 
970  float *rt2 = rect2i + yoff * 4 * x;
971  float *rt1 = rect1i;
972  float *out = outi;
973  for (int i = 0; i < y - yoff; i++) {
974  memcpy(out, rt1, sizeof(*out) * xoff * 4);
975  rt1 += xoff * 4;
976  out += xoff * 4;
977 
978  for (int j = xoff; j < x; j++) {
979  float temp_fac2 = temp_fac * rt2[3];
980 
981  *(out++) = MAX2(0.0f, *rt1 - temp_fac2);
982  rt1++;
983  *(out++) = MAX2(0.0f, *rt1 - temp_fac2);
984  rt1++;
985  *(out++) = MAX2(0.0f, *rt1 - temp_fac2);
986  rt1++;
987  *(out++) = MAX2(0.0f, *rt1 - temp_fac2);
988  rt1++;
989  rt2 += 4;
990  }
991  rt2 += xoff * 4;
992  }
993  memcpy(out, rt1, sizeof(*out) * yoff * 4 * x);
994 }
995 
998 /* -------------------------------------------------------------------- */
1003  float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
1004 {
1005  unsigned char *rt1 = rect1;
1006  unsigned char *rt2 = rect2;
1007  unsigned char *rt = out;
1008 
1009  int temp_fac = (int)(256.0f * fac);
1010 
1011  /* Formula:
1012  * `fac * (a * b) + (1 - fac) * a => fac * a * (b - 1) + axaux = c * px + py * s;` // + centx
1013  * `yaux = -s * px + c * py;` // + centy */
1014 
1015  for (int i = 0; i < y; i++) {
1016  for (int j = 0; j < x; j++) {
1017  rt[0] = rt1[0] + ((temp_fac * rt1[0] * (rt2[0] - 255)) >> 16);
1018  rt[1] = rt1[1] + ((temp_fac * rt1[1] * (rt2[1] - 255)) >> 16);
1019  rt[2] = rt1[2] + ((temp_fac * rt1[2] * (rt2[2] - 255)) >> 16);
1020  rt[3] = rt1[3] + ((temp_fac * rt1[3] * (rt2[3] - 255)) >> 16);
1021 
1022  rt1 += 4;
1023  rt2 += 4;
1024  rt += 4;
1025  }
1026  }
1027 }
1028 
1029 static void do_mul_effect_float(float fac, int x, int y, float *rect1, float *rect2, float *out)
1030 {
1031  float *rt1 = rect1;
1032  float *rt2 = rect2;
1033  float *rt = out;
1034 
1035  /* Formula:
1036  * `fac * (a * b) + (1 - fac) * a => fac * a * (b - 1) + a`. */
1037 
1038  for (int i = 0; i < y; i++) {
1039  for (int j = 0; j < x; j++) {
1040  rt[0] = rt1[0] + fac * rt1[0] * (rt2[0] - 1.0f);
1041  rt[1] = rt1[1] + fac * rt1[1] * (rt2[1] - 1.0f);
1042  rt[2] = rt1[2] + fac * rt1[2] * (rt2[2] - 1.0f);
1043  rt[3] = rt1[3] + fac * rt1[3] * (rt2[3] - 1.0f);
1044 
1045  rt1 += 4;
1046  rt2 += 4;
1047  rt += 4;
1048  }
1049  }
1050 }
1051 
1053  Sequence *UNUSED(seq),
1054  float UNUSED(timeline_frame),
1055  float fac,
1056  ImBuf *ibuf1,
1057  ImBuf *ibuf2,
1058  ImBuf *UNUSED(ibuf3),
1059  int start_line,
1060  int total_lines,
1061  ImBuf *out)
1062 {
1063  if (out->rect_float) {
1064  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
1065 
1067  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1068 
1069  do_mul_effect_float(fac, context->rectx, total_lines, rect1, rect2, rect_out);
1070  }
1071  else {
1072  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
1073 
1075  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1076 
1077  do_mul_effect_byte(fac, context->rectx, total_lines, rect1, rect2, rect_out);
1078  }
1079 }
1080 
1083 /* -------------------------------------------------------------------- */
1087 typedef void (*IMB_blend_func_byte)(unsigned char *dst,
1088  const unsigned char *src1,
1089  const unsigned char *src2);
1090 typedef void (*IMB_blend_func_float)(float *dst, const float *src1, const float *src2);
1091 
1093  int x,
1094  int y,
1095  unsigned char *rect1,
1096  unsigned char *rect2,
1097  unsigned char *out,
1098  IMB_blend_func_byte blend_function)
1099 {
1100  unsigned char *rt1 = rect1;
1101  unsigned char *rt2 = rect2;
1102  unsigned char *rt = out;
1103 
1104  for (int i = 0; i < y; i++) {
1105  for (int j = 0; j < x; j++) {
1106  unsigned int achannel = rt2[3];
1107  rt2[3] = (unsigned int)achannel * fac;
1108  blend_function(rt, rt1, rt2);
1109  rt2[3] = achannel;
1110  rt[3] = rt1[3];
1111  rt1 += 4;
1112  rt2 += 4;
1113  rt += 4;
1114  }
1115  }
1116 }
1117 
1119  int x,
1120  int y,
1121  float *rect1,
1122  float *rect2,
1123  float *out,
1124  IMB_blend_func_float blend_function)
1125 {
1126  float *rt1 = rect1;
1127  float *rt2 = rect2;
1128  float *rt = out;
1129 
1130  for (int i = 0; i < y; i++) {
1131  for (int j = 0; j < x; j++) {
1132  float achannel = rt2[3];
1133  rt2[3] = achannel * fac;
1134  blend_function(rt, rt1, rt2);
1135  rt2[3] = achannel;
1136  rt[3] = rt1[3];
1137  rt1 += 4;
1138  rt2 += 4;
1139  rt += 4;
1140  }
1141  }
1142 }
1143 
1145  float fac, int x, int y, float *rect1, float *rect2, int btype, float *out)
1146 {
1147  switch (btype) {
1148  case SEQ_TYPE_ADD:
1149  apply_blend_function_float(fac, x, y, rect1, rect2, out, blend_color_add_float);
1150  break;
1151  case SEQ_TYPE_SUB:
1152  apply_blend_function_float(fac, x, y, rect1, rect2, out, blend_color_sub_float);
1153  break;
1154  case SEQ_TYPE_MUL:
1155  apply_blend_function_float(fac, x, y, rect1, rect2, out, blend_color_mul_float);
1156  break;
1157  case SEQ_TYPE_DARKEN:
1159  break;
1160  case SEQ_TYPE_COLOR_BURN:
1161  apply_blend_function_float(fac, x, y, rect1, rect2, out, blend_color_burn_float);
1162  break;
1163  case SEQ_TYPE_LINEAR_BURN:
1165  break;
1166  case SEQ_TYPE_SCREEN:
1168  break;
1169  case SEQ_TYPE_LIGHTEN:
1171  break;
1172  case SEQ_TYPE_DODGE:
1173  apply_blend_function_float(fac, x, y, rect1, rect2, out, blend_color_dodge_float);
1174  break;
1175  case SEQ_TYPE_OVERLAY:
1177  break;
1178  case SEQ_TYPE_SOFT_LIGHT:
1180  break;
1181  case SEQ_TYPE_HARD_LIGHT:
1183  break;
1184  case SEQ_TYPE_PIN_LIGHT:
1186  break;
1187  case SEQ_TYPE_LIN_LIGHT:
1189  break;
1190  case SEQ_TYPE_VIVID_LIGHT:
1192  break;
1193  case SEQ_TYPE_BLEND_COLOR:
1194  apply_blend_function_float(fac, x, y, rect1, rect2, out, blend_color_color_float);
1195  break;
1196  case SEQ_TYPE_HUE:
1197  apply_blend_function_float(fac, x, y, rect1, rect2, out, blend_color_hue_float);
1198  break;
1199  case SEQ_TYPE_SATURATION:
1201  break;
1202  case SEQ_TYPE_VALUE:
1204  break;
1205  case SEQ_TYPE_DIFFERENCE:
1207  break;
1208  case SEQ_TYPE_EXCLUSION:
1210  break;
1211  default:
1212  break;
1213  }
1214 }
1215 
1216 static void do_blend_effect_byte(float fac,
1217  int x,
1218  int y,
1219  unsigned char *rect1,
1220  unsigned char *rect2,
1221  int btype,
1222  unsigned char *out)
1223 {
1224  switch (btype) {
1225  case SEQ_TYPE_ADD:
1226  apply_blend_function_byte(fac, x, y, rect1, rect2, out, blend_color_add_byte);
1227  break;
1228  case SEQ_TYPE_SUB:
1229  apply_blend_function_byte(fac, x, y, rect1, rect2, out, blend_color_sub_byte);
1230  break;
1231  case SEQ_TYPE_MUL:
1232  apply_blend_function_byte(fac, x, y, rect1, rect2, out, blend_color_mul_byte);
1233  break;
1234  case SEQ_TYPE_DARKEN:
1235  apply_blend_function_byte(fac, x, y, rect1, rect2, out, blend_color_darken_byte);
1236  break;
1237  case SEQ_TYPE_COLOR_BURN:
1238  apply_blend_function_byte(fac, x, y, rect1, rect2, out, blend_color_burn_byte);
1239  break;
1240  case SEQ_TYPE_LINEAR_BURN:
1242  break;
1243  case SEQ_TYPE_SCREEN:
1244  apply_blend_function_byte(fac, x, y, rect1, rect2, out, blend_color_screen_byte);
1245  break;
1246  case SEQ_TYPE_LIGHTEN:
1247  apply_blend_function_byte(fac, x, y, rect1, rect2, out, blend_color_lighten_byte);
1248  break;
1249  case SEQ_TYPE_DODGE:
1250  apply_blend_function_byte(fac, x, y, rect1, rect2, out, blend_color_dodge_byte);
1251  break;
1252  case SEQ_TYPE_OVERLAY:
1253  apply_blend_function_byte(fac, x, y, rect1, rect2, out, blend_color_overlay_byte);
1254  break;
1255  case SEQ_TYPE_SOFT_LIGHT:
1257  break;
1258  case SEQ_TYPE_HARD_LIGHT:
1260  break;
1261  case SEQ_TYPE_PIN_LIGHT:
1263  break;
1264  case SEQ_TYPE_LIN_LIGHT:
1266  break;
1267  case SEQ_TYPE_VIVID_LIGHT:
1269  break;
1270  case SEQ_TYPE_BLEND_COLOR:
1271  apply_blend_function_byte(fac, x, y, rect1, rect2, out, blend_color_color_byte);
1272  break;
1273  case SEQ_TYPE_HUE:
1274  apply_blend_function_byte(fac, x, y, rect1, rect2, out, blend_color_hue_byte);
1275  break;
1276  case SEQ_TYPE_SATURATION:
1278  break;
1279  case SEQ_TYPE_VALUE:
1281  break;
1282  case SEQ_TYPE_DIFFERENCE:
1284  break;
1285  case SEQ_TYPE_EXCLUSION:
1287  break;
1288  default:
1289  break;
1290  }
1291 }
1292 
1294  Sequence *seq,
1295  float UNUSED(timeline_frame),
1296  float fac,
1297  ImBuf *ibuf1,
1298  ImBuf *ibuf2,
1299  ImBuf *UNUSED(ibuf3),
1300  int start_line,
1301  int total_lines,
1302  ImBuf *out)
1303 {
1304  if (out->rect_float) {
1305  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
1307  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1309  fac, context->rectx, total_lines, rect1, rect2, seq->blend_mode, rect_out);
1310  }
1311  else {
1312  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
1314  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1316  fac, context->rectx, total_lines, rect1, rect2, seq->blend_mode, rect_out);
1317  }
1318 }
1319 
1322 /* -------------------------------------------------------------------- */
1327 {
1328  ColorMixVars *data;
1329 
1330  if (seq->effectdata) {
1331  MEM_freeN(seq->effectdata);
1332  }
1333  seq->effectdata = MEM_callocN(sizeof(ColorMixVars), "colormixvars");
1334  data = (ColorMixVars *)seq->effectdata;
1335  data->blend_effect = SEQ_TYPE_OVERLAY;
1336  data->factor = 1.0f;
1337 }
1338 
1340  Sequence *seq,
1341  float UNUSED(timeline_frame),
1342  float UNUSED(fac),
1343  ImBuf *ibuf1,
1344  ImBuf *ibuf2,
1345  ImBuf *UNUSED(ibuf3),
1346  int start_line,
1347  int total_lines,
1348  ImBuf *out)
1349 {
1350  float fac;
1351 
1352  ColorMixVars *data = seq->effectdata;
1353  fac = data->factor;
1354 
1355  if (out->rect_float) {
1356  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
1358  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1360  fac, context->rectx, total_lines, rect1, rect2, data->blend_effect, rect_out);
1361  }
1362  else {
1363  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
1365  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1367  fac, context->rectx, total_lines, rect1, rect2, data->blend_effect, rect_out);
1368  }
1369 }
1370 
1373 /* -------------------------------------------------------------------- */
1377 typedef struct WipeZone {
1378  float angle;
1379  int flip;
1380  int xo, yo;
1381  int width;
1382  float pythangle;
1384 
1385 static void precalc_wipe_zone(WipeZone *wipezone, WipeVars *wipe, int xo, int yo)
1386 {
1387  wipezone->flip = (wipe->angle < 0.0f);
1388  wipezone->angle = tanf(fabsf(wipe->angle));
1389  wipezone->xo = xo;
1390  wipezone->yo = yo;
1391  wipezone->width = (int)(wipe->edgeWidth * ((xo + yo) / 2.0f));
1392  wipezone->pythangle = 1.0f / sqrtf(wipezone->angle * wipezone->angle + 1.0f);
1393 }
1394 
1398 static float in_band(float width, float dist, int side, int dir)
1399 {
1400  float alpha;
1401 
1402  if (width == 0) {
1403  return (float)side;
1404  }
1405 
1406  if (width < dist) {
1407  return (float)side;
1408  }
1409 
1410  if (side == 1) {
1411  alpha = (dist + 0.5f * width) / (width);
1412  }
1413  else {
1414  alpha = (0.5f * width - dist) / (width);
1415  }
1416 
1417  if (dir == 0) {
1418  alpha = 1 - alpha;
1419  }
1420 
1421  return alpha;
1422 }
1423 
1424 static float check_zone(WipeZone *wipezone, int x, int y, Sequence *seq, float fac)
1425 {
1426  float posx, posy, hyp, hyp2, angle, hwidth, b1, b2, b3, pointdist;
1427  /* some future stuff */
1428  /* float hyp3, hyp4, b4, b5 */
1429  float temp1, temp2, temp3, temp4; /* some placeholder variables */
1430  int xo = wipezone->xo;
1431  int yo = wipezone->yo;
1432  float halfx = xo * 0.5f;
1433  float halfy = yo * 0.5f;
1434  float widthf, output = 0;
1435  WipeVars *wipe = (WipeVars *)seq->effectdata;
1436  int width;
1437 
1438  if (wipezone->flip) {
1439  x = xo - x;
1440  }
1441  angle = wipezone->angle;
1442 
1443  if (wipe->forward) {
1444  posx = fac * xo;
1445  posy = fac * yo;
1446  }
1447  else {
1448  posx = xo - fac * xo;
1449  posy = yo - fac * yo;
1450  }
1451 
1452  switch (wipe->wipetype) {
1453  case DO_SINGLE_WIPE:
1454  width = min_ii(wipezone->width, fac * yo);
1455  width = min_ii(width, yo - fac * yo);
1456 
1457  if (angle == 0.0f) {
1458  b1 = posy;
1459  b2 = y;
1460  hyp = fabsf(y - posy);
1461  }
1462  else {
1463  b1 = posy - (-angle) * posx;
1464  b2 = y - (-angle) * x;
1465  hyp = fabsf(angle * x + y + (-posy - angle * posx)) * wipezone->pythangle;
1466  }
1467 
1468  if (angle < 0) {
1469  temp1 = b1;
1470  b1 = b2;
1471  b2 = temp1;
1472  }
1473 
1474  if (wipe->forward) {
1475  if (b1 < b2) {
1476  output = in_band(width, hyp, 1, 1);
1477  }
1478  else {
1479  output = in_band(width, hyp, 0, 1);
1480  }
1481  }
1482  else {
1483  if (b1 < b2) {
1484  output = in_band(width, hyp, 0, 1);
1485  }
1486  else {
1487  output = in_band(width, hyp, 1, 1);
1488  }
1489  }
1490  break;
1491 
1492  case DO_DOUBLE_WIPE:
1493  if (!wipe->forward) {
1494  fac = 1.0f - fac; /* Go the other direction */
1495  }
1496 
1497  width = wipezone->width; /* calculate the blur width */
1498  hwidth = width * 0.5f;
1499  if (angle == 0) {
1500  b1 = posy * 0.5f;
1501  b3 = yo - posy * 0.5f;
1502  b2 = y;
1503 
1504  hyp = fabsf(y - posy * 0.5f);
1505  hyp2 = fabsf(y - (yo - posy * 0.5f));
1506  }
1507  else {
1508  b1 = posy * 0.5f - (-angle) * posx * 0.5f;
1509  b3 = (yo - posy * 0.5f) - (-angle) * (xo - posx * 0.5f);
1510  b2 = y - (-angle) * x;
1511 
1512  hyp = fabsf(angle * x + y + (-posy * 0.5f - angle * posx * 0.5f)) * wipezone->pythangle;
1513  hyp2 = fabsf(angle * x + y + (-(yo - posy * 0.5f) - angle * (xo - posx * 0.5f))) *
1514  wipezone->pythangle;
1515  }
1516 
1517  hwidth = min_ff(hwidth, fabsf(b3 - b1) / 2.0f);
1518 
1519  if (b2 < b1 && b2 < b3) {
1520  output = in_band(hwidth, hyp, 0, 1);
1521  }
1522  else if (b2 > b1 && b2 > b3) {
1523  output = in_band(hwidth, hyp2, 0, 1);
1524  }
1525  else {
1526  if (hyp < hwidth && hyp2 > hwidth) {
1527  output = in_band(hwidth, hyp, 1, 1);
1528  }
1529  else if (hyp > hwidth && hyp2 < hwidth) {
1530  output = in_band(hwidth, hyp2, 1, 1);
1531  }
1532  else {
1533  output = in_band(hwidth, hyp2, 1, 1) * in_band(hwidth, hyp, 1, 1);
1534  }
1535  }
1536  if (!wipe->forward) {
1537  output = 1 - output;
1538  }
1539  break;
1540  case DO_CLOCK_WIPE:
1541  /*
1542  * temp1: angle of effect center in rads
1543  * temp2: angle of line through (halfx, halfy) and (x, y) in rads
1544  * temp3: angle of low side of blur
1545  * temp4: angle of high side of blur
1546  */
1547  output = 1.0f - fac;
1548  widthf = wipe->edgeWidth * 2.0f * (float)M_PI;
1549  temp1 = 2.0f * (float)M_PI * fac;
1550 
1551  if (wipe->forward) {
1552  temp1 = 2.0f * (float)M_PI - temp1;
1553  }
1554 
1555  x = x - halfx;
1556  y = y - halfy;
1557 
1558  temp2 = asin(abs(y) / hypot(x, y));
1559  if (x <= 0 && y >= 0) {
1560  temp2 = (float)M_PI - temp2;
1561  }
1562  else if (x <= 0 && y <= 0) {
1563  temp2 += (float)M_PI;
1564  }
1565  else if (x >= 0 && y <= 0) {
1566  temp2 = 2.0f * (float)M_PI - temp2;
1567  }
1568 
1569  if (wipe->forward) {
1570  temp3 = temp1 - (widthf * 0.5f) * fac;
1571  temp4 = temp1 + (widthf * 0.5f) * (1 - fac);
1572  }
1573  else {
1574  temp3 = temp1 - (widthf * 0.5f) * (1 - fac);
1575  temp4 = temp1 + (widthf * 0.5f) * fac;
1576  }
1577  if (temp3 < 0) {
1578  temp3 = 0;
1579  }
1580  if (temp4 > 2.0f * (float)M_PI) {
1581  temp4 = 2.0f * (float)M_PI;
1582  }
1583 
1584  if (temp2 < temp3) {
1585  output = 0;
1586  }
1587  else if (temp2 > temp4) {
1588  output = 1;
1589  }
1590  else {
1591  output = (temp2 - temp3) / (temp4 - temp3);
1592  }
1593  if (x == 0 && y == 0) {
1594  output = 1;
1595  }
1596  if (output != output) {
1597  output = 1;
1598  }
1599  if (wipe->forward) {
1600  output = 1 - output;
1601  }
1602  break;
1603  case DO_IRIS_WIPE:
1604  if (xo > yo) {
1605  yo = xo;
1606  }
1607  else {
1608  xo = yo;
1609  }
1610 
1611  if (!wipe->forward) {
1612  fac = 1 - fac;
1613  }
1614 
1615  width = wipezone->width;
1616  hwidth = width * 0.5f;
1617 
1618  temp1 = (halfx - (halfx)*fac);
1619  pointdist = hypotf(temp1, temp1);
1620 
1621  temp2 = hypotf(halfx - x, halfy - y);
1622  if (temp2 > pointdist) {
1623  output = in_band(hwidth, fabsf(temp2 - pointdist), 0, 1);
1624  }
1625  else {
1626  output = in_band(hwidth, fabsf(temp2 - pointdist), 1, 1);
1627  }
1628 
1629  if (!wipe->forward) {
1630  output = 1 - output;
1631  }
1632 
1633  break;
1634  }
1635  if (output < 0) {
1636  output = 0;
1637  }
1638  else if (output > 1) {
1639  output = 1;
1640  }
1641  return output;
1642 }
1643 
1644 static void init_wipe_effect(Sequence *seq)
1645 {
1646  if (seq->effectdata) {
1647  MEM_freeN(seq->effectdata);
1648  }
1649 
1650  seq->effectdata = MEM_callocN(sizeof(WipeVars), "wipevars");
1651 }
1652 
1653 static int num_inputs_wipe(void)
1654 {
1655  return 2;
1656 }
1657 
1658 static void free_wipe_effect(Sequence *seq, const bool UNUSED(do_id_user))
1659 {
1660  MEM_SAFE_FREE(seq->effectdata);
1661 }
1662 
1663 static void copy_wipe_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
1664 {
1665  dst->effectdata = MEM_dupallocN(src->effectdata);
1666 }
1667 
1669  float fac,
1670  int x,
1671  int y,
1672  unsigned char *rect1,
1673  unsigned char *rect2,
1674  unsigned char *out)
1675 {
1676  WipeZone wipezone;
1677  WipeVars *wipe = (WipeVars *)seq->effectdata;
1678  precalc_wipe_zone(&wipezone, wipe, x, y);
1679 
1680  unsigned char *cp1 = rect1;
1681  unsigned char *cp2 = rect2;
1682  unsigned char *rt = out;
1683 
1684  for (int i = 0; i < y; i++) {
1685  for (int j = 0; j < x; j++) {
1686  float check = check_zone(&wipezone, j, i, seq, fac);
1687  if (check) {
1688  if (cp1) {
1689  float rt1[4], rt2[4], tempc[4];
1690 
1693 
1694  tempc[0] = rt1[0] * check + rt2[0] * (1 - check);
1695  tempc[1] = rt1[1] * check + rt2[1] * (1 - check);
1696  tempc[2] = rt1[2] * check + rt2[2] * (1 - check);
1697  tempc[3] = rt1[3] * check + rt2[3] * (1 - check);
1698 
1699  premul_float_to_straight_uchar(rt, tempc);
1700  }
1701  else {
1702  rt[0] = 0;
1703  rt[1] = 0;
1704  rt[2] = 0;
1705  rt[3] = 255;
1706  }
1707  }
1708  else {
1709  if (cp2) {
1710  rt[0] = cp2[0];
1711  rt[1] = cp2[1];
1712  rt[2] = cp2[2];
1713  rt[3] = cp2[3];
1714  }
1715  else {
1716  rt[0] = 0;
1717  rt[1] = 0;
1718  rt[2] = 0;
1719  rt[3] = 255;
1720  }
1721  }
1722 
1723  rt += 4;
1724  if (cp1 != NULL) {
1725  cp1 += 4;
1726  }
1727  if (cp2 != NULL) {
1728  cp2 += 4;
1729  }
1730  }
1731  }
1732 }
1733 
1735  Sequence *seq, float fac, int x, int y, float *rect1, float *rect2, float *out)
1736 {
1737  WipeZone wipezone;
1738  WipeVars *wipe = (WipeVars *)seq->effectdata;
1739  precalc_wipe_zone(&wipezone, wipe, x, y);
1740 
1741  float *rt1 = rect1;
1742  float *rt2 = rect2;
1743  float *rt = out;
1744 
1745  for (int i = 0; i < y; i++) {
1746  for (int j = 0; j < x; j++) {
1747  float check = check_zone(&wipezone, j, i, seq, fac);
1748  if (check) {
1749  if (rt1) {
1750  rt[0] = rt1[0] * check + rt2[0] * (1 - check);
1751  rt[1] = rt1[1] * check + rt2[1] * (1 - check);
1752  rt[2] = rt1[2] * check + rt2[2] * (1 - check);
1753  rt[3] = rt1[3] * check + rt2[3] * (1 - check);
1754  }
1755  else {
1756  rt[0] = 0;
1757  rt[1] = 0;
1758  rt[2] = 0;
1759  rt[3] = 1.0;
1760  }
1761  }
1762  else {
1763  if (rt2) {
1764  rt[0] = rt2[0];
1765  rt[1] = rt2[1];
1766  rt[2] = rt2[2];
1767  rt[3] = rt2[3];
1768  }
1769  else {
1770  rt[0] = 0;
1771  rt[1] = 0;
1772  rt[2] = 0;
1773  rt[3] = 1.0;
1774  }
1775  }
1776 
1777  rt += 4;
1778  if (rt1 != NULL) {
1779  rt1 += 4;
1780  }
1781  if (rt2 != NULL) {
1782  rt2 += 4;
1783  }
1784  }
1785  }
1786 }
1787 
1789  Sequence *seq,
1790  float UNUSED(timeline_frame),
1791  float fac,
1792  ImBuf *ibuf1,
1793  ImBuf *ibuf2,
1794  ImBuf *ibuf3)
1795 {
1796  ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
1797 
1798  if (out->rect_float) {
1800  fac,
1801  context->rectx,
1802  context->recty,
1803  ibuf1->rect_float,
1804  ibuf2->rect_float,
1805  out->rect_float);
1806  }
1807  else {
1808  do_wipe_effect_byte(seq,
1809  fac,
1810  context->rectx,
1811  context->recty,
1812  (unsigned char *)ibuf1->rect,
1813  (unsigned char *)ibuf2->rect,
1814  (unsigned char *)out->rect);
1815  }
1816 
1817  return out;
1818 }
1819 
1822 /* -------------------------------------------------------------------- */
1827 {
1829 
1830  if (seq->effectdata) {
1831  MEM_freeN(seq->effectdata);
1832  }
1833 
1834  seq->effectdata = MEM_callocN(sizeof(TransformVars), "transformvars");
1835 
1837 
1838  transform->ScalexIni = 1.0f;
1839  transform->ScaleyIni = 1.0f;
1840 
1841  transform->xIni = 0.0f;
1842  transform->yIni = 0.0f;
1843 
1844  transform->rotIni = 0.0f;
1845 
1846  transform->interpolation = 1;
1847  transform->percent = 1;
1848  transform->uniform_scale = 0;
1849 }
1850 
1851 static int num_inputs_transform(void)
1852 {
1853  return 1;
1854 }
1855 
1856 static void free_transform_effect(Sequence *seq, const bool UNUSED(do_id_user))
1857 {
1858  MEM_SAFE_FREE(seq->effectdata);
1859 }
1860 
1861 static void copy_transform_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
1862 {
1863  dst->effectdata = MEM_dupallocN(src->effectdata);
1864 }
1865 
1866 static void transform_image(int x,
1867  int y,
1868  int start_line,
1869  int total_lines,
1870  ImBuf *ibuf1,
1871  ImBuf *out,
1872  float scale_x,
1873  float scale_y,
1874  float translate_x,
1875  float translate_y,
1876  float rotate,
1877  int interpolation)
1878 {
1879  /* Rotate */
1880  float s = sinf(rotate);
1881  float c = cosf(rotate);
1882 
1883  for (int yi = start_line; yi < start_line + total_lines; yi++) {
1884  for (int xi = 0; xi < x; xi++) {
1885  /* Translate point. */
1886  float xt = xi - translate_x;
1887  float yt = yi - translate_y;
1888 
1889  /* Rotate point with center ref. */
1890  float xr = c * xt + s * yt;
1891  float yr = -s * xt + c * yt;
1892 
1893  /* Scale point with center ref. */
1894  xt = xr / scale_x;
1895  yt = yr / scale_y;
1896 
1897  /* Undo reference center point. */
1898  xt += (x / 2.0f);
1899  yt += (y / 2.0f);
1900 
1901  /* interpolate */
1902  switch (interpolation) {
1903  case 0:
1904  nearest_interpolation(ibuf1, out, xt, yt, xi, yi);
1905  break;
1906  case 1:
1907  bilinear_interpolation(ibuf1, out, xt, yt, xi, yi);
1908  break;
1909  case 2:
1910  bicubic_interpolation(ibuf1, out, xt, yt, xi, yi);
1911  break;
1912  }
1913  }
1914  }
1915 }
1916 
1918  Sequence *seq,
1919  float UNUSED(timeline_frame),
1920  float UNUSED(fac),
1921  ImBuf *ibuf1,
1922  ImBuf *UNUSED(ibuf2),
1923  ImBuf *UNUSED(ibuf3),
1924  int start_line,
1925  int total_lines,
1926  ImBuf *out)
1927 {
1929  float scale_x, scale_y, translate_x, translate_y, rotate_radians;
1930 
1931  /* Scale */
1932  if (transform->uniform_scale) {
1933  scale_x = scale_y = transform->ScalexIni;
1934  }
1935  else {
1936  scale_x = transform->ScalexIni;
1937  scale_y = transform->ScaleyIni;
1938  }
1939 
1940  int x = context->rectx;
1941  int y = context->recty;
1942 
1943  /* Translate */
1944  if (!transform->percent) {
1945  /* Compensate text size for preview render size. */
1946  double proxy_size_comp = context->scene->r.size / 100.0;
1947  if (context->preview_render_size != SEQ_RENDER_SIZE_SCENE) {
1948  proxy_size_comp = SEQ_rendersize_to_scale_factor(context->preview_render_size);
1949  }
1950 
1951  translate_x = transform->xIni * proxy_size_comp + (x / 2.0f);
1952  translate_y = transform->yIni * proxy_size_comp + (y / 2.0f);
1953  }
1954  else {
1955  translate_x = x * (transform->xIni / 100.0f) + (x / 2.0f);
1956  translate_y = y * (transform->yIni / 100.0f) + (y / 2.0f);
1957  }
1958 
1959  /* Rotate */
1960  rotate_radians = DEG2RADF(transform->rotIni);
1961 
1963  y,
1964  start_line,
1965  total_lines,
1966  ibuf1,
1967  out,
1968  scale_x,
1969  scale_y,
1970  translate_x,
1971  translate_y,
1972  rotate_radians,
1973  transform->interpolation);
1974 }
1975 
1978 /* -------------------------------------------------------------------- */
1982 static void RVBlurBitmap2_float(float *map, int width, int height, float blur, int quality)
1983 {
1984  /* Much better than the previous blur!
1985  * We do the blurring in two passes which is a whole lot faster.
1986  * I changed the math around to implement an actual Gaussian distribution.
1987  *
1988  * Watch out though, it tends to misbehave with large blur values on
1989  * a small bitmap. Avoid! */
1990 
1991  float *temp = NULL, *swap;
1992  float *filter = NULL;
1993  int x, y, i, fx, fy;
1994  int index, ix, halfWidth;
1995  float fval, k, curColor[4], curColor2[4], weight = 0;
1996 
1997  /* If we're not really blurring, bail out */
1998  if (blur <= 0) {
1999  return;
2000  }
2001 
2002  /* If result would be no blurring, early out. */
2003  halfWidth = ((quality + 1) * blur);
2004  if (halfWidth == 0) {
2005  return;
2006  }
2007 
2008  /* Allocate memory for the tempmap and the blur filter matrix */
2009  temp = MEM_mallocN(sizeof(float[4]) * width * height, "blurbitmaptemp");
2010  if (!temp) {
2011  return;
2012  }
2013 
2014  /* Allocate memory for the filter elements */
2015  filter = (float *)MEM_mallocN(sizeof(float) * halfWidth * 2, "blurbitmapfilter");
2016  if (!filter) {
2017  MEM_freeN(temp);
2018  return;
2019  }
2020 
2021  /* Apparently we're calculating a bell curve based on the standard deviation (or radius)
2022  * This code is based on an example posted to comp.graphics.algorithms by
2023  * Blancmange <bmange@airdmhor.gen.nz>
2024  */
2025 
2026  k = -1.0f / (2.0f * (float)M_PI * blur * blur);
2027 
2028  for (ix = 0; ix < halfWidth; ix++) {
2029  weight = (float)exp(k * (ix * ix));
2030  filter[halfWidth - ix] = weight;
2031  filter[halfWidth + ix] = weight;
2032  }
2033  filter[0] = weight;
2034 
2035  /* Normalize the array */
2036  fval = 0;
2037  for (ix = 0; ix < halfWidth * 2; ix++) {
2038  fval += filter[ix];
2039  }
2040 
2041  for (ix = 0; ix < halfWidth * 2; ix++) {
2042  filter[ix] /= fval;
2043  }
2044 
2045  /* Blur the rows */
2046  for (y = 0; y < height; y++) {
2047  /* Do the left & right strips */
2048  for (x = 0; x < halfWidth; x++) {
2049  fx = 0;
2050  zero_v4(curColor);
2051  zero_v4(curColor2);
2052 
2053  for (i = x - halfWidth; i < x + halfWidth; i++) {
2054  if ((i >= 0) && (i < width)) {
2055  index = (i + y * width) * 4;
2056  madd_v4_v4fl(curColor, map + index, filter[fx]);
2057 
2058  index = (width - 1 - i + y * width) * 4;
2059  madd_v4_v4fl(curColor2, map + index, filter[fx]);
2060  }
2061  fx++;
2062  }
2063  index = (x + y * width) * 4;
2064  copy_v4_v4(temp + index, curColor);
2065 
2066  index = (width - 1 - x + y * width) * 4;
2067  copy_v4_v4(temp + index, curColor2);
2068  }
2069 
2070  /* Do the main body */
2071  for (x = halfWidth; x < width - halfWidth; x++) {
2072  fx = 0;
2073  zero_v4(curColor);
2074  for (i = x - halfWidth; i < x + halfWidth; i++) {
2075  index = (i + y * width) * 4;
2076  madd_v4_v4fl(curColor, map + index, filter[fx]);
2077  fx++;
2078  }
2079  index = (x + y * width) * 4;
2080  copy_v4_v4(temp + index, curColor);
2081  }
2082  }
2083 
2084  /* Swap buffers */
2085  swap = temp;
2086  temp = map;
2087  map = swap;
2088 
2089  /* Blur the columns */
2090  for (x = 0; x < width; x++) {
2091  /* Do the top & bottom strips */
2092  for (y = 0; y < halfWidth; y++) {
2093  fy = 0;
2094  zero_v4(curColor);
2095  zero_v4(curColor2);
2096  for (i = y - halfWidth; i < y + halfWidth; i++) {
2097  if ((i >= 0) && (i < height)) {
2098  /* Bottom */
2099  index = (x + i * width) * 4;
2100  madd_v4_v4fl(curColor, map + index, filter[fy]);
2101 
2102  /* Top */
2103  index = (x + (height - 1 - i) * width) * 4;
2104  madd_v4_v4fl(curColor2, map + index, filter[fy]);
2105  }
2106  fy++;
2107  }
2108  index = (x + y * width) * 4;
2109  copy_v4_v4(temp + index, curColor);
2110 
2111  index = (x + (height - 1 - y) * width) * 4;
2112  copy_v4_v4(temp + index, curColor2);
2113  }
2114 
2115  /* Do the main body */
2116  for (y = halfWidth; y < height - halfWidth; y++) {
2117  fy = 0;
2118  zero_v4(curColor);
2119  for (i = y - halfWidth; i < y + halfWidth; i++) {
2120  index = (x + i * width) * 4;
2121  madd_v4_v4fl(curColor, map + index, filter[fy]);
2122  fy++;
2123  }
2124  index = (x + y * width) * 4;
2125  copy_v4_v4(temp + index, curColor);
2126  }
2127  }
2128 
2129  /* Swap buffers */
2130  swap = temp;
2131  temp = map; /* map = swap; */ /* UNUSED */
2132 
2133  /* Tidy up. */
2134  MEM_freeN(filter);
2135  MEM_freeN(temp);
2136 }
2137 
2138 static void RVAddBitmaps_float(float *a, float *b, float *c, int width, int height)
2139 {
2140  int x, y, index;
2141 
2142  for (y = 0; y < height; y++) {
2143  for (x = 0; x < width; x++) {
2144  index = (x + y * width) * 4;
2145  c[index + GlowR] = min_ff(1.0f, a[index + GlowR] + b[index + GlowR]);
2146  c[index + GlowG] = min_ff(1.0f, a[index + GlowG] + b[index + GlowG]);
2147  c[index + GlowB] = min_ff(1.0f, a[index + GlowB] + b[index + GlowB]);
2148  c[index + GlowA] = min_ff(1.0f, a[index + GlowA] + b[index + GlowA]);
2149  }
2150  }
2151 }
2152 
2154  const float *in, float *out, int width, int height, float threshold, float boost, float clamp)
2155 {
2156  int x, y, index;
2157  float intensity;
2158 
2159  for (y = 0; y < height; y++) {
2160  for (x = 0; x < width; x++) {
2161  index = (x + y * width) * 4;
2162 
2163  /* Isolate the intensity */
2164  intensity = (in[index + GlowR] + in[index + GlowG] + in[index + GlowB] - threshold);
2165  if (intensity > 0) {
2166  out[index + GlowR] = min_ff(clamp, (in[index + GlowR] * boost * intensity));
2167  out[index + GlowG] = min_ff(clamp, (in[index + GlowG] * boost * intensity));
2168  out[index + GlowB] = min_ff(clamp, (in[index + GlowB] * boost * intensity));
2169  out[index + GlowA] = min_ff(clamp, (in[index + GlowA] * boost * intensity));
2170  }
2171  else {
2172  out[index + GlowR] = 0;
2173  out[index + GlowG] = 0;
2174  out[index + GlowB] = 0;
2175  out[index + GlowA] = 0;
2176  }
2177  }
2178  }
2179 }
2180 
2181 static void init_glow_effect(Sequence *seq)
2182 {
2183  GlowVars *glow;
2184 
2185  if (seq->effectdata) {
2186  MEM_freeN(seq->effectdata);
2187  }
2188 
2189  seq->effectdata = MEM_callocN(sizeof(GlowVars), "glowvars");
2190 
2191  glow = (GlowVars *)seq->effectdata;
2192  glow->fMini = 0.25;
2193  glow->fClamp = 1.0;
2194  glow->fBoost = 0.5;
2195  glow->dDist = 3.0;
2196  glow->dQuality = 3;
2197  glow->bNoComp = 0;
2198 }
2199 
2200 static int num_inputs_glow(void)
2201 {
2202  return 1;
2203 }
2204 
2205 static void free_glow_effect(Sequence *seq, const bool UNUSED(do_id_user))
2206 {
2207  MEM_SAFE_FREE(seq->effectdata);
2208 }
2209 
2210 static void copy_glow_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
2211 {
2212  dst->effectdata = MEM_dupallocN(src->effectdata);
2213 }
2214 
2216  int render_size,
2217  float fac,
2218  int x,
2219  int y,
2220  unsigned char *rect1,
2221  unsigned char *UNUSED(rect2),
2222  unsigned char *out)
2223 {
2224  float *outbuf, *inbuf;
2225  GlowVars *glow = (GlowVars *)seq->effectdata;
2226 
2227  inbuf = MEM_mallocN(sizeof(float[4]) * x * y, "glow effect input");
2228  outbuf = MEM_mallocN(sizeof(float[4]) * x * y, "glow effect output");
2229 
2230  IMB_buffer_float_from_byte(inbuf, rect1, IB_PROFILE_SRGB, IB_PROFILE_SRGB, false, x, y, x, x);
2231  IMB_buffer_float_premultiply(inbuf, x, y);
2232 
2234  inbuf, outbuf, x, y, glow->fMini * 3.0f, glow->fBoost * fac, glow->fClamp);
2235  RVBlurBitmap2_float(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality);
2236  if (!glow->bNoComp) {
2237  RVAddBitmaps_float(inbuf, outbuf, outbuf, x, y);
2238  }
2239 
2242  out, outbuf, 4, 0.0f, IB_PROFILE_SRGB, IB_PROFILE_SRGB, false, x, y, x, x);
2243 
2244  MEM_freeN(inbuf);
2245  MEM_freeN(outbuf);
2246 }
2247 
2249  int render_size,
2250  float fac,
2251  int x,
2252  int y,
2253  float *rect1,
2254  float *UNUSED(rect2),
2255  float *out)
2256 {
2257  float *outbuf = out;
2258  float *inbuf = rect1;
2259  GlowVars *glow = (GlowVars *)seq->effectdata;
2260 
2262  inbuf, outbuf, x, y, glow->fMini * 3.0f, glow->fBoost * fac, glow->fClamp);
2263  RVBlurBitmap2_float(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality);
2264  if (!glow->bNoComp) {
2265  RVAddBitmaps_float(inbuf, outbuf, outbuf, x, y);
2266  }
2267 }
2268 
2270  Sequence *seq,
2271  float UNUSED(timeline_frame),
2272  float fac,
2273  ImBuf *ibuf1,
2274  ImBuf *ibuf2,
2275  ImBuf *ibuf3)
2276 {
2277  ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2278 
2279  int render_size = 100 * context->rectx / context->scene->r.xsch;
2280 
2281  if (out->rect_float) {
2283  render_size,
2284  fac,
2285  context->rectx,
2286  context->recty,
2287  ibuf1->rect_float,
2288  NULL,
2289  out->rect_float);
2290  }
2291  else {
2292  do_glow_effect_byte(seq,
2293  render_size,
2294  fac,
2295  context->rectx,
2296  context->recty,
2297  (unsigned char *)ibuf1->rect,
2298  NULL,
2299  (unsigned char *)out->rect);
2300  }
2301 
2302  return out;
2303 }
2304 
2307 /* -------------------------------------------------------------------- */
2311 static void init_solid_color(Sequence *seq)
2312 {
2313  SolidColorVars *cv;
2314 
2315  if (seq->effectdata) {
2316  MEM_freeN(seq->effectdata);
2317  }
2318 
2319  seq->effectdata = MEM_callocN(sizeof(SolidColorVars), "solidcolor");
2320 
2321  cv = (SolidColorVars *)seq->effectdata;
2322  cv->col[0] = cv->col[1] = cv->col[2] = 0.5;
2323 }
2324 
2325 static int num_inputs_color(void)
2326 {
2327  return 0;
2328 }
2329 
2330 static void free_solid_color(Sequence *seq, const bool UNUSED(do_id_user))
2331 {
2332  MEM_SAFE_FREE(seq->effectdata);
2333 }
2334 
2335 static void copy_solid_color(Sequence *dst, Sequence *src, const int UNUSED(flag))
2336 {
2337  dst->effectdata = MEM_dupallocN(src->effectdata);
2338 }
2339 
2340 static int early_out_color(Sequence *UNUSED(seq), float UNUSED(fac))
2341 {
2342  return EARLY_NO_INPUT;
2343 }
2344 
2346  Sequence *seq,
2347  float UNUSED(timeline_frame),
2348  float UNUSED(fac),
2349  ImBuf *ibuf1,
2350  ImBuf *ibuf2,
2351  ImBuf *ibuf3)
2352 {
2353  ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2354 
2356 
2357  int x = out->x;
2358  int y = out->y;
2359 
2360  if (out->rect) {
2361  unsigned char color[4];
2362  color[0] = cv->col[0] * 255;
2363  color[1] = cv->col[1] * 255;
2364  color[2] = cv->col[2] * 255;
2365  color[3] = 255;
2366 
2367  unsigned char *rect = (unsigned char *)out->rect;
2368 
2369  for (int i = 0; i < y; i++) {
2370  for (int j = 0; j < x; j++) {
2371  rect[0] = color[0];
2372  rect[1] = color[1];
2373  rect[2] = color[2];
2374  rect[3] = color[3];
2375  rect += 4;
2376  }
2377  }
2378  }
2379  else if (out->rect_float) {
2380  float color[4];
2381  color[0] = cv->col[0];
2382  color[1] = cv->col[1];
2383  color[2] = cv->col[2];
2384  color[3] = 255;
2385 
2386  float *rect_float = out->rect_float;
2387 
2388  for (int i = 0; i < y; i++) {
2389  for (int j = 0; j < x; j++) {
2390  rect_float[0] = color[0];
2391  rect_float[1] = color[1];
2392  rect_float[2] = color[2];
2393  rect_float[3] = color[3];
2394  rect_float += 4;
2395  }
2396  }
2397  }
2398 
2399  out->planes = R_IMF_PLANES_RGB;
2400 
2401  return out;
2402 }
2403 
2406 /* -------------------------------------------------------------------- */
2411 static int num_inputs_multicam(void)
2412 {
2413  return 0;
2414 }
2415 
2416 static int early_out_multicam(Sequence *UNUSED(seq), float UNUSED(fac))
2417 {
2418  return EARLY_NO_INPUT;
2419 }
2420 
2422  Sequence *seq,
2423  float timeline_frame,
2424  float UNUSED(fac),
2425  ImBuf *UNUSED(ibuf1),
2426  ImBuf *UNUSED(ibuf2),
2427  ImBuf *UNUSED(ibuf3))
2428 {
2429  ImBuf *out;
2430  Editing *ed;
2431 
2432  if (seq->multicam_source == 0 || seq->multicam_source >= seq->machine) {
2433  return NULL;
2434  }
2435 
2436  ed = context->scene->ed;
2437  if (!ed) {
2438  return NULL;
2439  }
2440  ListBase *seqbasep = SEQ_get_seqbase_by_seq(context->scene, seq);
2442  if (!seqbasep) {
2443  return NULL;
2444  }
2445 
2447  context, timeline_frame, seq->multicam_source, channels, seqbasep);
2448 
2449  return out;
2450 }
2451 
2454 /* -------------------------------------------------------------------- */
2459 static int num_inputs_adjustment(void)
2460 {
2461  return 0;
2462 }
2463 
2464 static int early_out_adjustment(Sequence *UNUSED(seq), float UNUSED(fac))
2465 {
2466  return EARLY_NO_INPUT;
2467 }
2468 
2469 static ImBuf *do_adjustment_impl(const SeqRenderData *context, Sequence *seq, float timeline_frame)
2470 {
2471  Editing *ed;
2472  ImBuf *i = NULL;
2473 
2474  ed = context->scene->ed;
2475 
2476  ListBase *seqbasep = SEQ_get_seqbase_by_seq(context->scene, seq);
2478 
2479  /* Clamp timeline_frame to strip range so it behaves as if it had "still frame" offset (last
2480  * frame is static after end of strip). This is how most strips behave. This way transition
2481  * effects that doesn't overlap or speed effect can't fail rendering outside of strip range. */
2482  timeline_frame = clamp_i(timeline_frame,
2484  SEQ_time_right_handle_frame_get(context->scene, seq) - 1);
2485 
2486  if (seq->machine > 1) {
2488  context, timeline_frame, seq->machine - 1, channels, seqbasep);
2489  }
2490 
2491  /* Found nothing? so let's work the way up the meta-strip stack, so
2492  * that it is possible to group a bunch of adjustment strips into
2493  * a meta-strip and have that work on everything below the meta-strip. */
2494 
2495  if (!i) {
2496  Sequence *meta;
2497 
2498  meta = SEQ_find_metastrip_by_sequence(&ed->seqbase, NULL, seq);
2499 
2500  if (meta) {
2501  i = do_adjustment_impl(context, meta, timeline_frame);
2502  }
2503  }
2504 
2505  return i;
2506 }
2507 
2509  Sequence *seq,
2510  float timeline_frame,
2511  float UNUSED(fac),
2512  ImBuf *UNUSED(ibuf1),
2513  ImBuf *UNUSED(ibuf2),
2514  ImBuf *UNUSED(ibuf3))
2515 {
2516  ImBuf *out;
2517  Editing *ed;
2518 
2519  ed = context->scene->ed;
2520 
2521  if (!ed) {
2522  return NULL;
2523  }
2524 
2525  out = do_adjustment_impl(context, seq, timeline_frame);
2526 
2527  return out;
2528 }
2529 
2532 /* -------------------------------------------------------------------- */
2536 static void init_speed_effect(Sequence *seq)
2537 {
2539 
2540  if (seq->effectdata) {
2541  MEM_freeN(seq->effectdata);
2542  }
2543 
2544  seq->effectdata = MEM_callocN(sizeof(SpeedControlVars), "speedcontrolvars");
2545 
2546  v = (SpeedControlVars *)seq->effectdata;
2547  v->speed_control_type = SEQ_SPEED_STRETCH;
2548  v->speed_fader = 1.0f;
2549  v->speed_fader_length = 0.0f;
2550  v->speed_fader_frame_number = 0.0f;
2551 }
2552 
2553 static void load_speed_effect(Sequence *seq)
2554 {
2556  v->frameMap = NULL;
2557 }
2558 
2559 static int num_inputs_speed(void)
2560 {
2561  return 1;
2562 }
2563 
2564 static void free_speed_effect(Sequence *seq, const bool UNUSED(do_id_user))
2565 {
2567  if (v->frameMap) {
2568  MEM_freeN(v->frameMap);
2569  }
2570  MEM_SAFE_FREE(seq->effectdata);
2571 }
2572 
2573 static void copy_speed_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
2574 {
2576  dst->effectdata = MEM_dupallocN(src->effectdata);
2577  v = (SpeedControlVars *)dst->effectdata;
2578  v->frameMap = NULL;
2579 }
2580 
2581 static int early_out_speed(Sequence *UNUSED(seq), float UNUSED(fac))
2582 {
2583  return EARLY_DO_EFFECT;
2584 }
2585 
2587 {
2588  return id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0, NULL);
2589 }
2590 
2592 {
2593  const int effect_strip_length = SEQ_time_right_handle_frame_get(scene, seq) -
2595 
2596  if ((seq->seq1 == NULL) || (effect_strip_length < 1)) {
2597  return; /* Make coverity happy and check for (CID 598) input strip... */
2598  }
2599 
2601  if (fcu == NULL) {
2602  return;
2603  }
2604 
2606  if (v->frameMap) {
2607  MEM_freeN(v->frameMap);
2608  }
2609 
2610  v->frameMap = MEM_mallocN(sizeof(float) * effect_strip_length, __func__);
2611  v->frameMap[0] = 0.0f;
2612 
2613  float target_frame = 0;
2614  for (int frame_index = 1; frame_index < effect_strip_length; frame_index++) {
2615  target_frame += evaluate_fcurve(fcu, SEQ_time_left_handle_frame_get(scene, seq) + frame_index);
2616  const int target_frame_max = SEQ_time_strip_length_get(scene, seq->seq1);
2617  CLAMP(target_frame, 0, target_frame_max);
2618  v->frameMap[frame_index] = target_frame;
2619  }
2620 }
2621 
2623 {
2625  if (v->frameMap != NULL) {
2626  return;
2627  }
2628 
2630 }
2631 
2633  Sequence *seq_speed,
2634  float timeline_frame,
2635  int input)
2636 {
2637  if (seq_speed->seq1 == NULL) {
2638  return 0.0f;
2639  }
2640 
2641  SEQ_effect_handle_get(seq_speed); /* Ensure, that data are initialized. */
2642  int frame_index = seq_give_frame_index(scene, seq_speed, timeline_frame);
2643  SpeedControlVars *s = (SpeedControlVars *)seq_speed->effectdata;
2644  const Sequence *source = seq_speed->seq1;
2645 
2646  float target_frame = 0.0f;
2647  switch (s->speed_control_type) {
2648  case SEQ_SPEED_STRETCH: {
2649  /* Only right handle controls effect speed! */
2650  const float target_content_length = SEQ_time_strip_length_get(scene, source) -
2651  source->startofs;
2652  const float speed_effetct_length = SEQ_time_right_handle_frame_get(scene, seq_speed) -
2654  const float ratio = frame_index / speed_effetct_length;
2655  target_frame = target_content_length * ratio;
2656  break;
2657  }
2658  case SEQ_SPEED_MULTIPLY: {
2660  if (fcu != NULL) {
2662  target_frame = s->frameMap[frame_index];
2663  }
2664  else {
2665  target_frame = frame_index * s->speed_fader;
2666  }
2667  break;
2668  }
2669  case SEQ_SPEED_LENGTH:
2670  target_frame = SEQ_time_strip_length_get(scene, source) * (s->speed_fader_length / 100.0f);
2671  break;
2673  target_frame = s->speed_fader_frame_number;
2674  break;
2675  }
2676 
2677  CLAMP(target_frame, 0, SEQ_time_strip_length_get(scene, source));
2678  target_frame += seq_speed->start;
2679 
2680  /* No interpolation. */
2681  if ((s->flags & SEQ_SPEED_USE_INTERPOLATION) == 0) {
2682  return target_frame;
2683  }
2684 
2685  /* Interpolation is used, switch between current and next frame based on which input is
2686  * requested. */
2687  return input == 0 ? target_frame : ceil(target_frame);
2688 }
2689 
2691  Sequence *seq_speed,
2692  float timeline_frame)
2693 {
2694  const float target_frame = seq_speed_effect_target_frame_get(
2695  scene, seq_speed, timeline_frame, 0);
2696  return target_frame - floor(target_frame);
2697 }
2698 
2700  Sequence *seq,
2701  float timeline_frame,
2702  float fac,
2703  ImBuf *ibuf1,
2704  ImBuf *ibuf2,
2705  ImBuf *ibuf3)
2706 {
2709  ImBuf *out;
2710 
2712  fac = speed_effect_interpolation_ratio_get(context->scene, seq, timeline_frame);
2713  /* Current frame is ibuf1, next frame is ibuf2. */
2715  &cross_effect, context, NULL, timeline_frame, fac, ibuf1, ibuf2, ibuf3);
2716  return out;
2717  }
2718 
2719  /* No interpolation. */
2720  return IMB_dupImBuf(ibuf1);
2721 }
2722 
2725 /* -------------------------------------------------------------------- */
2730  Sequence *UNUSED(seq),
2731  float UNUSED(timeline_frame),
2732  float fac,
2733  ImBuf *ibuf1,
2734  ImBuf *ibuf2,
2735  ImBuf *UNUSED(ibuf3),
2736  int start_line,
2737  int total_lines,
2738  ImBuf *out)
2739 {
2740  int x = context->rectx;
2741  int y = total_lines;
2742 
2743  if (out->rect_float) {
2744  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
2745 
2747  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
2748 
2749  do_drop_effect_float(fac, x, y, rect1, rect2, rect_out);
2750  do_alphaover_effect_float(fac, x, y, rect1, rect2, rect_out);
2751  }
2752  else {
2753  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
2754 
2756  context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
2757 
2758  do_drop_effect_byte(fac, x, y, rect1, rect2, rect_out);
2759  do_alphaover_effect_byte(fac, x, y, rect1, rect2, rect_out);
2760  }
2761 }
2762 
2765 /* -------------------------------------------------------------------- */
2769 /* NOTE: This gaussian blur implementation accumulates values in the square
2770  * kernel rather that doing X direction and then Y direction because of the
2771  * lack of using multiple-staged filters.
2772  *
2773  * Once we can we'll implement a way to apply filter as multiple stages we
2774  * can optimize hell of a lot in here.
2775  */
2776 
2778 {
2779  if (seq->effectdata) {
2780  MEM_freeN(seq->effectdata);
2781  }
2782 
2783  seq->effectdata = MEM_callocN(sizeof(WipeVars), "wipevars");
2784 }
2785 
2787 {
2788  return 1;
2789 }
2790 
2791 static void free_gaussian_blur_effect(Sequence *seq, const bool UNUSED(do_id_user))
2792 {
2793  MEM_SAFE_FREE(seq->effectdata);
2794 }
2795 
2796 static void copy_gaussian_blur_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
2797 {
2798  dst->effectdata = MEM_dupallocN(src->effectdata);
2799 }
2800 
2801 static int early_out_gaussian_blur(Sequence *seq, float UNUSED(fac))
2802 {
2804  if (data->size_x == 0.0f && data->size_y == 0) {
2805  return EARLY_USE_INPUT_1;
2806  }
2807  return EARLY_DO_EFFECT;
2808 }
2809 
2810 /* TODO(sergey): De-duplicate with compositor. */
2811 static float *make_gaussian_blur_kernel(float rad, int size)
2812 {
2813  float *gausstab, sum, val;
2814  float fac;
2815  int i, n;
2816 
2817  n = 2 * size + 1;
2818 
2819  gausstab = (float *)MEM_mallocN(sizeof(float) * n, __func__);
2820 
2821  sum = 0.0f;
2822  fac = (rad > 0.0f ? 1.0f / rad : 0.0f);
2823  for (i = -size; i <= size; i++) {
2824  val = RE_filter_value(R_FILTER_GAUSS, (float)i * fac);
2825  sum += val;
2826  gausstab[i + size] = val;
2827  }
2828 
2829  sum = 1.0f / sum;
2830  for (i = 0; i < n; i++) {
2831  gausstab[i] *= sum;
2832  }
2833 
2834  return gausstab;
2835 }
2836 
2838  int start_line,
2839  int x,
2840  int y,
2841  int frame_width,
2842  int UNUSED(frame_height),
2843  const unsigned char *rect,
2844  unsigned char *out)
2845 {
2846 #define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
2848  const int size_x = (int)(data->size_x + 0.5f);
2849  int i, j;
2850 
2851  /* Make gaussian weight table. */
2852  float *gausstab_x;
2853  gausstab_x = make_gaussian_blur_kernel(data->size_x, size_x);
2854 
2855  for (i = 0; i < y; i++) {
2856  for (j = 0; j < x; j++) {
2857  int out_index = INDEX(j, i);
2858  float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f};
2859  float accum_weight = 0.0f;
2860 
2861  for (int current_x = j - size_x; current_x <= j + size_x; current_x++) {
2862  if (current_x < 0 || current_x >= frame_width) {
2863  /* Out of bounds. */
2864  continue;
2865  }
2866  int index = INDEX(current_x, i + start_line);
2867  float weight = gausstab_x[current_x - j + size_x];
2868  accum[0] += rect[index] * weight;
2869  accum[1] += rect[index + 1] * weight;
2870  accum[2] += rect[index + 2] * weight;
2871  accum[3] += rect[index + 3] * weight;
2872  accum_weight += weight;
2873  }
2874 
2875  float inv_accum_weight = 1.0f / accum_weight;
2876  out[out_index + 0] = accum[0] * inv_accum_weight;
2877  out[out_index + 1] = accum[1] * inv_accum_weight;
2878  out[out_index + 2] = accum[2] * inv_accum_weight;
2879  out[out_index + 3] = accum[3] * inv_accum_weight;
2880  }
2881  }
2882 
2883  MEM_freeN(gausstab_x);
2884 #undef INDEX
2885 }
2886 
2888  int start_line,
2889  int x,
2890  int y,
2891  int UNUSED(frame_width),
2892  int frame_height,
2893  const unsigned char *rect,
2894  unsigned char *out)
2895 {
2896 #define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
2898  const int size_y = (int)(data->size_y + 0.5f);
2899  int i, j;
2900 
2901  /* Make gaussian weight table. */
2902  float *gausstab_y;
2903  gausstab_y = make_gaussian_blur_kernel(data->size_y, size_y);
2904 
2905  for (i = 0; i < y; i++) {
2906  for (j = 0; j < x; j++) {
2907  int out_index = INDEX(j, i);
2908  float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f};
2909  float accum_weight = 0.0f;
2910  for (int current_y = i - size_y; current_y <= i + size_y; current_y++) {
2911  if (current_y < -start_line || current_y + start_line >= frame_height) {
2912  /* Out of bounds. */
2913  continue;
2914  }
2915  int index = INDEX(j, current_y + start_line);
2916  float weight = gausstab_y[current_y - i + size_y];
2917  accum[0] += rect[index] * weight;
2918  accum[1] += rect[index + 1] * weight;
2919  accum[2] += rect[index + 2] * weight;
2920  accum[3] += rect[index + 3] * weight;
2921  accum_weight += weight;
2922  }
2923  float inv_accum_weight = 1.0f / accum_weight;
2924  out[out_index + 0] = accum[0] * inv_accum_weight;
2925  out[out_index + 1] = accum[1] * inv_accum_weight;
2926  out[out_index + 2] = accum[2] * inv_accum_weight;
2927  out[out_index + 3] = accum[3] * inv_accum_weight;
2928  }
2929  }
2930 
2931  MEM_freeN(gausstab_y);
2932 #undef INDEX
2933 }
2934 
2936  int start_line,
2937  int x,
2938  int y,
2939  int frame_width,
2940  int UNUSED(frame_height),
2941  float *rect,
2942  float *out)
2943 {
2944 #define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
2946  const int size_x = (int)(data->size_x + 0.5f);
2947  int i, j;
2948 
2949  /* Make gaussian weight table. */
2950  float *gausstab_x;
2951  gausstab_x = make_gaussian_blur_kernel(data->size_x, size_x);
2952 
2953  for (i = 0; i < y; i++) {
2954  for (j = 0; j < x; j++) {
2955  int out_index = INDEX(j, i);
2956  float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f};
2957  float accum_weight = 0.0f;
2958  for (int current_x = j - size_x; current_x <= j + size_x; current_x++) {
2959  if (current_x < 0 || current_x >= frame_width) {
2960  /* Out of bounds. */
2961  continue;
2962  }
2963  int index = INDEX(current_x, i + start_line);
2964  float weight = gausstab_x[current_x - j + size_x];
2965  madd_v4_v4fl(accum, &rect[index], weight);
2966  accum_weight += weight;
2967  }
2968  mul_v4_v4fl(&out[out_index], accum, 1.0f / accum_weight);
2969  }
2970  }
2971 
2972  MEM_freeN(gausstab_x);
2973 #undef INDEX
2974 }
2975 
2977  int start_line,
2978  int x,
2979  int y,
2980  int UNUSED(frame_width),
2981  int frame_height,
2982  float *rect,
2983  float *out)
2984 {
2985 #define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
2987  const int size_y = (int)(data->size_y + 0.5f);
2988  int i, j;
2989 
2990  /* Make gaussian weight table. */
2991  float *gausstab_y;
2992  gausstab_y = make_gaussian_blur_kernel(data->size_y, size_y);
2993 
2994  for (i = 0; i < y; i++) {
2995  for (j = 0; j < x; j++) {
2996  int out_index = INDEX(j, i);
2997  float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f};
2998  float accum_weight = 0.0f;
2999  for (int current_y = i - size_y; current_y <= i + size_y; current_y++) {
3000  if (current_y < -start_line || current_y + start_line >= frame_height) {
3001  /* Out of bounds. */
3002  continue;
3003  }
3004  int index = INDEX(j, current_y + start_line);
3005  float weight = gausstab_y[current_y - i + size_y];
3006  madd_v4_v4fl(accum, &rect[index], weight);
3007  accum_weight += weight;
3008  }
3009  mul_v4_v4fl(&out[out_index], accum, 1.0f / accum_weight);
3010  }
3011  }
3012 
3013  MEM_freeN(gausstab_y);
3014 #undef INDEX
3015 }
3016 
3018  Sequence *seq,
3019  ImBuf *ibuf,
3020  int start_line,
3021  int total_lines,
3022  ImBuf *out)
3023 {
3024  if (out->rect_float) {
3025  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
3026 
3028  context, ibuf, NULL, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
3029 
3031  start_line,
3032  context->rectx,
3033  total_lines,
3034  context->rectx,
3035  context->recty,
3036  ibuf->rect_float,
3037  rect_out);
3038  }
3039  else {
3040  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
3041 
3043  context, ibuf, NULL, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
3044 
3046  start_line,
3047  context->rectx,
3048  total_lines,
3049  context->rectx,
3050  context->recty,
3051  (unsigned char *)ibuf->rect,
3052  rect_out);
3053  }
3054 }
3055 
3057  Sequence *seq,
3058  ImBuf *ibuf,
3059  int start_line,
3060  int total_lines,
3061  ImBuf *out)
3062 {
3063  if (out->rect_float) {
3064  float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
3065 
3067  context, ibuf, NULL, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
3068 
3070  start_line,
3071  context->rectx,
3072  total_lines,
3073  context->rectx,
3074  context->recty,
3075  ibuf->rect_float,
3076  rect_out);
3077  }
3078  else {
3079  unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
3080 
3082  context, ibuf, NULL, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
3083 
3085  start_line,
3086  context->rectx,
3087  total_lines,
3088  context->rectx,
3089  context->recty,
3090  (unsigned char *)ibuf->rect,
3091  rect_out);
3092  }
3093 }
3094 
3101 
3109 
3110 static void render_effect_execute_init_handle(void *handle_v,
3111  int start_line,
3112  int tot_line,
3113  void *init_data_v)
3114 {
3117 
3118  handle->context = init_data->context;
3119  handle->seq = init_data->seq;
3120  handle->ibuf = init_data->ibuf;
3121  handle->out = init_data->out;
3122 
3123  handle->start_line = start_line;
3124  handle->tot_line = tot_line;
3125 }
3126 
3127 static void *render_effect_execute_do_x_thread(void *thread_data_v)
3128 {
3129  RenderGaussianBlurEffectThread *thread_data = (RenderGaussianBlurEffectThread *)thread_data_v;
3131  thread_data->seq,
3132  thread_data->ibuf,
3133  thread_data->start_line,
3134  thread_data->tot_line,
3135  thread_data->out);
3136  return NULL;
3137 }
3138 
3139 static void *render_effect_execute_do_y_thread(void *thread_data_v)
3140 {
3141  RenderGaussianBlurEffectThread *thread_data = (RenderGaussianBlurEffectThread *)thread_data_v;
3143  thread_data->seq,
3144  thread_data->ibuf,
3145  thread_data->start_line,
3146  thread_data->tot_line,
3147  thread_data->out);
3148 
3149  return NULL;
3150 }
3151 
3153  Sequence *seq,
3154  float UNUSED(timeline_frame),
3155  float UNUSED(fac),
3156  ImBuf *ibuf1,
3157  ImBuf *UNUSED(ibuf2),
3158  ImBuf *UNUSED(ibuf3))
3159 {
3161 
3163 
3164  init_data.context = context;
3165  init_data.seq = seq;
3166  init_data.ibuf = ibuf1;
3167  init_data.out = out;
3168 
3171  &init_data,
3174 
3175  ibuf1 = out;
3176  init_data.ibuf = ibuf1;
3178  init_data.out = out;
3179 
3182  &init_data,
3185 
3186  IMB_freeImBuf(ibuf1);
3187 
3188  return out;
3189 }
3190 
3193 /* -------------------------------------------------------------------- */
3197 static void init_text_effect(Sequence *seq)
3198 {
3199  TextVars *data;
3200 
3201  if (seq->effectdata) {
3202  MEM_freeN(seq->effectdata);
3203  }
3204 
3205  data = seq->effectdata = MEM_callocN(sizeof(TextVars), "textvars");
3206  data->text_font = NULL;
3207  data->text_blf_id = -1;
3208  data->text_size = 60.0f;
3209 
3210  copy_v4_fl(data->color, 1.0f);
3211  data->shadow_color[3] = 0.7f;
3212  data->box_color[0] = 0.2f;
3213  data->box_color[1] = 0.2f;
3214  data->box_color[2] = 0.2f;
3215  data->box_color[3] = 0.7f;
3216  data->box_margin = 0.01f;
3217 
3218  BLI_strncpy(data->text, "Text", sizeof(data->text));
3219 
3220  data->loc[0] = 0.5f;
3221  data->loc[1] = 0.5f;
3222  data->align = SEQ_TEXT_ALIGN_X_CENTER;
3223  data->align_y = SEQ_TEXT_ALIGN_Y_CENTER;
3224  data->wrap_width = 1.0f;
3225 }
3226 
3227 void SEQ_effect_text_font_unload(TextVars *data, const bool do_id_user)
3228 {
3229  if (data == NULL) {
3230  return;
3231  }
3232 
3233  /* Unlink the VFont */
3234  if (do_id_user && data->text_font != NULL) {
3235  id_us_min(&data->text_font->id);
3236  data->text_font = NULL;
3237  }
3238 
3239  /* Unload the BLF font. */
3240  if (data->text_blf_id >= 0) {
3241  BLF_unload_id(data->text_blf_id);
3242  }
3243 }
3244 
3245 void SEQ_effect_text_font_load(TextVars *data, const bool do_id_user)
3246 {
3247  VFont *vfont = data->text_font;
3248  if (vfont == NULL) {
3249  return;
3250  }
3251 
3252  if (do_id_user) {
3253  id_us_plus(&vfont->id);
3254  }
3255 
3256  if (vfont->packedfile != NULL) {
3257  PackedFile *pf = vfont->packedfile;
3258  /* Create a name that's unique between library data-blocks to avoid loading
3259  * a font per strip which will load fonts many times. */
3260  char name[MAX_ID_FULL_NAME];
3261  BKE_id_full_name_get(name, &vfont->id, 0);
3262 
3263  data->text_blf_id = BLF_load_mem(name, pf->data, pf->size);
3264  }
3265  else {
3266  char path[FILE_MAX];
3267  STRNCPY(path, vfont->filepath);
3269  BLI_path_abs(path, ID_BLEND_PATH_FROM_GLOBAL(&vfont->id));
3270 
3271  data->text_blf_id = BLF_load(path);
3272  }
3273 }
3274 
3275 static void free_text_effect(Sequence *seq, const bool do_id_user)
3276 {
3277  TextVars *data = seq->effectdata;
3278  SEQ_effect_text_font_unload(data, do_id_user);
3279 
3280  if (data) {
3281  MEM_freeN(data);
3282  seq->effectdata = NULL;
3283  }
3284 }
3285 
3286 static void load_text_effect(Sequence *seq)
3287 {
3288  TextVars *data = seq->effectdata;
3290 }
3291 
3292 static void copy_text_effect(Sequence *dst, Sequence *src, const int flag)
3293 {
3294  dst->effectdata = MEM_dupallocN(src->effectdata);
3295  TextVars *data = dst->effectdata;
3296 
3297  data->text_blf_id = -1;
3299 }
3300 
3301 static int num_inputs_text(void)
3302 {
3303  return 0;
3304 }
3305 
3306 static int early_out_text(Sequence *seq, float UNUSED(fac))
3307 {
3308  TextVars *data = seq->effectdata;
3309  if (data->text[0] == 0 || data->text_size < 1.0f ||
3310  ((data->color[3] == 0.0f) &&
3311  (data->shadow_color[3] == 0.0f || (data->flag & SEQ_TEXT_SHADOW) == 0))) {
3312  return EARLY_USE_INPUT_1;
3313  }
3314  return EARLY_NO_INPUT;
3315 }
3316 
3318  Sequence *seq,
3319  float UNUSED(timeline_frame),
3320  float UNUSED(fac),
3321  ImBuf *ibuf1,
3322  ImBuf *ibuf2,
3323  ImBuf *ibuf3)
3324 {
3325  ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
3326  TextVars *data = seq->effectdata;
3327  int width = out->x;
3328  int height = out->y;
3329  struct ColorManagedDisplay *display;
3330  const char *display_device;
3331  int font = blf_mono_font_render;
3332  int line_height;
3333  int y_ofs, x, y;
3334  double proxy_size_comp;
3335 
3336  if (data->text_blf_id == SEQ_FONT_NOT_LOADED) {
3337  data->text_blf_id = -1;
3338 
3340  }
3341 
3342  if (data->text_blf_id >= 0) {
3343  font = data->text_blf_id;
3344  }
3345 
3346  display_device = context->scene->display_settings.display_device;
3347  display = IMB_colormanagement_display_get_named(display_device);
3348 
3349  /* Compensate text size for preview render size. */
3350  proxy_size_comp = context->scene->r.size / 100.0;
3351  if (context->preview_render_size != SEQ_RENDER_SIZE_SCENE) {
3352  proxy_size_comp = SEQ_rendersize_to_scale_factor(context->preview_render_size);
3353  }
3354 
3355  /* set before return */
3356  BLF_size(font, proxy_size_comp * data->text_size, 72);
3357 
3358  const int font_flags = BLF_WORD_WRAP | /* Always allow wrapping. */
3359  ((data->flag & SEQ_TEXT_BOLD) ? BLF_BOLD : 0) |
3360  ((data->flag & SEQ_TEXT_ITALIC) ? BLF_ITALIC : 0);
3361  BLF_enable(font, font_flags);
3362 
3363  /* use max width to enable newlines only */
3364  BLF_wordwrap(font, (data->wrap_width != 0.0f) ? data->wrap_width * width : -1);
3365 
3366  BLF_buffer(
3367  font, out->rect_float, (unsigned char *)out->rect, width, height, out->channels, display);
3368 
3369  line_height = BLF_height_max(font);
3370 
3371  y_ofs = -BLF_descender(font);
3372 
3373  x = (data->loc[0] * width);
3374  y = (data->loc[1] * height) + y_ofs;
3375 
3376  /* vars for calculating wordwrap and optional box */
3377  struct {
3378  struct ResultBLF info;
3379  rcti rect;
3380  } wrap;
3381 
3382  BLF_boundbox_ex(font, data->text, sizeof(data->text), &wrap.rect, &wrap.info);
3383 
3384  if ((data->align == SEQ_TEXT_ALIGN_X_LEFT) && (data->align_y == SEQ_TEXT_ALIGN_Y_TOP)) {
3385  y -= line_height;
3386  }
3387  else {
3388  if (data->align == SEQ_TEXT_ALIGN_X_RIGHT) {
3389  x -= BLI_rcti_size_x(&wrap.rect);
3390  }
3391  else if (data->align == SEQ_TEXT_ALIGN_X_CENTER) {
3392  x -= BLI_rcti_size_x(&wrap.rect) / 2;
3393  }
3394 
3395  if (data->align_y == SEQ_TEXT_ALIGN_Y_TOP) {
3396  y -= line_height;
3397  }
3398  else if (data->align_y == SEQ_TEXT_ALIGN_Y_BOTTOM) {
3399  y += (wrap.info.lines - 1) * line_height;
3400  }
3401  else if (data->align_y == SEQ_TEXT_ALIGN_Y_CENTER) {
3402  y += (((wrap.info.lines - 1) / 2) * line_height) - (line_height / 2);
3403  }
3404  }
3405 
3406  if (data->flag & SEQ_TEXT_BOX) {
3407  if (out->rect) {
3408  const int margin = data->box_margin * width;
3409  const int minx = x + wrap.rect.xmin - margin;
3410  const int maxx = x + wrap.rect.xmax + margin;
3411  const int miny = y + wrap.rect.ymin - margin;
3412  const int maxy = y + wrap.rect.ymax + margin;
3413  IMB_rectfill_area_replace(out, data->box_color, minx, miny, maxx, maxy);
3414  }
3415  }
3416  /* BLF_SHADOW won't work with buffers, instead use cheap shadow trick */
3417  if (data->flag & SEQ_TEXT_SHADOW) {
3418  int fontx, fonty;
3419  fontx = BLF_width_max(font);
3420  fonty = line_height;
3421  BLF_position(font, x + max_ii(fontx / 55, 1), y - max_ii(fonty / 30, 1), 0.0f);
3422  BLF_buffer_col(font, data->shadow_color);
3423  BLF_draw_buffer(font, data->text, sizeof(data->text));
3424  }
3425 
3426  BLF_position(font, x, y, 0.0f);
3427  BLF_buffer_col(font, data->color);
3428  BLF_draw_buffer(font, data->text, sizeof(data->text));
3429 
3430  BLF_buffer(font, NULL, NULL, 0, 0, 0, NULL);
3431 
3432  BLF_disable(font, font_flags);
3433 
3434  return out;
3435 }
3436 
3439 /* -------------------------------------------------------------------- */
3443 static void init_noop(Sequence *UNUSED(seq))
3444 {
3445 }
3446 
3447 static void load_noop(Sequence *UNUSED(seq))
3448 {
3449 }
3450 
3451 static void free_noop(Sequence *UNUSED(seq), const bool UNUSED(do_id_user))
3452 {
3453 }
3454 
3455 static int num_inputs_default(void)
3456 {
3457  return 2;
3458 }
3459 
3460 static void copy_effect_default(Sequence *dst, Sequence *src, const int UNUSED(flag))
3461 {
3462  dst->effectdata = MEM_dupallocN(src->effectdata);
3463 }
3464 
3465 static void free_effect_default(Sequence *seq, const bool UNUSED(do_id_user))
3466 {
3467  MEM_SAFE_FREE(seq->effectdata);
3468 }
3469 
3470 static int early_out_noop(Sequence *UNUSED(seq), float UNUSED(fac))
3471 {
3472  return EARLY_DO_EFFECT;
3473 }
3474 
3475 static int early_out_fade(Sequence *UNUSED(seq), float fac)
3476 {
3477  if (fac == 0.0f) {
3478  return EARLY_USE_INPUT_1;
3479  }
3480  if (fac == 1.0f) {
3481  return EARLY_USE_INPUT_2;
3482  }
3483  return EARLY_DO_EFFECT;
3484 }
3485 
3486 static int early_out_mul_input2(Sequence *UNUSED(seq), float fac)
3487 {
3488  if (fac == 0.0f) {
3489  return EARLY_USE_INPUT_1;
3490  }
3491  return EARLY_DO_EFFECT;
3492 }
3493 
3494 static int early_out_mul_input1(Sequence *UNUSED(seq), float fac)
3495 {
3496  if (fac == 0.0f) {
3497  return EARLY_USE_INPUT_2;
3498  }
3499  return EARLY_DO_EFFECT;
3500 }
3501 
3503  Sequence *UNUSED(seq),
3504  float UNUSED(timeline_frame),
3505  float *fac)
3506 {
3507  *fac = 1.0f;
3508 }
3509 
3510 static void get_default_fac_fade(const Scene *scene,
3511  Sequence *seq,
3512  float timeline_frame,
3513  float *fac)
3514 {
3515  *fac = (float)(timeline_frame - SEQ_time_left_handle_frame_get(scene, seq));
3516  *fac /= SEQ_time_strip_length_get(scene, seq);
3517 }
3518 
3520  ImBuf *ibuf1,
3521  ImBuf *ibuf2,
3522  ImBuf *ibuf3)
3523 {
3524  ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
3525 
3526  return out;
3527 }
3528 
3529 static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
3530 {
3531  struct SeqEffectHandle rval;
3532  int sequence_type = seq_type;
3533 
3534  rval.multithreaded = false;
3535  rval.supports_mask = false;
3536  rval.init = init_noop;
3537  rval.num_inputs = num_inputs_default;
3538  rval.load = load_noop;
3539  rval.free = free_noop;
3540  rval.early_out = early_out_noop;
3541  rval.get_default_fac = get_default_fac_noop;
3542  rval.execute = NULL;
3543  rval.init_execution = init_execution;
3544  rval.execute_slice = NULL;
3545  rval.copy = NULL;
3546 
3547  switch (sequence_type) {
3548  case SEQ_TYPE_CROSS:
3549  rval.multithreaded = true;
3550  rval.execute_slice = do_cross_effect;
3551  rval.early_out = early_out_fade;
3552  rval.get_default_fac = get_default_fac_fade;
3553  break;
3554  case SEQ_TYPE_GAMCROSS:
3555  rval.multithreaded = true;
3556  rval.init = init_gammacross;
3557  rval.load = load_gammacross;
3558  rval.free = free_gammacross;
3559  rval.early_out = early_out_fade;
3560  rval.get_default_fac = get_default_fac_fade;
3561  rval.init_execution = gammacross_init_execution;
3562  rval.execute_slice = do_gammacross_effect;
3563  break;
3564  case SEQ_TYPE_ADD:
3565  rval.multithreaded = true;
3566  rval.execute_slice = do_add_effect;
3567  rval.early_out = early_out_mul_input2;
3568  break;
3569  case SEQ_TYPE_SUB:
3570  rval.multithreaded = true;
3571  rval.execute_slice = do_sub_effect;
3572  rval.early_out = early_out_mul_input2;
3573  break;
3574  case SEQ_TYPE_MUL:
3575  rval.multithreaded = true;
3576  rval.execute_slice = do_mul_effect;
3577  rval.early_out = early_out_mul_input2;
3578  break;
3579  case SEQ_TYPE_SCREEN:
3580  case SEQ_TYPE_OVERLAY:
3581  case SEQ_TYPE_COLOR_BURN:
3582  case SEQ_TYPE_LINEAR_BURN:
3583  case SEQ_TYPE_DARKEN:
3584  case SEQ_TYPE_LIGHTEN:
3585  case SEQ_TYPE_DODGE:
3586  case SEQ_TYPE_SOFT_LIGHT:
3587  case SEQ_TYPE_HARD_LIGHT:
3588  case SEQ_TYPE_PIN_LIGHT:
3589  case SEQ_TYPE_LIN_LIGHT:
3590  case SEQ_TYPE_VIVID_LIGHT:
3591  case SEQ_TYPE_BLEND_COLOR:
3592  case SEQ_TYPE_HUE:
3593  case SEQ_TYPE_SATURATION:
3594  case SEQ_TYPE_VALUE:
3595  case SEQ_TYPE_DIFFERENCE:
3596  case SEQ_TYPE_EXCLUSION:
3597  rval.multithreaded = true;
3598  rval.execute_slice = do_blend_mode_effect;
3599  rval.early_out = early_out_mul_input2;
3600  break;
3601  case SEQ_TYPE_COLORMIX:
3602  rval.multithreaded = true;
3603  rval.init = init_colormix_effect;
3604  rval.free = free_effect_default;
3605  rval.copy = copy_effect_default;
3606  rval.execute_slice = do_colormix_effect;
3607  rval.early_out = early_out_mul_input2;
3608  break;
3609  case SEQ_TYPE_ALPHAOVER:
3610  rval.multithreaded = true;
3611  rval.init = init_alpha_over_or_under;
3612  rval.execute_slice = do_alphaover_effect;
3613  rval.early_out = early_out_mul_input1;
3614  break;
3615  case SEQ_TYPE_OVERDROP:
3616  rval.multithreaded = true;
3617  rval.execute_slice = do_overdrop_effect;
3618  break;
3619  case SEQ_TYPE_ALPHAUNDER:
3620  rval.multithreaded = true;
3621  rval.init = init_alpha_over_or_under;
3622  rval.execute_slice = do_alphaunder_effect;
3623  break;
3624  case SEQ_TYPE_WIPE:
3625  rval.init = init_wipe_effect;
3626  rval.num_inputs = num_inputs_wipe;
3627  rval.free = free_wipe_effect;
3628  rval.copy = copy_wipe_effect;
3629  rval.early_out = early_out_fade;
3630  rval.get_default_fac = get_default_fac_fade;
3631  rval.execute = do_wipe_effect;
3632  break;
3633  case SEQ_TYPE_GLOW:
3634  rval.init = init_glow_effect;
3635  rval.num_inputs = num_inputs_glow;
3636  rval.free = free_glow_effect;
3637  rval.copy = copy_glow_effect;
3638  rval.execute = do_glow_effect;
3639  break;
3640  case SEQ_TYPE_TRANSFORM:
3641  rval.multithreaded = true;
3642  rval.init = init_transform_effect;
3643  rval.num_inputs = num_inputs_transform;
3644  rval.free = free_transform_effect;
3645  rval.copy = copy_transform_effect;
3646  rval.execute_slice = do_transform_effect;
3647  break;
3648  case SEQ_TYPE_SPEED:
3649  rval.init = init_speed_effect;
3650  rval.num_inputs = num_inputs_speed;
3651  rval.load = load_speed_effect;
3652  rval.free = free_speed_effect;
3653  rval.copy = copy_speed_effect;
3654  rval.execute = do_speed_effect;
3655  rval.early_out = early_out_speed;
3656  break;
3657  case SEQ_TYPE_COLOR:
3658  rval.init = init_solid_color;
3659  rval.num_inputs = num_inputs_color;
3660  rval.early_out = early_out_color;
3661  rval.free = free_solid_color;
3662  rval.copy = copy_solid_color;
3663  rval.execute = do_solid_color;
3664  break;
3665  case SEQ_TYPE_MULTICAM:
3666  rval.num_inputs = num_inputs_multicam;
3667  rval.early_out = early_out_multicam;
3668  rval.execute = do_multicam;
3669  break;
3670  case SEQ_TYPE_ADJUSTMENT:
3671  rval.supports_mask = true;
3672  rval.num_inputs = num_inputs_adjustment;
3673  rval.early_out = early_out_adjustment;
3674  rval.execute = do_adjustment;
3675  break;
3677  rval.init = init_gaussian_blur_effect;
3678  rval.num_inputs = num_inputs_gaussian_blur;
3679  rval.free = free_gaussian_blur_effect;
3680  rval.copy = copy_gaussian_blur_effect;
3681  rval.early_out = early_out_gaussian_blur;
3682  rval.execute = do_gaussian_blur_effect;
3683  break;
3684  case SEQ_TYPE_TEXT:
3685  rval.num_inputs = num_inputs_text;
3686  rval.init = init_text_effect;
3687  rval.free = free_text_effect;
3688  rval.load = load_text_effect;
3689  rval.copy = copy_text_effect;
3690  rval.early_out = early_out_text;
3691  rval.execute = do_text_effect;
3692  break;
3693  }
3694 
3695  return rval;
3696 }
3697 
3700 /* -------------------------------------------------------------------- */
3705 {
3706  struct SeqEffectHandle rval = {false, false, NULL};
3707 
3708  if (seq->type & SEQ_TYPE_EFFECT) {
3709  rval = get_sequence_effect_impl(seq->type);
3710  if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) {
3711  rval.load(seq);
3712  seq->flag &= ~SEQ_EFFECT_NOT_LOADED;
3713  }
3714  }
3715 
3716  return rval;
3717 }
3718 
3720 {
3721  struct SeqEffectHandle rval = {false, false, NULL};
3722 
3723  if (seq->blend_mode != 0) {
3724  if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) {
3725  /* load the effect first */
3726  rval = get_sequence_effect_impl(seq->type);
3727  rval.load(seq);
3728  }
3729 
3730  rval = get_sequence_effect_impl(seq->blend_mode);
3731  if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) {
3732  /* now load the blend and unset unloaded flag */
3733  rval.load(seq);
3734  seq->flag &= ~SEQ_EFFECT_NOT_LOADED;
3735  }
3736  }
3737 
3738  return rval;
3739 }
3740 
3741 int SEQ_effect_get_num_inputs(int seq_type)
3742 {
3743  struct SeqEffectHandle rval = get_sequence_effect_impl(seq_type);
3744 
3745  int count = rval.num_inputs();
3746  if (rval.execute || (rval.execute_slice && rval.init_execution)) {
3747  return count;
3748  }
3749  return 0;
3750 }
3751 
typedef float(TangentPoint)[2]
float evaluate_fcurve(struct FCurve *fcu, float evaltime)
Definition: fcurve.c:2135
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:201
@ LIB_ID_CREATE_NO_USER_REFCOUNT
Definition: BKE_lib_id.h:126
void id_us_min(struct ID *id)
Definition: lib_id.c:313
void id_us_plus(struct ID *id)
Definition: lib_id.c:305
void BKE_id_full_name_get(char name[MAX_ID_FULL_NAME], const struct ID *id, char separator_char)
#define MAX_ID_FULL_NAME
Definition: BKE_lib_id.h:550
@ BLF_ITALIC
Definition: BLF_api.h:347
@ BLF_WORD_WRAP
Definition: BLF_api.h:340
@ BLF_BOLD
Definition: BLF_api.h:346
void BLF_draw_buffer(int fontid, const char *str, size_t str_len) ATTR_NONNULL(2)
Definition: blf.c:881
int BLF_descender(int fontid) ATTR_WARN_UNUSED_RESULT
Definition: blf.c:744
int BLF_load_mem(const char *name, const unsigned char *mem, int mem_size) ATTR_NONNULL()
Definition: blf.c:187
int BLF_width_max(int fontid) ATTR_WARN_UNUSED_RESULT
Definition: blf.c:733
void BLF_boundbox_ex(int fontid, const char *str, size_t str_len, struct rcti *box, struct ResultBLF *r_info) ATTR_NONNULL(2)
Definition: blf.c:640
int blf_mono_font_render
Definition: blf.c:49
void BLF_disable(int fontid, int option)
Definition: blf.c:279
void BLF_buffer_col(int fontid, const float rgba[4]) ATTR_NONNULL(2)
Definition: blf.c:836
void BLF_unload_id(int fontid)
Definition: blf.c:242
void BLF_buffer(int fontid, float *fbuf, unsigned char *cbuf, int w, int h, int nch, struct ColorManagedDisplay *display)
Definition: blf.c:816
void BLF_enable(int fontid, int option)
Definition: blf.c:270
int BLF_load(const char *name) ATTR_NONNULL()
Definition: blf.c:135
int BLF_height_max(int fontid) ATTR_WARN_UNUSED_RESULT
Definition: blf.c:722
void BLF_size(int fontid, float size, int dpi)
Definition: blf.c:363
void BLF_wordwrap(int fontid, int wrap_width)
Definition: blf.c:787
void BLF_position(int fontid, float x, float y, float z)
Definition: blf.c:308
#define BLI_assert(a)
Definition: BLI_assert.h:46
#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:20
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 copy_v4_v4(float r[4], const float a[4])
MINLINE void mul_v4_v4fl(float r[4], const float a[4], float f)
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:897
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:186
#define STRNCPY(dst, src)
Definition: BLI_string.h:483
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
int BLI_thread_is_main(void)
Definition: threads.cc:207
#define UNUSED(x)
#define MAX2(a, b)
#define UNLIKELY(x)
void swap(T &a, T &b)
Definition: Common.h:19
#define ID_BLEND_PATH_FROM_GLOBAL(_id)
Definition: DNA_ID.h:561
#define R_FILTER_GAUSS
#define R_IMF_PLANES_RGB
@ 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_X_RIGHT
@ SEQ_TEXT_ALIGN_X_CENTER
@ SEQ_TEXT_ALIGN_X_LEFT
#define SEQ_FONT_NOT_LOADED
#define SEQ_SPEED_USE_INTERPOLATION
@ SEQ_TEXT_ALIGN_Y_BOTTOM
@ SEQ_TEXT_ALIGN_Y_TOP
@ SEQ_TEXT_ALIGN_Y_CENTER
@ SEQ_SPEED_STRETCH
@ SEQ_SPEED_MULTIPLY
@ SEQ_SPEED_LENGTH
@ SEQ_SPEED_FRAME_NUMBER
@ SEQ_EFFECT_NOT_LOADED
@ SEQ_TEXT_ITALIC
@ SEQ_TEXT_SHADOW
@ SEQ_TEXT_BOLD
@ SEQ_TEXT_BOX
@ SEQ_RENDER_SIZE_SCENE
_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
_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
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(const struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout)
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:500
struct ImBuf * IMB_dupImBuf(const struct ImBuf *ibuf1)
void IMB_rect_from_float(struct ImBuf *ibuf)
Definition: divers.c:696
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:355
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:350
void IMB_buffer_float_premultiply(float *buf, int width, int height)
Definition: divers.c:873
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:94
void IMB_buffer_float_unpremultiply(float *buf, int width, int height)
Definition: divers.c:863
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:64
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
static void init_data(ModifierData *md)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a producing a negative Combine Generate a color from its and blue channels(Deprecated)") DefNode(ShaderNode
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
@ DO_IRIS_WIPE
Definition: SEQ_effects.h:25
@ DO_CLOCK_WIPE
Definition: SEQ_effects.h:26
@ DO_DOUBLE_WIPE
Definition: SEQ_effects.h:22
@ DO_SINGLE_WIPE
Definition: SEQ_effects.h:21
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
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.
ListBase * SEQ_get_channels_by_seq(ListBase *seqbase, ListBase *channels, const Sequence *seq)
Definition: channels.c:85
#define sinf(x)
Definition: cuda/compat.h:102
#define cosf(x)
Definition: cuda/compat.h:101
#define tanf(x)
Definition: cuda/compat.h:104
#define powf(x, y)
Definition: cuda/compat.h:103
Scene scene
SyclQueue void void * src
SyclQueue void void size_t num_bytes void
static ImBuf * do_multicam(const SeqRenderData *context, Sequence *seq, float timeline_frame, float UNUSED(fac), ImBuf *UNUSED(ibuf1), ImBuf *UNUSED(ibuf2), ImBuf *UNUSED(ibuf3))
Definition: effects.c:2421
static void do_cross_effect_byte(float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
Definition: effects.c:433
static void copy_speed_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
Definition: effects.c:2573
struct SeqEffectHandle SEQ_effect_handle_get(Sequence *seq)
Definition: effects.c:3704
static void init_text_effect(Sequence *seq)
Definition: effects.c:3197
#define RE_GAMMA_TABLE_SIZE
Definition: effects.c:519
static int early_out_gaussian_blur(Sequence *seq, float UNUSED(fac))
Definition: effects.c:2801
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:3017
struct WipeZone WipeZone
static void makeGammaTables(float gamma)
Definition: effects.c:531
static struct ImBuf * init_execution(const SeqRenderData *context, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
Definition: effects.c:3519
static float in_band(float width, float dist, int side, int dir)
Definition: effects.c:1398
static void do_sub_effect(const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(timeline_frame), float fac, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:889
static void free_noop(Sequence *UNUSED(seq), const bool UNUSED(do_id_user))
Definition: effects.c:3451
static float check_zone(WipeZone *wipezone, int x, int y, Sequence *seq, float fac)
Definition: effects.c:1424
float seq_speed_effect_target_frame_get(Scene *scene, Sequence *seq_speed, float timeline_frame, int input)
Definition: effects.c:2632
static int num_inputs_color(void)
Definition: effects.c:2325
static int early_out_text(Sequence *seq, float UNUSED(fac))
Definition: effects.c:3306
static bool gamma_tabs_init
Definition: effects.c:517
static void do_colormix_effect(const SeqRenderData *context, Sequence *seq, float UNUSED(timeline_frame), float UNUSED(fac), ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:1339
static void init_speed_effect(Sequence *seq)
Definition: effects.c:2536
static void get_default_fac_fade(const Scene *scene, Sequence *seq, float timeline_frame, float *fac)
Definition: effects.c:3510
static void build_gammatabs(void)
Definition: effects.c:647
static void do_alphaover_effect(const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(timeline_frame), float fac, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:277
static float inv_gamfactor_table[RE_GAMMA_TABLE_SIZE]
Definition: effects.c:524
static void copy_wipe_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
Definition: effects.c:1663
static void do_drop_effect_byte(float fac, int x, int y, unsigned char *rect2i, unsigned char *rect1i, unsigned char *outi)
Definition: effects.c:928
static void do_sub_effect_byte(float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
Definition: effects.c:842
static void free_solid_color(Sequence *seq, const bool UNUSED(do_id_user))
Definition: effects.c:2330
static void do_gammacross_effect_float(float fac, int x, int y, float *rect1, float *rect2, float *out)
Definition: effects.c:697
static void free_gammacross(Sequence *UNUSED(seq), const bool UNUSED(do_id_user))
Definition: effects.c:664
static void do_add_effect(const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(timeline_frame), float fac, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:807
static void init_colormix_effect(Sequence *seq)
Definition: effects.c:1326
@ GlowR
Definition: effects.c:125
@ GlowB
Definition: effects.c:127
@ GlowG
Definition: effects.c:126
@ GlowA
Definition: effects.c:128
static float gamfactor_table[RE_GAMMA_TABLE_SIZE]
Definition: effects.c:522
static void copy_solid_color(Sequence *dst, Sequence *src, const int UNUSED(flag))
Definition: effects.c:2335
static void do_mul_effect_byte(float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
Definition: effects.c:1002
static void init_alpha_over_or_under(Sequence *seq)
Definition: effects.c:198
static int num_inputs_speed(void)
Definition: effects.c:2559
static int early_out_mul_input1(Sequence *UNUSED(seq), float fac)
Definition: effects.c:3494
static void RVAddBitmaps_float(float *a, float *b, float *c, int width, int height)
Definition: effects.c:2138
static void free_glow_effect(Sequence *seq, const bool UNUSED(do_id_user))
Definition: effects.c:2205
struct RenderGaussianBlurEffectInitData RenderGaussianBlurEffectInitData
static void do_blend_effect_float(float fac, int x, int y, float *rect1, float *rect2, int btype, float *out)
Definition: effects.c:1144
static void init_glow_effect(Sequence *seq)
Definition: effects.c:2181
void SEQ_effect_text_font_unload(TextVars *data, const bool do_id_user)
Definition: effects.c:3227
BLI_INLINE void apply_blend_function_byte(float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out, IMB_blend_func_byte blend_function)
Definition: effects.c:1092
static int num_inputs_glow(void)
Definition: effects.c:2200
static void load_text_effect(Sequence *seq)
Definition: effects.c:3286
static int num_inputs_text(void)
Definition: effects.c:3301
int SEQ_effect_get_num_inputs(int seq_type)
Definition: effects.c:3741
static float gamma_range_table[RE_GAMMA_TABLE_SIZE+1]
Definition: effects.c:521
static void gamtabs(float gamma)
Definition: effects.c:613
static int early_out_color(Sequence *UNUSED(seq), float UNUSED(fac))
Definition: effects.c:2340
static void copy_transform_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
Definition: effects.c:1861
static void free_effect_default(Sequence *seq, const bool UNUSED(do_id_user))
Definition: effects.c:3465
#define YOFF
Definition: effects.c:926
static void do_mul_effect(const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(timeline_frame), float fac, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:1052
static void do_add_effect_float(float fac, int x, int y, float *rect1, float *rect2, float *out)
Definition: effects.c:786
#define XOFF
Definition: effects.c:925
static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
Definition: effects.c:3529
static void init_gammacross(Sequence *UNUSED(seq))
Definition: effects.c:656
static void free_transform_effect(Sequence *seq, const bool UNUSED(do_id_user))
Definition: effects.c:1856
static void init_wipe_effect(Sequence *seq)
Definition: effects.c:1644
static int early_out_mul_input2(Sequence *UNUSED(seq), float fac)
Definition: effects.c:3486
static ImBuf * do_wipe_effect(const SeqRenderData *context, Sequence *seq, float UNUSED(timeline_frame), float fac, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
Definition: effects.c:1788
static float invGammaCorrect(float c)
Definition: effects.c:593
static void do_glow_effect_byte(Sequence *seq, int render_size, float fac, int x, int y, unsigned char *rect1, unsigned char *UNUSED(rect2), unsigned char *out)
Definition: effects.c:2215
static void do_transform_effect(const SeqRenderData *context, Sequence *seq, float UNUSED(timeline_frame), float UNUSED(fac), ImBuf *ibuf1, ImBuf *UNUSED(ibuf2), ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:1917
static void free_gaussian_blur_effect(Sequence *seq, const bool UNUSED(do_id_user))
Definition: effects.c:2791
static float gammaCorrect(float c)
Definition: effects.c:567
static void precalc_wipe_zone(WipeZone *wipezone, WipeVars *wipe, int xo, int yo)
Definition: effects.c:1385
static ImBuf * prepare_effect_imbufs(const SeqRenderData *context, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
Definition: effects.c:131
static void do_blend_mode_effect(const SeqRenderData *context, Sequence *seq, float UNUSED(timeline_frame), float fac, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:1293
static float valid_gamma
Definition: effects.c:528
static float inv_color_step
Definition: effects.c:527
static ImBuf * do_solid_color(const SeqRenderData *context, Sequence *seq, float UNUSED(timeline_frame), float UNUSED(fac), ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
Definition: effects.c:2345
void(* IMB_blend_func_byte)(unsigned char *dst, const unsigned char *src1, const unsigned char *src2)
Definition: effects.c:1087
static float color_domain_table[RE_GAMMA_TABLE_SIZE+1]
Definition: effects.c:525
static int num_inputs_transform(void)
Definition: effects.c:1851
static void do_cross_effect_float(float fac, int x, int y, float *rect1, float *rect2, float *out)
Definition: effects.c:457
static void do_alphaover_effect_float(float fac, int x, int y, float *rect1, float *rect2, float *out)
Definition: effects.c:245
static void * render_effect_execute_do_y_thread(void *thread_data_v)
Definition: effects.c:3139
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:68
static FCurve * seq_effect_speed_speed_factor_curve_get(Scene *scene, Sequence *seq)
Definition: effects.c:2586
static void copy_effect_default(Sequence *dst, Sequence *src, const int UNUSED(flag))
Definition: effects.c:3460
static void RVIsolateHighlights_float(const float *in, float *out, int width, int height, float threshold, float boost, float clamp)
Definition: effects.c:2153
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:2887
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:1866
static ImBuf * do_glow_effect(const SeqRenderData *context, Sequence *seq, float UNUSED(timeline_frame), float fac, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
Definition: effects.c:2269
static ImBuf * do_gaussian_blur_effect(const SeqRenderData *context, Sequence *seq, float UNUSED(timeline_frame), float UNUSED(fac), ImBuf *ibuf1, ImBuf *UNUSED(ibuf2), ImBuf *UNUSED(ibuf3))
Definition: effects.c:3152
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:2976
static void RVBlurBitmap2_float(float *map, int width, int height, float blur, int quality)
Definition: effects.c:1982
static void do_gammacross_effect(const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(timeline_frame), float fac, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:727
static void load_speed_effect(Sequence *seq)
Definition: effects.c:2553
static void init_noop(Sequence *UNUSED(seq))
Definition: effects.c:3443
static void do_alphaover_effect_byte(float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
Definition: effects.c:207
static void load_gammacross(Sequence *UNUSED(seq))
Definition: effects.c:660
static int early_out_adjustment(Sequence *UNUSED(seq), float UNUSED(fac))
Definition: effects.c:2464
static void do_drop_effect_float(float fac, int x, int y, float *rect2i, float *rect1i, float *outi)
Definition: effects.c:962
static void copy_gaussian_blur_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
Definition: effects.c:2796
static float color_step
Definition: effects.c:526
static void do_alphaunder_effect(const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(timeline_frame), float fac, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:398
static void load_noop(Sequence *UNUSED(seq))
Definition: effects.c:3447
struct SeqEffectHandle seq_effect_get_sequence_blend(Sequence *seq)
Definition: effects.c:3719
void(* IMB_blend_func_float)(float *dst, const float *src1, const float *src2)
Definition: effects.c:1090
static void free_wipe_effect(Sequence *seq, const bool UNUSED(do_id_user))
Definition: effects.c:1658
static void do_alphaunder_effect_byte(float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
Definition: effects.c:312
static float inv_gamma_range_table[RE_GAMMA_TABLE_SIZE+1]
Definition: effects.c:523
static ImBuf * do_adjustment(const SeqRenderData *context, Sequence *seq, float timeline_frame, float UNUSED(fac), ImBuf *UNUSED(ibuf1), ImBuf *UNUSED(ibuf2), ImBuf *UNUSED(ibuf3))
Definition: effects.c:2508
static void seq_effect_speed_frame_map_ensure(Scene *scene, Sequence *seq)
Definition: effects.c:2622
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:3056
static void init_solid_color(Sequence *seq)
Definition: effects.c:2311
static int early_out_noop(Sequence *UNUSED(seq), float UNUSED(fac))
Definition: effects.c:3470
static unsigned short gamtab[65536]
Definition: effects.c:515
static int early_out_speed(Sequence *UNUSED(seq), float UNUSED(fac))
Definition: effects.c:2581
static void free_text_effect(Sequence *seq, const bool do_id_user)
Definition: effects.c:3275
static int early_out_multicam(Sequence *UNUSED(seq), float UNUSED(fac))
Definition: effects.c:2416
static int early_out_fade(Sequence *UNUSED(seq), float fac)
Definition: effects.c:3475
static void do_blend_effect_byte(float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, int btype, unsigned char *out)
Definition: effects.c:1216
static void do_alphaunder_effect_float(float fac, int x, int y, float *rect1, float *rect2, float *out)
Definition: effects.c:358
static int num_inputs_wipe(void)
Definition: effects.c:1653
static float valid_inv_gamma
Definition: effects.c:529
static void do_mul_effect_float(float fac, int x, int y, float *rect1, float *rect2, float *out)
Definition: effects.c:1029
static void do_wipe_effect_byte(Sequence *seq, float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
Definition: effects.c:1668
static void do_gammacross_effect_byte(float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
Definition: effects.c:668
static float * make_gaussian_blur_kernel(float rad, int size)
Definition: effects.c:2811
static ImBuf * do_adjustment_impl(const SeqRenderData *context, Sequence *seq, float timeline_frame)
Definition: effects.c:2469
static float speed_effect_interpolation_ratio_get(Scene *scene, Sequence *seq_speed, float timeline_frame)
Definition: effects.c:2690
static void copy_text_effect(Sequence *dst, Sequence *src, const int flag)
Definition: effects.c:3292
static void do_add_effect_byte(float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
Definition: effects.c:762
static void do_wipe_effect_float(Sequence *seq, float fac, int x, int y, float *rect1, float *rect2, float *out)
Definition: effects.c:1734
static int num_inputs_adjustment(void)
Definition: effects.c:2459
static void do_glow_effect_float(Sequence *seq, int render_size, float fac, int x, int y, float *rect1, float *UNUSED(rect2), float *out)
Definition: effects.c:2248
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:93
void seq_effect_speed_rebuild_map(Scene *scene, Sequence *seq)
Definition: effects.c:2591
static void init_transform_effect(Sequence *seq)
Definition: effects.c:1826
static int num_inputs_gaussian_blur(void)
Definition: effects.c:2786
static void init_gaussian_blur_effect(Sequence *seq)
Definition: effects.c:2777
static ImBuf * do_text_effect(const SeqRenderData *context, Sequence *seq, float UNUSED(timeline_frame), float UNUSED(fac), ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
Definition: effects.c:3317
static void do_overdrop_effect(const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(timeline_frame), float fac, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:2729
static void do_sub_effect_float(float fac, int x, int y, float *rect1, float *rect2, float *out)
Definition: effects.c:866
static struct ImBuf * gammacross_init_execution(const SeqRenderData *context, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
Definition: effects.c:716
BLI_INLINE void apply_blend_function_float(float fac, int x, int y, float *rect1, float *rect2, float *out, IMB_blend_func_float blend_function)
Definition: effects.c:1118
#define INDEX(_x, _y)
static void free_speed_effect(Sequence *seq, const bool UNUSED(do_id_user))
Definition: effects.c:2564
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:2837
static void do_cross_effect(const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(timeline_frame), float fac, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
Definition: effects.c:479
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:2935
static void get_default_fac_noop(const Scene *UNUSED(scene), Sequence *UNUSED(seq), float UNUSED(timeline_frame), float *fac)
Definition: effects.c:3502
static void render_effect_execute_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v)
Definition: effects.c:3110
static void * render_effect_execute_do_x_thread(void *thread_data_v)
Definition: effects.c:3127
void SEQ_effect_text_font_load(TextVars *data, const bool do_id_user)
Definition: effects.c:3245
static unsigned short igamtab1[256]
Definition: effects.c:516
static int num_inputs_multicam(void)
Definition: effects.c:2411
static int num_inputs_default(void)
Definition: effects.c:3455
struct RenderGaussianBlurEffectThread RenderGaussianBlurEffectThread
static ImBuf * do_speed_effect(const SeqRenderData *context, Sequence *seq, float timeline_frame, float fac, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
Definition: effects.c:2699
static void copy_glow_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
Definition: effects.c:2210
#define pf(_x, _i)
Prefetch 64.
Definition: gim_memory.h:48
void IMB_freeImBuf(ImBuf *UNUSED(ibuf))
DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
float RE_filter_value(int type, float x)
Definition: initrender.c:108
int count
ccl_gpu_kernel_postfix ccl_global float int int int int float threshold
ccl_global KernelShaderEvalInput ccl_global float * output
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
ccl_global KernelShaderEvalInput * input
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
ccl_device_inline float3 exp(float3 v)
Definition: math_float3.h:392
ccl_device_inline float3 ceil(const float3 &a)
Definition: math_float3.h:363
ccl_device_inline float3 pow(float3 v, float e)
Definition: math_float3.h:533
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:248
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:78
#define hypotf(x, y)
Definition: metal/compat.h:226
#define floorf(x)
Definition: metal/compat.h:224
#define fabsf(x)
Definition: metal/compat.h:219
#define sqrtf(x)
Definition: metal/compat.h:243
static unsigned c
Definition: RandGen.cpp:83
static unsigned a[3]
Definition: RandGen.cpp:78
INLINE Rall1d< T, V, S > asin(const Rall1d< T, V, S > &x)
Definition: rall1d.h:391
INLINE Rall1d< T, V, S > hypot(const Rall1d< T, V, S > &y, const Rall1d< T, V, S > &x)
Definition: rall1d.h:383
static struct PartialUpdateUser * wrap(PartialUpdateUserImpl *user)
T clamp(const T &a, const T &min, const T &max)
T floor(const T &a)
T abs(const T &a)
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
SocketIndexByIdentifierMap * map
double SEQ_rendersize_to_scale_factor(int render_size)
Definition: proxy.c:86
ImBuf * seq_render_give_ibuf_seqbase(const SeqRenderData *context, float timeline_frame, int chan_shown, ListBase *channels, ListBase *seqbasep)
Definition: render.c:1982
void seq_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, bool make_float)
Definition: render.c:101
ImBuf * seq_render_effect_execute_threaded(struct SeqEffectHandle *sh, const SeqRenderData *context, Sequence *seq, float timeline_frame, float fac, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
Definition: render.c:740
#define EARLY_USE_INPUT_2
Definition: render.h:24
#define EARLY_DO_EFFECT
Definition: render.h:22
#define EARLY_USE_INPUT_1
Definition: render.h:23
#define EARLY_NO_INPUT
Definition: render.h:21
struct Sequence * SEQ_find_metastrip_by_sequence(ListBase *seqbase, Sequence *meta, Sequence *seq)
int SEQ_time_strip_length_get(const Scene *scene, const Sequence *seq)
Definition: strip_time.c:484
int SEQ_time_left_handle_frame_get(const Scene *UNUSED(scene), const Sequence *seq)
Definition: strip_time.c:506
float seq_give_frame_index(const Scene *scene, Sequence *seq, float timeline_frame)
Definition: strip_time.c:52
int SEQ_time_right_handle_frame_get(const Scene *scene, const Sequence *seq)
Definition: strip_time.c:515
ListBase seqbase
ListBase channels
unsigned int * rect
float * rect_float
const SeqRenderData * context
Definition: effects.c:3096
const SeqRenderData * context
Definition: effects.c:3103
ColorManagedColorspaceSettings sequencer_colorspace_settings
int(* num_inputs)(void)
Definition: SEQ_effects.h:39
void(* load)(struct Sequence *seqconst)
Definition: SEQ_effects.h:43
struct ImBuf *(* execute)(const struct SeqRenderData *context, struct Sequence *seq, float timeline_frame, float fac, struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf3)
Definition: SEQ_effects.h:68
void(* execute_slice)(const struct SeqRenderData *context, struct Sequence *seq, float timeline_frame, float fac, struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf3, int start_line, int total_lines, struct ImBuf *out)
Definition: SEQ_effects.h:81
struct ImBuf *(* init_execution)(const struct SeqRenderData *context, struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf3)
Definition: SEQ_effects.h:76
struct Sequence * seq1
struct Sequence * seq2
char filepath[1024]
struct PackedFile * packedfile
float angle
Definition: effects.c:1378
int flip
Definition: effects.c:1379
int xo
Definition: effects.c:1380
int yo
Definition: effects.c:1380
float pythangle
Definition: effects.c:1382
int width
Definition: effects.c:1381
ListBase * SEQ_get_seqbase_by_seq(const Scene *scene, Sequence *seq)
Definition: utils.c:373