Blender  V2.93
sequencer/intern/modifier.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2012 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include <stddef.h>
25 #include <string.h>
26 
27 #include "MEM_guardedalloc.h"
28 
29 #include "BLI_listbase.h"
30 #include "BLI_math.h"
31 #include "BLI_string.h"
32 #include "BLI_string_utils.h"
33 #include "BLI_utildefines.h"
34 
35 #include "BLT_translation.h"
36 
37 #include "DNA_mask_types.h"
38 #include "DNA_scene_types.h"
39 #include "DNA_sequence_types.h"
40 
41 #include "BKE_colortools.h"
42 
43 #include "IMB_colormanagement.h"
44 #include "IMB_imbuf.h"
45 #include "IMB_imbuf_types.h"
46 
47 #include "SEQ_modifier.h"
48 #include "SEQ_render.h"
49 
50 #include "BLO_read_write.h"
51 
52 #include "render.h"
53 
55 static bool modifierTypesInit = false;
56 
57 /* -------------------------------------------------------------------- */
61 typedef void (*modifier_apply_threaded_cb)(int width,
62  int height,
63  unsigned char *rect,
64  float *rect_float,
65  unsigned char *mask_rect,
66  const float *mask_rect_float,
67  void *data_v);
68 
69 typedef struct ModifierInitData {
72  void *user_data;
73 
76 
77 typedef struct ModifierThread {
78  int width, height;
79 
80  unsigned char *rect, *mask_rect;
82 
83  void *user_data;
84 
87 
92  int mask_input_type,
93  Sequence *mask_sequence,
94  Mask *mask_id,
95  int timeline_frame,
96  int fra_offset,
97  bool make_float)
98 {
99  ImBuf *mask_input = NULL;
100 
101  if (mask_input_type == SEQUENCE_MASK_INPUT_STRIP) {
102  if (mask_sequence) {
105 
106  mask_input = seq_render_strip(context, &state, mask_sequence, timeline_frame);
107 
108  if (make_float) {
109  if (!mask_input->rect_float) {
110  IMB_float_from_rect(mask_input);
111  }
112  }
113  else {
114  if (!mask_input->rect) {
115  IMB_rect_from_float(mask_input);
116  }
117  }
118  }
119  }
120  else if (mask_input_type == SEQUENCE_MASK_INPUT_ID) {
121  mask_input = seq_render_mask(context, mask_id, timeline_frame - fra_offset, make_float);
122  }
123 
124  return mask_input;
125 }
126 
128  const SeqRenderData *context,
129  int timeline_frame,
130  int fra_offset,
131  bool make_float)
132 {
134  smd->mask_input_type,
135  smd->mask_sequence,
136  smd->mask_id,
137  timeline_frame,
138  fra_offset,
139  make_float);
140 }
141 
142 static void modifier_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v)
143 {
144  ModifierThread *handle = (ModifierThread *)handle_v;
145  ModifierInitData *init_data = (ModifierInitData *)init_data_v;
146  ImBuf *ibuf = init_data->ibuf;
147  ImBuf *mask = init_data->mask;
148 
149  int offset = 4 * start_line * ibuf->x;
150 
151  memset(handle, 0, sizeof(ModifierThread));
152 
153  handle->width = ibuf->x;
154  handle->height = tot_line;
155  handle->apply_callback = init_data->apply_callback;
156  handle->user_data = init_data->user_data;
157 
158  if (ibuf->rect) {
159  handle->rect = (unsigned char *)ibuf->rect + offset;
160  }
161 
162  if (ibuf->rect_float) {
163  handle->rect_float = ibuf->rect_float + offset;
164  }
165 
166  if (mask) {
167  if (mask->rect) {
168  handle->mask_rect = (unsigned char *)mask->rect + offset;
169  }
170 
171  if (mask->rect_float) {
172  handle->mask_rect_float = mask->rect_float + offset;
173  }
174  }
175  else {
176  handle->mask_rect = NULL;
177  handle->mask_rect_float = NULL;
178  }
179 }
180 
181 static void *modifier_do_thread(void *thread_data_v)
182 {
183  ModifierThread *td = (ModifierThread *)thread_data_v;
184 
185  td->apply_callback(td->width,
186  td->height,
187  td->rect,
188  td->rect_float,
189  td->mask_rect,
190  td->mask_rect_float,
191  td->user_data);
192 
193  return NULL;
194 }
195 
196 static void modifier_apply_threaded(ImBuf *ibuf,
197  ImBuf *mask,
198  modifier_apply_threaded_cb apply_callback,
199  void *user_data)
200 {
202 
203  init_data.ibuf = ibuf;
204  init_data.mask = mask;
205  init_data.user_data = user_data;
206 
207  init_data.apply_callback = apply_callback;
208 
211 }
212 
215 /* -------------------------------------------------------------------- */
220 {
221  StripColorBalance cb = *cb_;
222  int c;
223 
224  for (c = 0; c < 3; c++) {
225  cb.lift[c] = 2.0f - cb.lift[c];
226  }
227 
229  for (c = 0; c < 3; c++) {
230  /* tweak to give more subtle results
231  * values above 1.0 are scaled */
232  if (cb.lift[c] > 1.0f) {
233  cb.lift[c] = pow(cb.lift[c] - 1.0f, 2.0) + 1.0;
234  }
235 
236  cb.lift[c] = 2.0f - cb.lift[c];
237  }
238  }
239 
241  for (c = 0; c < 3; c++) {
242  if (cb.gain[c] != 0.0f) {
243  cb.gain[c] = 1.0f / cb.gain[c];
244  }
245  else {
246  cb.gain[c] = 1000000; /* should be enough :) */
247  }
248  }
249  }
250 
252  for (c = 0; c < 3; c++) {
253  if (cb.gamma[c] != 0.0f) {
254  cb.gamma[c] = 1.0f / cb.gamma[c];
255  }
256  else {
257  cb.gamma[c] = 1000000; /* should be enough :) */
258  }
259  }
260  }
261 
262  return cb;
263 }
264 
265 /* note: lift is actually 2-lift */
267  float in, const float lift, const float gain, const float gamma, const float mul)
268 {
269  float x = (((in - 1.0f) * lift) + 1.0f) * gain;
270 
271  /* prevent NaN */
272  if (x < 0.0f) {
273  x = 0.0f;
274  }
275 
276  x = powf(x, gamma) * mul;
277  CLAMP(x, FLT_MIN, FLT_MAX);
278  return x;
279 }
280 
281 static void make_cb_table_float(float lift, float gain, float gamma, float *table, float mul)
282 {
283  int y;
284 
285  for (y = 0; y < 256; y++) {
286  float v = color_balance_fl((float)y * (1.0f / 255.0f), lift, gain, gamma, mul);
287 
288  table[y] = v;
289  }
290 }
291 
293  unsigned char *rect,
294  unsigned char *mask_rect,
295  int width,
296  int height,
297  float mul)
298 {
299  // unsigned char cb_tab[3][256];
300  unsigned char *cp = rect;
301  unsigned char *e = cp + width * 4 * height;
302  unsigned char *m = mask_rect;
303 
304  StripColorBalance cb = calc_cb(cb_);
305 
306  while (cp < e) {
307  float p[4];
308  int c;
309 
311 
312  for (c = 0; c < 3; c++) {
313  float t = color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul);
314 
315  if (m) {
316  float m_normal = (float)m[c] / 255.0f;
317 
318  p[c] = p[c] * (1.0f - m_normal) + t * m_normal;
319  }
320  else {
321  p[c] = t;
322  }
323  }
324 
326 
327  cp += 4;
328  if (m) {
329  m += 4;
330  }
331  }
332 }
333 
335  unsigned char *rect,
336  float *rect_float,
337  unsigned char *mask_rect,
338  int width,
339  int height,
340  float mul)
341 {
342  float cb_tab[4][256];
343  int c, i;
344  unsigned char *p = rect;
345  unsigned char *e = p + width * 4 * height;
346  unsigned char *m = mask_rect;
347  float *o;
349 
350  o = rect_float;
351 
352  cb = calc_cb(cb_);
353 
354  for (c = 0; c < 3; c++) {
355  make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c], cb_tab[c], mul);
356  }
357 
358  for (i = 0; i < 256; i++) {
359  cb_tab[3][i] = ((float)i) * (1.0f / 255.0f);
360  }
361 
362  while (p < e) {
363  if (m) {
364  const float t[3] = {m[0] / 255.0f, m[1] / 255.0f, m[2] / 255.0f};
365 
366  p[0] = p[0] * (1.0f - t[0]) + t[0] * cb_tab[0][p[0]];
367  p[1] = p[1] * (1.0f - t[1]) + t[1] * cb_tab[1][p[1]];
368  p[2] = p[2] * (1.0f - t[2]) + t[2] * cb_tab[2][p[2]];
369 
370  m += 4;
371  }
372  else {
373  o[0] = cb_tab[0][p[0]];
374  o[1] = cb_tab[1][p[1]];
375  o[2] = cb_tab[2][p[2]];
376  }
377 
378  o[3] = cb_tab[3][p[3]];
379 
380  p += 4;
381  o += 4;
382  }
383 }
384 
386  float *rect_float,
387  const float *mask_rect_float,
388  int width,
389  int height,
390  float mul)
391 {
392  float *p = rect_float;
393  const float *e = rect_float + width * 4 * height;
394  const float *m = mask_rect_float;
395  StripColorBalance cb = calc_cb(cb_);
396 
397  while (p < e) {
398  int c;
399  for (c = 0; c < 3; c++) {
400  float t = color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul);
401 
402  if (m) {
403  p[c] = p[c] * (1.0f - m[c]) + t * m[c];
404  }
405  else {
406  p[c] = t;
407  }
408  }
409 
410  p += 4;
411  if (m) {
412  m += 4;
413  }
414  }
415 }
416 
417 typedef struct ColorBalanceInitData {
420  float mul;
424 
425 typedef struct ColorBalanceThread {
427  float mul;
428 
429  int width, height;
430 
431  unsigned char *rect, *mask_rect;
433 
436 
437 static void color_balance_init_handle(void *handle_v,
438  int start_line,
439  int tot_line,
440  void *init_data_v)
441 {
442  ColorBalanceThread *handle = (ColorBalanceThread *)handle_v;
444  ImBuf *ibuf = init_data->ibuf;
445  ImBuf *mask = init_data->mask;
446 
447  int offset = 4 * start_line * ibuf->x;
448 
449  memset(handle, 0, sizeof(ColorBalanceThread));
450 
451  handle->cb = init_data->cb;
452  handle->mul = init_data->mul;
453  handle->width = ibuf->x;
454  handle->height = tot_line;
455  handle->make_float = init_data->make_float;
456 
457  if (ibuf->rect) {
458  handle->rect = (unsigned char *)ibuf->rect + offset;
459  }
460 
461  if (ibuf->rect_float) {
462  handle->rect_float = ibuf->rect_float + offset;
463  }
464 
465  if (mask) {
466  if (mask->rect) {
467  handle->mask_rect = (unsigned char *)mask->rect + offset;
468  }
469 
470  if (mask->rect_float) {
471  handle->mask_rect_float = mask->rect_float + offset;
472  }
473  }
474  else {
475  handle->mask_rect = NULL;
476  handle->mask_rect_float = NULL;
477  }
478 }
479 
480 static void *color_balance_do_thread(void *thread_data_v)
481 {
482  ColorBalanceThread *thread_data = (ColorBalanceThread *)thread_data_v;
483  StripColorBalance *cb = thread_data->cb;
484  int width = thread_data->width, height = thread_data->height;
485  unsigned char *rect = thread_data->rect;
486  unsigned char *mask_rect = thread_data->mask_rect;
487  float *rect_float = thread_data->rect_float;
488  float *mask_rect_float = thread_data->mask_rect_float;
489  float mul = thread_data->mul;
490 
491  if (rect_float) {
492  color_balance_float_float(cb, rect_float, mask_rect_float, width, height, mul);
493  }
494  else if (thread_data->make_float) {
495  color_balance_byte_float(cb, rect, rect_float, mask_rect, width, height, mul);
496  }
497  else {
498  color_balance_byte_byte(cb, rect, mask_rect, width, height, mul);
499  }
500 
501  return NULL;
502 }
503 
505 {
507  int c;
508 
509  cbmd->color_multiply = 1.0f;
510 
511  for (c = 0; c < 3; c++) {
512  cbmd->color_balance.lift[c] = 1.0f;
513  cbmd->color_balance.gamma[c] = 1.0f;
514  cbmd->color_balance.gain[c] = 1.0f;
515  }
516 }
517 
519  StripColorBalance *cb, ImBuf *ibuf, float mul, bool make_float, ImBuf *mask_input)
520 {
522 
523  if (!ibuf->rect_float && make_float) {
524  imb_addrectfloatImBuf(ibuf);
525  }
526 
527  init_data.cb = cb;
528  init_data.ibuf = ibuf;
529  init_data.mul = mul;
530  init_data.make_float = make_float;
531  init_data.mask = mask_input;
532 
534  sizeof(ColorBalanceThread),
535  &init_data,
538 
539  /* color balance either happens on float buffer or byte buffer, but never on both,
540  * free byte buffer if there's float buffer since float buffer would be used for
541  * color balance in favor of byte buffer
542  */
543  if (ibuf->rect_float && ibuf->rect) {
544  imb_freerectImBuf(ibuf);
545  }
546 }
547 
549 {
551 
552  modifier_color_balance_apply(&cbmd->color_balance, ibuf, cbmd->color_multiply, false, mask);
553 }
554 
556  CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Color Balance"), /* name */
557  "ColorBalanceModifierData", /* struct_name */
558  sizeof(ColorBalanceModifierData), /* struct_size */
559  colorBalance_init_data, /* init_data */
560  NULL, /* free_data */
561  NULL, /* copy_data */
562  colorBalance_apply, /* apply */
563 };
564 
567 /* -------------------------------------------------------------------- */
572 {
574  copy_v3_fl(cbmd->white_value, 1.0f);
575 }
576 
577 typedef struct WhiteBalanceThreadData {
578  float white[3];
580 
582  int height,
583  unsigned char *rect,
584  float *rect_float,
585  unsigned char *mask_rect,
586  const float *mask_rect_float,
587  void *data_v)
588 {
589  int x, y;
590  float multiplier[3];
591 
593 
594  multiplier[0] = (data->white[0] != 0.0f) ? 1.0f / data->white[0] : FLT_MAX;
595  multiplier[1] = (data->white[1] != 0.0f) ? 1.0f / data->white[1] : FLT_MAX;
596  multiplier[2] = (data->white[2] != 0.0f) ? 1.0f / data->white[2] : FLT_MAX;
597 
598  for (y = 0; y < height; y++) {
599  for (x = 0; x < width; x++) {
600  int pixel_index = (y * width + x) * 4;
601  float rgba[4], result[4], mask[3] = {1.0f, 1.0f, 1.0f};
602 
603  if (rect_float) {
604  copy_v3_v3(rgba, rect_float + pixel_index);
605  }
606  else {
607  straight_uchar_to_premul_float(rgba, rect + pixel_index);
608  }
609 
610  copy_v4_v4(result, rgba);
611 #if 0
612  mul_v3_v3(result, multiplier);
613 #else
614  /* similar to division without the clipping */
615  for (int i = 0; i < 3; i++) {
616  result[i] = 1.0f - powf(1.0f - rgba[i], multiplier[i]);
617  }
618 #endif
619 
620  if (mask_rect_float) {
621  copy_v3_v3(mask, mask_rect_float + pixel_index);
622  }
623  else if (mask_rect) {
624  rgb_uchar_to_float(mask, mask_rect + pixel_index);
625  }
626 
627  result[0] = rgba[0] * (1.0f - mask[0]) + result[0] * mask[0];
628  result[1] = rgba[1] * (1.0f - mask[1]) + result[1] * mask[1];
629  result[2] = rgba[2] * (1.0f - mask[2]) + result[2] * mask[2];
630 
631  if (rect_float) {
632  copy_v3_v3(rect_float + pixel_index, result);
633  }
634  else {
635  premul_float_to_straight_uchar(rect + pixel_index, result);
636  }
637  }
638  }
639 }
640 
642 {
645 
646  copy_v3_v3(data.white, wbmd->white_value);
647 
649 }
650 
652  CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "White Balance"), /* name */
653  "WhiteBalanceModifierData", /* struct_name */
654  sizeof(WhiteBalanceModifierData), /* struct_size */
655  whiteBalance_init_data, /* init_data */
656  NULL, /* free_data */
657  NULL, /* copy_data */
658  whiteBalance_apply, /* apply */
659 };
660 
663 /* -------------------------------------------------------------------- */
668 {
670 
671  BKE_curvemapping_set_defaults(&cmd->curve_mapping, 4, 0.0f, 0.0f, 1.0f, 1.0f);
672 }
673 
675 {
677 
679 }
680 
682 {
684  CurvesModifierData *cmd_target = (CurvesModifierData *)target;
685 
687 }
688 
689 static void curves_apply_threaded(int width,
690  int height,
691  unsigned char *rect,
692  float *rect_float,
693  unsigned char *mask_rect,
694  const float *mask_rect_float,
695  void *data_v)
696 {
697  CurveMapping *curve_mapping = (CurveMapping *)data_v;
698  int x, y;
699 
700  for (y = 0; y < height; y++) {
701  for (x = 0; x < width; x++) {
702  int pixel_index = (y * width + x) * 4;
703 
704  if (rect_float) {
705  float *pixel = rect_float + pixel_index;
706  float result[3];
707 
708  BKE_curvemapping_evaluate_premulRGBF(curve_mapping, result, pixel);
709 
710  if (mask_rect_float) {
711  const float *m = mask_rect_float + pixel_index;
712 
713  pixel[0] = pixel[0] * (1.0f - m[0]) + result[0] * m[0];
714  pixel[1] = pixel[1] * (1.0f - m[1]) + result[1] * m[1];
715  pixel[2] = pixel[2] * (1.0f - m[2]) + result[2] * m[2];
716  }
717  else {
718  pixel[0] = result[0];
719  pixel[1] = result[1];
720  pixel[2] = result[2];
721  }
722  }
723  if (rect) {
724  unsigned char *pixel = rect + pixel_index;
725  float result[3], tempc[4];
726 
727  straight_uchar_to_premul_float(tempc, pixel);
728 
729  BKE_curvemapping_evaluate_premulRGBF(curve_mapping, result, tempc);
730 
731  if (mask_rect) {
732  float t[3];
733 
734  rgb_uchar_to_float(t, mask_rect + pixel_index);
735 
736  tempc[0] = tempc[0] * (1.0f - t[0]) + result[0] * t[0];
737  tempc[1] = tempc[1] * (1.0f - t[1]) + result[1] * t[1];
738  tempc[2] = tempc[2] * (1.0f - t[2]) + result[2] * t[2];
739  }
740  else {
741  tempc[0] = result[0];
742  tempc[1] = result[1];
743  tempc[2] = result[2];
744  }
745 
746  premul_float_to_straight_uchar(pixel, tempc);
747  }
748  }
749  }
750 }
751 
752 static void curves_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
753 {
755 
756  const float black[3] = {0.0f, 0.0f, 0.0f};
757  const float white[3] = {1.0f, 1.0f, 1.0f};
758 
760 
762  BKE_curvemapping_set_black_white(&cmd->curve_mapping, black, white);
763 
765 
767 }
768 
770  CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Curves"), /* name */
771  "CurvesModifierData", /* struct_name */
772  sizeof(CurvesModifierData), /* struct_size */
773  curves_init_data, /* init_data */
774  curves_free_data, /* free_data */
775  curves_copy_data, /* copy_data */
776  curves_apply, /* apply */
777 };
778 
781 /* -------------------------------------------------------------------- */
786 {
788  int c;
789 
790  BKE_curvemapping_set_defaults(&hcmd->curve_mapping, 1, 0.0f, 0.0f, 1.0f, 1.0f);
792 
793  for (c = 0; c < 3; c++) {
794  CurveMap *cuma = &hcmd->curve_mapping.cm[c];
795 
798  }
799 
800  /* default to showing Saturation */
801  hcmd->curve_mapping.cur = 1;
802 }
803 
805 {
807 
809 }
810 
812 {
814  HueCorrectModifierData *hcmd_target = (HueCorrectModifierData *)target;
815 
817 }
818 
820  int height,
821  unsigned char *rect,
822  float *rect_float,
823  unsigned char *mask_rect,
824  const float *mask_rect_float,
825  void *data_v)
826 {
827  CurveMapping *curve_mapping = (CurveMapping *)data_v;
828  int x, y;
829 
830  for (y = 0; y < height; y++) {
831  for (x = 0; x < width; x++) {
832  int pixel_index = (y * width + x) * 4;
833  float pixel[3], result[3], mask[3] = {1.0f, 1.0f, 1.0f};
834  float hsv[3], f;
835 
836  if (rect_float) {
837  copy_v3_v3(pixel, rect_float + pixel_index);
838  }
839  else {
840  rgb_uchar_to_float(pixel, rect + pixel_index);
841  }
842 
843  rgb_to_hsv(pixel[0], pixel[1], pixel[2], hsv, hsv + 1, hsv + 2);
844 
845  /* adjust hue, scaling returned default 0.5 up to 1 */
846  f = BKE_curvemapping_evaluateF(curve_mapping, 0, hsv[0]);
847  hsv[0] += f - 0.5f;
848 
849  /* adjust saturation, scaling returned default 0.5 up to 1 */
850  f = BKE_curvemapping_evaluateF(curve_mapping, 1, hsv[0]);
851  hsv[1] *= (f * 2.0f);
852 
853  /* adjust value, scaling returned default 0.5 up to 1 */
854  f = BKE_curvemapping_evaluateF(curve_mapping, 2, hsv[0]);
855  hsv[2] *= (f * 2.0f);
856 
857  hsv[0] = hsv[0] - floorf(hsv[0]); /* mod 1.0 */
858  CLAMP(hsv[1], 0.0f, 1.0f);
859 
860  /* convert back to rgb */
861  hsv_to_rgb(hsv[0], hsv[1], hsv[2], result, result + 1, result + 2);
862 
863  if (mask_rect_float) {
864  copy_v3_v3(mask, mask_rect_float + pixel_index);
865  }
866  else if (mask_rect) {
867  rgb_uchar_to_float(mask, mask_rect + pixel_index);
868  }
869 
870  result[0] = pixel[0] * (1.0f - mask[0]) + result[0] * mask[0];
871  result[1] = pixel[1] * (1.0f - mask[1]) + result[1] * mask[1];
872  result[2] = pixel[2] * (1.0f - mask[2]) + result[2] * mask[2];
873 
874  if (rect_float) {
875  copy_v3_v3(rect_float + pixel_index, result);
876  }
877  else {
878  rgb_float_to_uchar(rect + pixel_index, result);
879  }
880  }
881  }
882 }
883 
884 static void hue_correct_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
885 {
887 
889 
891 }
892 
894  CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Hue Correct"), /* name */
895  "HueCorrectModifierData", /* struct_name */
896  sizeof(HueCorrectModifierData), /* struct_size */
897  hue_correct_init_data, /* init_data */
898  hue_correct_free_data, /* free_data */
899  hue_correct_copy_data, /* copy_data */
900  hue_correct_apply, /* apply */
901 };
902 
905 /* -------------------------------------------------------------------- */
909 typedef struct BrightContrastThreadData {
910  float bright;
911  float contrast;
913 
915  int height,
916  unsigned char *rect,
917  float *rect_float,
918  unsigned char *mask_rect,
919  const float *mask_rect_float,
920  void *data_v)
921 {
923  int x, y;
924 
925  float i;
926  int c;
927  float a, b, v;
928  float brightness = data->bright / 100.0f;
929  float contrast = data->contrast;
930  float delta = contrast / 200.0f;
931  /*
932  * The algorithm is by Werner D. Streidt
933  * (http://visca.com/ffactory/archives/5-99/msg00021.html)
934  * Extracted of OpenCV demhist.c
935  */
936  if (contrast > 0) {
937  a = 1.0f - delta * 2.0f;
938  a = 1.0f / max_ff(a, FLT_EPSILON);
939  b = a * (brightness - delta);
940  }
941  else {
942  delta *= -1;
943  a = max_ff(1.0f - delta * 2.0f, 0.0f);
944  b = a * brightness + delta;
945  }
946 
947  for (y = 0; y < height; y++) {
948  for (x = 0; x < width; x++) {
949  int pixel_index = (y * width + x) * 4;
950 
951  if (rect) {
952  unsigned char *pixel = rect + pixel_index;
953 
954  for (c = 0; c < 3; c++) {
955  i = (float)pixel[c] / 255.0f;
956  v = a * i + b;
957 
958  if (mask_rect) {
959  unsigned char *m = mask_rect + pixel_index;
960  float t = (float)m[c] / 255.0f;
961 
962  v = (float)pixel[c] / 255.0f * (1.0f - t) + v * t;
963  }
964 
965  pixel[c] = unit_float_to_uchar_clamp(v);
966  }
967  }
968  else if (rect_float) {
969  float *pixel = rect_float + pixel_index;
970 
971  for (c = 0; c < 3; c++) {
972  i = pixel[c];
973  v = a * i + b;
974 
975  if (mask_rect_float) {
976  const float *m = mask_rect_float + pixel_index;
977 
978  pixel[c] = pixel[c] * (1.0f - m[c]) + v * m[c];
979  }
980  else {
981  pixel[c] = v;
982  }
983  }
984  }
985  }
986  }
987 }
988 
989 static void brightcontrast_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
990 {
993 
994  data.bright = bcmd->bright;
995  data.contrast = bcmd->contrast;
996 
998 }
999 
1001  CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Bright/Contrast"), /* name */
1002  "BrightContrastModifierData", /* struct_name */
1003  sizeof(BrightContrastModifierData), /* struct_size */
1004  NULL, /* init_data */
1005  NULL, /* free_data */
1006  NULL, /* copy_data */
1007  brightcontrast_apply, /* apply */
1008 };
1009 
1012 /* -------------------------------------------------------------------- */
1017  int height,
1018  unsigned char *rect,
1019  float *rect_float,
1020  unsigned char *mask_rect,
1021  const float *mask_rect_float,
1022  void *UNUSED(data_v))
1023 {
1024  int x, y;
1025 
1026  if (rect && !mask_rect) {
1027  return;
1028  }
1029 
1030  if (rect_float && !mask_rect_float) {
1031  return;
1032  }
1033 
1034  for (y = 0; y < height; y++) {
1035  for (x = 0; x < width; x++) {
1036  int pixel_index = (y * width + x) * 4;
1037 
1038  if (rect) {
1039  unsigned char *pixel = rect + pixel_index;
1040  unsigned char *mask_pixel = mask_rect + pixel_index;
1041  unsigned char mask = min_iii(mask_pixel[0], mask_pixel[1], mask_pixel[2]);
1042 
1043  /* byte buffer is straight, so only affect on alpha itself,
1044  * this is the only way to alpha-over byte strip after
1045  * applying mask modifier.
1046  */
1047  pixel[3] = (float)(pixel[3] * mask) / 255.0f;
1048  }
1049  else if (rect_float) {
1050  int c;
1051  float *pixel = rect_float + pixel_index;
1052  const float *mask_pixel = mask_rect_float + pixel_index;
1053  float mask = min_fff(mask_pixel[0], mask_pixel[1], mask_pixel[2]);
1054 
1055  /* float buffers are premultiplied, so need to premul color
1056  * as well to make it easy to alpha-over masted strip.
1057  */
1058  for (c = 0; c < 4; c++) {
1059  pixel[c] = pixel[c] * mask;
1060  }
1061  }
1062  }
1063  }
1064 }
1065 
1066 static void maskmodifier_apply(struct SequenceModifierData *UNUSED(smd), ImBuf *ibuf, ImBuf *mask)
1067 {
1068  // SequencerMaskModifierData *bcmd = (SequencerMaskModifierData *)smd;
1069 
1071 }
1072 
1074  CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Mask"), /* name */
1075  "SequencerMaskModifierData", /* struct_name */
1076  sizeof(SequencerMaskModifierData), /* struct_size */
1077  NULL, /* init_data */
1078  NULL, /* free_data */
1079  NULL, /* copy_data */
1080  maskmodifier_apply, /* apply */
1081 };
1082 
1085 /* -------------------------------------------------------------------- */
1089 typedef struct AvgLogLum {
1092  float al;
1093  float auto_key;
1094  float lav;
1095  float cav[4];
1096  float igm;
1098 
1100 {
1102  /* Same as tonemap compositor node. */
1104  tmmd->key = 0.18f;
1105  tmmd->offset = 1.0f;
1106  tmmd->gamma = 1.0f;
1107  tmmd->intensity = 0.0f;
1108  tmmd->contrast = 0.0f;
1109  tmmd->adaptation = 1.0f;
1110  tmmd->correction = 0.0f;
1111 }
1112 
1114  int height,
1115  unsigned char *rect,
1116  float *rect_float,
1117  unsigned char *mask_rect,
1118  const float *mask_rect_float,
1119  void *data_v)
1120 {
1121  AvgLogLum *avg = (AvgLogLum *)data_v;
1122  for (int y = 0; y < height; y++) {
1123  for (int x = 0; x < width; x++) {
1124  int pixel_index = (y * width + x) * 4;
1125  float input[4], output[4], mask[3] = {1.0f, 1.0f, 1.0f};
1126  /* Get input value. */
1127  if (rect_float) {
1128  copy_v4_v4(input, &rect_float[pixel_index]);
1129  }
1130  else {
1131  straight_uchar_to_premul_float(input, &rect[pixel_index]);
1132  }
1134  copy_v4_v4(output, input);
1135  /* Get mask value. */
1136  if (mask_rect_float) {
1137  copy_v3_v3(mask, mask_rect_float + pixel_index);
1138  }
1139  else if (mask_rect) {
1140  rgb_uchar_to_float(mask, mask_rect + pixel_index);
1141  }
1142  /* Apply correction. */
1143  mul_v3_fl(output, avg->al);
1144  float dr = output[0] + avg->tmmd->offset;
1145  float dg = output[1] + avg->tmmd->offset;
1146  float db = output[2] + avg->tmmd->offset;
1147  output[0] /= ((dr == 0.0f) ? 1.0f : dr);
1148  output[1] /= ((dg == 0.0f) ? 1.0f : dg);
1149  output[2] /= ((db == 0.0f) ? 1.0f : db);
1150  const float igm = avg->igm;
1151  if (igm != 0.0f) {
1152  output[0] = powf(max_ff(output[0], 0.0f), igm);
1153  output[1] = powf(max_ff(output[1], 0.0f), igm);
1154  output[2] = powf(max_ff(output[2], 0.0f), igm);
1155  }
1156  /* Apply mask. */
1157  output[0] = input[0] * (1.0f - mask[0]) + output[0] * mask[0];
1158  output[1] = input[1] * (1.0f - mask[1]) + output[1] * mask[1];
1159  output[2] = input[2] * (1.0f - mask[2]) + output[2] * mask[2];
1160  /* Copy result back. */
1162  if (rect_float) {
1163  copy_v4_v4(&rect_float[pixel_index], output);
1164  }
1165  else {
1166  premul_float_to_straight_uchar(&rect[pixel_index], output);
1167  }
1168  }
1169  }
1170 }
1171 
1173  int height,
1174  unsigned char *rect,
1175  float *rect_float,
1176  unsigned char *mask_rect,
1177  const float *mask_rect_float,
1178  void *data_v)
1179 {
1180  AvgLogLum *avg = (AvgLogLum *)data_v;
1181  const float f = expf(-avg->tmmd->intensity);
1182  const float m = (avg->tmmd->contrast > 0.0f) ? avg->tmmd->contrast :
1183  (0.3f + 0.7f * powf(avg->auto_key, 1.4f));
1184  const float ic = 1.0f - avg->tmmd->correction, ia = 1.0f - avg->tmmd->adaptation;
1185  for (int y = 0; y < height; y++) {
1186  for (int x = 0; x < width; x++) {
1187  int pixel_index = (y * width + x) * 4;
1188  float input[4], output[4], mask[3] = {1.0f, 1.0f, 1.0f};
1189  /* Get input value. */
1190  if (rect_float) {
1191  copy_v4_v4(input, &rect_float[pixel_index]);
1192  }
1193  else {
1194  straight_uchar_to_premul_float(input, &rect[pixel_index]);
1195  }
1197  copy_v4_v4(output, input);
1198  /* Get mask value. */
1199  if (mask_rect_float) {
1200  copy_v3_v3(mask, mask_rect_float + pixel_index);
1201  }
1202  else if (mask_rect) {
1203  rgb_uchar_to_float(mask, mask_rect + pixel_index);
1204  }
1205  /* Apply correction. */
1207  float I_l = output[0] + ic * (L - output[0]);
1208  float I_g = avg->cav[0] + ic * (avg->lav - avg->cav[0]);
1209  float I_a = I_l + ia * (I_g - I_l);
1210  output[0] /= (output[0] + powf(f * I_a, m));
1211  I_l = output[1] + ic * (L - output[1]);
1212  I_g = avg->cav[1] + ic * (avg->lav - avg->cav[1]);
1213  I_a = I_l + ia * (I_g - I_l);
1214  output[1] /= (output[1] + powf(f * I_a, m));
1215  I_l = output[2] + ic * (L - output[2]);
1216  I_g = avg->cav[2] + ic * (avg->lav - avg->cav[2]);
1217  I_a = I_l + ia * (I_g - I_l);
1218  output[2] /= (output[2] + powf(f * I_a, m));
1219  /* Apply mask. */
1220  output[0] = input[0] * (1.0f - mask[0]) + output[0] * mask[0];
1221  output[1] = input[1] * (1.0f - mask[1]) + output[1] * mask[1];
1222  output[2] = input[2] * (1.0f - mask[2]) + output[2] * mask[2];
1223  /* Copy result back. */
1225  if (rect_float) {
1226  copy_v4_v4(&rect_float[pixel_index], output);
1227  }
1228  else {
1229  premul_float_to_straight_uchar(&rect[pixel_index], output);
1230  }
1231  }
1232  }
1233 }
1234 
1235 static void tonemapmodifier_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
1236 {
1238  AvgLogLum data;
1239  data.tmmd = tmmd;
1240  data.colorspace = (ibuf->rect_float != NULL) ? ibuf->float_colorspace : ibuf->rect_colorspace;
1241  float lsum = 0.0f;
1242  int p = ibuf->x * ibuf->y;
1243  float *fp = ibuf->rect_float;
1244  unsigned char *cp = (unsigned char *)ibuf->rect;
1245  float avl, maxl = -FLT_MAX, minl = FLT_MAX;
1246  const float sc = 1.0f / p;
1247  float Lav = 0.0f;
1248  float cav[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1249  while (p--) {
1250  float pixel[4];
1251  if (fp != NULL) {
1252  copy_v4_v4(pixel, fp);
1253  }
1254  else {
1255  straight_uchar_to_premul_float(pixel, cp);
1256  }
1258  float L = IMB_colormanagement_get_luminance(pixel);
1259  Lav += L;
1260  add_v3_v3(cav, pixel);
1261  lsum += logf(max_ff(L, 0.0f) + 1e-5f);
1262  maxl = (L > maxl) ? L : maxl;
1263  minl = (L < minl) ? L : minl;
1264  if (fp != NULL) {
1265  fp += 4;
1266  }
1267  else {
1268  cp += 4;
1269  }
1270  }
1271  data.lav = Lav * sc;
1272  mul_v3_v3fl(data.cav, cav, sc);
1273  maxl = logf(maxl + 1e-5f);
1274  minl = logf(minl + 1e-5f);
1275  avl = lsum * sc;
1276  data.auto_key = (maxl > minl) ? ((maxl - avl) / (maxl - minl)) : 1.0f;
1277  float al = expf(avl);
1278  data.al = (al == 0.0f) ? 0.0f : (tmmd->key / al);
1279  data.igm = (tmmd->gamma == 0.0f) ? 1.0f : (1.0f / tmmd->gamma);
1280 
1281  if (tmmd->type == SEQ_TONEMAP_RD_PHOTORECEPTOR) {
1283  }
1284  else /* if (tmmd->type == SEQ_TONEMAP_RD_SIMPLE) */ {
1286  }
1287 }
1288 
1290  CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Tonemap"), /* name */
1291  "SequencerTonemapModifierData", /* struct_name */
1292  sizeof(SequencerTonemapModifierData), /* struct_size */
1293  tonemapmodifier_init_data, /* init_data */
1294  NULL, /* free_data */
1295  NULL, /* copy_data */
1296  tonemapmodifier_apply, /* apply */
1297 };
1298 
1301 /* -------------------------------------------------------------------- */
1306 {
1307 #define INIT_TYPE(typeName) (modifiersTypes[seqModifierType_##typeName] = &seqModifier_##typeName)
1308 
1309  INIT_TYPE(ColorBalance);
1310  INIT_TYPE(Curves);
1313  INIT_TYPE(Mask);
1314  INIT_TYPE(WhiteBalance);
1315  INIT_TYPE(Tonemap);
1316 
1317 #undef INIT_TYPE
1318 }
1319 
1321 {
1322  if (!modifierTypesInit) {
1324  modifierTypesInit = true;
1325  }
1326 
1327  return modifiersTypes[type];
1328 }
1329 
1331 {
1332  SequenceModifierData *smd;
1334 
1335  smd = MEM_callocN(smti->struct_size, "sequence modifier");
1336 
1337  smd->type = type;
1339 
1340  if (!name || !name[0]) {
1341  BLI_strncpy(smd->name, smti->name, sizeof(smd->name));
1342  }
1343  else {
1344  BLI_strncpy(smd->name, name, sizeof(smd->name));
1345  }
1346 
1347  BLI_addtail(&seq->modifiers, smd);
1348 
1349  SEQ_modifier_unique_name(seq, smd);
1350 
1351  if (smti->init_data) {
1352  smti->init_data(smd);
1353  }
1354 
1355  return smd;
1356 }
1357 
1359 {
1360  if (BLI_findindex(&seq->modifiers, smd) == -1) {
1361  return false;
1362  }
1363 
1364  BLI_remlink(&seq->modifiers, smd);
1365  SEQ_modifier_free(smd);
1366 
1367  return true;
1368 }
1369 
1371 {
1372  SequenceModifierData *smd, *smd_next;
1373 
1374  for (smd = seq->modifiers.first; smd; smd = smd_next) {
1375  smd_next = smd->next;
1376  SEQ_modifier_free(smd);
1377  }
1378 
1380 }
1381 
1383 {
1385 
1386  if (smti && smti->free_data) {
1387  smti->free_data(smd);
1388  }
1389 
1390  MEM_freeN(smd);
1391 }
1392 
1394 {
1396 
1397  BLI_uniquename(&seq->modifiers,
1398  smd,
1400  '.',
1401  offsetof(SequenceModifierData, name),
1402  sizeof(smd->name));
1403 }
1404 
1406 {
1407  return BLI_findstring(&(seq->modifiers), name, offsetof(SequenceModifierData, name));
1408 }
1409 
1411  Sequence *seq,
1412  ImBuf *ibuf,
1413  int timeline_frame)
1414 {
1415  SequenceModifierData *smd;
1416  ImBuf *processed_ibuf = ibuf;
1417 
1418  if (seq->modifiers.first && (seq->flag & SEQ_USE_LINEAR_MODIFIERS)) {
1419  processed_ibuf = IMB_dupImBuf(ibuf);
1420  SEQ_render_imbuf_from_sequencer_space(context->scene, processed_ibuf);
1421  }
1422 
1423  for (smd = seq->modifiers.first; smd; smd = smd->next) {
1425 
1426  /* could happen if modifier is being removed or not exists in current version of blender */
1427  if (!smti) {
1428  continue;
1429  }
1430 
1431  /* modifier is muted, do nothing */
1432  if (smd->flag & SEQUENCE_MODIFIER_MUTE) {
1433  continue;
1434  }
1435 
1436  if (smti->apply) {
1437  int frame_offset;
1438  if (smd->mask_time == SEQUENCE_MASK_TIME_RELATIVE) {
1439  frame_offset = seq->start;
1440  }
1441  else /*if (smd->mask_time == SEQUENCE_MASK_TIME_ABSOLUTE)*/ {
1442  frame_offset = smd->mask_id ? ((Mask *)smd->mask_id)->sfra : 0;
1443  }
1444 
1446  smd, context, timeline_frame, frame_offset, ibuf->rect_float != NULL);
1447 
1448  if (processed_ibuf == ibuf) {
1449  processed_ibuf = IMB_dupImBuf(ibuf);
1450  }
1451 
1452  smti->apply(smd, processed_ibuf, mask);
1453 
1454  if (mask) {
1456  }
1457  }
1458  }
1459 
1460  if (seq->modifiers.first && (seq->flag & SEQ_USE_LINEAR_MODIFIERS)) {
1461  seq_imbuf_to_sequencer_space(context->scene, processed_ibuf, false);
1462  }
1463 
1464  return processed_ibuf;
1465 }
1466 
1468 {
1469  SequenceModifierData *smd;
1470 
1471  for (smd = seq->modifiers.first; smd; smd = smd->next) {
1472  SequenceModifierData *smdn;
1474 
1475  smdn = MEM_dupallocN(smd);
1476 
1477  if (smti && smti->copy_data) {
1478  smti->copy_data(smdn, smd);
1479  }
1480 
1481  smdn->next = smdn->prev = NULL;
1482  BLI_addtail(&seqn->modifiers, smdn);
1483  }
1484 }
1485 
1487 {
1489 }
1490 
1493 /* -------------------------------------------------------------------- */
1498 {
1499  LISTBASE_FOREACH (SequenceModifierData *, smd, modbase) {
1500  const SequenceModifierTypeInfo *smti = SEQ_modifier_type_info_get(smd->type);
1501 
1502  if (smti) {
1503  BLO_write_struct_by_name(writer, smti->struct_name, smd);
1504 
1505  if (smd->type == seqModifierType_Curves) {
1506  CurvesModifierData *cmd = (CurvesModifierData *)smd;
1507 
1509  }
1510  else if (smd->type == seqModifierType_HueCorrect) {
1512 
1514  }
1515  }
1516  else {
1517  BLO_write_struct(writer, SequenceModifierData, smd);
1518  }
1519  }
1520 }
1521 
1523 {
1524  BLO_read_list(reader, lb);
1525 
1526  LISTBASE_FOREACH (SequenceModifierData *, smd, lb) {
1527  if (smd->mask_sequence) {
1528  BLO_read_data_address(reader, &smd->mask_sequence);
1529  }
1530 
1531  if (smd->type == seqModifierType_Curves) {
1532  CurvesModifierData *cmd = (CurvesModifierData *)smd;
1533 
1535  }
1536  else if (smd->type == seqModifierType_HueCorrect) {
1538 
1540  }
1541  }
1542 }
1543 
1545 {
1546  LISTBASE_FOREACH (SequenceModifierData *, smd, lb) {
1547  if (smd->mask_id) {
1548  BLO_read_id_address(reader, scene->id.lib, &smd->mask_id);
1549  }
1550  }
1551 }
1552 
typedef float(TangentPoint)[2]
void BKE_curvemapping_evaluate_premulRGBF(const struct CurveMapping *cumap, float vecout[3], const float vecin[3])
void BKE_curvemapping_free_data(struct CurveMapping *cumap)
Definition: colortools.c:99
void BKE_curvemapping_init(struct CurveMapping *cumap)
Definition: colortools.c:1200
void BKE_curvemapping_set_black_white(struct CurveMapping *cumap, const float black[3], const float white[3])
Definition: colortools.c:168
void BKE_curvemapping_set_defaults(struct CurveMapping *cumap, int tot, float minx, float miny, float maxx, float maxy)
Definition: colortools.c:53
float BKE_curvemapping_evaluateF(const struct CurveMapping *cumap, int cur, float value)
void BKE_curvemapping_blend_read(struct BlendDataReader *reader, struct CurveMapping *cumap)
Definition: colortools.c:1252
void BKE_curvemapping_premultiply(struct CurveMapping *cumap, int restore)
Definition: colortools.c:805
void BKE_curvemap_reset(struct CurveMap *cuma, const struct rctf *clipr, int preset, int slope)
void BKE_curvemapping_blend_write(struct BlendWriter *writer, const struct CurveMapping *cumap)
@ CURVEMAP_SLOPE_POSITIVE
void BKE_curvemapping_copy_data(struct CurveMapping *target, const struct CurveMapping *cumap)
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:128
void * BLI_findstring(const struct ListBase *listbase, const char *id, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:133
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float max_ff(float a, float b)
MINLINE int min_iii(int a, int b, int c)
MINLINE float min_fff(float a, float b, float c)
MINLINE void straight_uchar_to_premul_float(float result[4], const unsigned char color[4])
void rgb_to_hsv(float r, float g, float b, float *r_h, float *r_s, float *r_v)
Definition: math_color.c:229
void hsv_to_rgb(float h, float s, float v, float *r_r, float *r_g, float *r_b)
Definition: math_color.c:31
void rgb_uchar_to_float(float r_col[3], const unsigned char col_ub[3])
Definition: math_color.c:407
void rgb_float_to_uchar(unsigned char r_col[3], const float col_f[3])
Definition: math_color.c:422
MINLINE void premul_float_to_straight_uchar(unsigned char *result, const float color[4])
#define MINLINE
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void mul_v3_v3(float r[3], const float a[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
bool BLI_uniquename(struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t len)
Definition: string_utils.c:381
#define UNUSED(x)
#define ELEM(...)
#define BLO_read_data_address(reader, ptr_p)
void BLO_write_struct_by_name(BlendWriter *writer, const char *struct_name, const void *data_ptr)
Definition: writefile.c:1291
#define BLO_write_struct(writer, struct_name, data_ptr)
void BLO_read_list(BlendDataReader *reader, struct ListBase *list)
Definition: readfile.c:5654
#define BLO_read_id_address(reader, lib, id_ptr_p)
#define CTX_N_(context, msgid)
#define BLT_I18NCONTEXT_ID_SEQUENCE
#define CTX_DATA_(context, msgid)
@ CURVE_PRESET_MID9
@ SEQ_USE_LINEAR_MODIFIERS
#define SEQ_COLOR_BALANCE_INVERSE_GAMMA
struct WhiteBalanceModifierData WhiteBalanceModifierData
@ SEQUENCE_MASK_INPUT_STRIP
@ SEQUENCE_MASK_INPUT_ID
struct ColorBalanceModifierData ColorBalanceModifierData
struct CurvesModifierData CurvesModifierData
@ SEQUENCE_MODIFIER_MUTE
@ SEQUENCE_MODIFIER_EXPANDED
@ SEQUENCE_MASK_TIME_RELATIVE
struct SequencerTonemapModifierData SequencerTonemapModifierData
@ NUM_SEQUENCE_MODIFIER_TYPES
@ seqModifierType_Curves
@ seqModifierType_HueCorrect
#define SEQ_COLOR_BALANCE_INVERSE_GAIN
struct HueCorrectModifierData HueCorrectModifierData
@ SEQ_TONEMAP_RD_PHOTORECEPTOR
#define SEQ_COLOR_BALANCE_INVERSE_LIFT
struct BrightContrastModifierData BrightContrastModifierData
@ SEQ_TYPE_SOUND_RAM
@ SEQ_TYPE_SOUND_HD
struct SequencerMaskModifierData SequencerMaskModifierData
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_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 GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
BLI_INLINE float IMB_colormanagement_get_luminance(const float rgb[3])
void IMB_colormanagement_scene_linear_to_colorspace_v3(float pixel[3], struct ColorSpace *colorspace)
void IMB_colormanagement_colorspace_to_scene_linear_v3(float pixel[3], struct ColorSpace *colorspace)
void IMB_float_from_rect(struct ImBuf *ibuf)
Definition: divers.c:780
struct ImBuf * IMB_dupImBuf(const struct ImBuf *ibuf1)
void IMB_rect_from_float(struct ImBuf *ibuf)
Definition: divers.c:720
void IMB_freeImBuf(struct ImBuf *ibuf)
Definition: allocimbuf.c:211
void imb_freerectImBuf(struct ImBuf *ibuf)
Definition: allocimbuf.c:115
void IMB_processor_apply_threaded(int buffer_lines, int handle_size, void *init_customdata, void(init_handle)(void *handle, int start_line, int tot_line, void *customdata), void *(do_thread)(void *))
Definition: imageprocess.c:362
bool imb_addrectfloatImBuf(struct ImBuf *ibuf)
Definition: allocimbuf.c:386
Contains defines and structs used throughout the imbuf module.
Read Guarded memory(de)allocation.
static void init_data(ModifierData *md)
Group RGB to Bright Vector Camera CLAMP
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel Split ID Combine Luminance Directional Alpha Distance HueCorrect
Group RGB to Bright Vector Curves
Group RGB to BrightContrast
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel Split ID Combine Luminance Directional Alpha Tonemap
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define output
static void mul(btAlignedObjectArray< T > &items, const Q &value)
Scene scene
void * user_data
#define logf(x)
#define expf(x)
#define powf(x, y)
#define floorf(x)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
MINLINE unsigned char unit_float_to_uchar_clamp(float val)
static ulong state[N]
#define L
static unsigned c
Definition: RandGen.cpp:97
static unsigned a[3]
Definition: RandGen.cpp:92
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
Definition: rall1d.h:359
ImBuf * seq_render_mask(const SeqRenderData *context, Mask *mask, float frame_index, bool make_float)
Definition: render.c:1301
ImBuf * seq_render_strip(const SeqRenderData *context, SeqRenderState *state, Sequence *seq, float timeline_frame)
Definition: render.c:1774
void seq_render_state_init(SeqRenderState *state)
Definition: render.c:237
void seq_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, bool make_float)
Definition: render.c:108
void SEQ_render_imbuf_from_sequencer_space(Scene *scene, ImBuf *ibuf)
Definition: render.c:174
struct SELECTID_Context context
Definition: select_engine.c:47
struct ColorBalanceThread ColorBalanceThread
static void hue_correct_apply_threaded(int width, int height, unsigned char *rect, float *rect_float, unsigned char *mask_rect, const float *mask_rect_float, void *data_v)
static void curves_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
void SEQ_modifier_blend_write(BlendWriter *writer, ListBase *modbase)
bool SEQ_modifier_remove(Sequence *seq, SequenceModifierData *smd)
struct BrightContrastThreadData BrightContrastThreadData
static void tonemapmodifier_init_data(SequenceModifierData *smd)
static void whiteBalance_apply_threaded(int width, int height, unsigned char *rect, float *rect_float, unsigned char *mask_rect, const float *mask_rect_float, void *data_v)
void(* modifier_apply_threaded_cb)(int width, int height, unsigned char *rect, float *rect_float, unsigned char *mask_rect, const float *mask_rect_float, void *data_v)
struct WhiteBalanceThreadData WhiteBalanceThreadData
static void hue_correct_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
static void modifier_apply_threaded(ImBuf *ibuf, ImBuf *mask, modifier_apply_threaded_cb apply_callback, void *user_data)
SequenceModifierData * SEQ_modifier_new(Sequence *seq, const char *name, int type)
static void hue_correct_free_data(SequenceModifierData *smd)
void SEQ_modifier_free(SequenceModifierData *smd)
ImBuf * SEQ_modifier_apply_stack(const SeqRenderData *context, Sequence *seq, ImBuf *ibuf, int timeline_frame)
static void tonemapmodifier_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
static void maskmodifier_apply(struct SequenceModifierData *UNUSED(smd), ImBuf *ibuf, ImBuf *mask)
MINLINE float color_balance_fl(float in, const float lift, const float gain, const float gamma, const float mul)
static void sequence_modifier_type_info_init(void)
void SEQ_modifier_blend_read_lib(BlendLibReader *reader, Scene *scene, ListBase *lb)
static void * modifier_do_thread(void *thread_data_v)
static void modifier_color_balance_apply(StripColorBalance *cb, ImBuf *ibuf, float mul, bool make_float, ImBuf *mask_input)
#define INIT_TYPE(typeName)
static SequenceModifierTypeInfo seqModifier_HueCorrect
static void brightcontrast_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
struct ModifierInitData ModifierInitData
static ImBuf * modifier_mask_get(SequenceModifierData *smd, const SeqRenderData *context, int timeline_frame, int fra_offset, bool make_float)
static void tonemapmodifier_apply_threaded_simple(int width, int height, unsigned char *rect, float *rect_float, unsigned char *mask_rect, const float *mask_rect_float, void *data_v)
SequenceModifierData * SEQ_modifier_find_by_name(Sequence *seq, const char *name)
static void hue_correct_init_data(SequenceModifierData *smd)
static SequenceModifierTypeInfo seqModifier_Curves
void SEQ_modifier_clear(Sequence *seq)
static void hue_correct_copy_data(SequenceModifierData *target, SequenceModifierData *smd)
static void curves_copy_data(SequenceModifierData *target, SequenceModifierData *smd)
struct AvgLogLum AvgLogLum
static void maskmodifier_apply_threaded(int width, int height, unsigned char *rect, float *rect_float, unsigned char *mask_rect, const float *mask_rect_float, void *UNUSED(data_v))
static void curves_free_data(SequenceModifierData *smd)
void SEQ_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb)
static void brightcontrast_apply_threaded(int width, int height, unsigned char *rect, float *rect_float, unsigned char *mask_rect, const float *mask_rect_float, void *data_v)
static SequenceModifierTypeInfo seqModifier_Mask
static SequenceModifierTypeInfo seqModifier_ColorBalance
static StripColorBalance calc_cb(StripColorBalance *cb_)
static SequenceModifierTypeInfo seqModifier_WhiteBalance
static SequenceModifierTypeInfo seqModifier_BrightContrast
static void * color_balance_do_thread(void *thread_data_v)
const SequenceModifierTypeInfo * SEQ_modifier_type_info_get(int type)
static void curves_init_data(SequenceModifierData *smd)
static SequenceModifierTypeInfo * modifiersTypes[NUM_SEQUENCE_MODIFIER_TYPES]
void SEQ_modifier_list_copy(Sequence *seqn, Sequence *seq)
static void make_cb_table_float(float lift, float gain, float gamma, float *table, float mul)
static void whiteBalance_apply(SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
static void color_balance_byte_float(StripColorBalance *cb_, unsigned char *rect, float *rect_float, unsigned char *mask_rect, int width, int height, float mul)
static void whiteBalance_init_data(SequenceModifierData *smd)
static SequenceModifierTypeInfo seqModifier_Tonemap
static void modifier_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v)
int SEQ_sequence_supports_modifiers(Sequence *seq)
struct ColorBalanceInitData ColorBalanceInitData
static ImBuf * modifier_render_mask_input(const SeqRenderData *context, int mask_input_type, Sequence *mask_sequence, Mask *mask_id, int timeline_frame, int fra_offset, bool make_float)
struct ModifierThread ModifierThread
static void color_balance_byte_byte(StripColorBalance *cb_, unsigned char *rect, unsigned char *mask_rect, int width, int height, float mul)
static void colorBalance_init_data(SequenceModifierData *smd)
static void color_balance_float_float(StripColorBalance *cb_, float *rect_float, const float *mask_rect_float, int width, int height, float mul)
static void curves_apply_threaded(int width, int height, unsigned char *rect, float *rect_float, unsigned char *mask_rect, const float *mask_rect_float, void *data_v)
static void colorBalance_apply(SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
void SEQ_modifier_unique_name(Sequence *seq, SequenceModifierData *smd)
static void color_balance_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v)
static void tonemapmodifier_apply_threaded_photoreceptor(int width, int height, unsigned char *rect, float *rect_float, unsigned char *mask_rect, const float *mask_rect_float, void *data_v)
static bool modifierTypesInit
SequencerTonemapModifierData * tmmd
struct ColorSpace * colorspace
StripColorBalance color_balance
char name[MAX_COLORSPACE_NAME]
CurveMap cm[4]
struct CurveMapping curve_mapping
struct CurveMapping curve_mapping
struct Library * lib
Definition: DNA_ID.h:277
struct ColorSpace * rect_colorspace
unsigned int * rect
float * rect_float
struct ColorSpace * float_colorspace
void * first
Definition: DNA_listBase.h:47
int sfra
modifier_apply_threaded_cb apply_callback
modifier_apply_threaded_cb apply_callback
unsigned char * mask_rect
struct SequenceModifierData * next
struct SequenceModifierData * prev
struct Sequence * mask_sequence
void(* init_data)(struct SequenceModifierData *smd)
Definition: SEQ_modifier.h:51
void(* free_data)(struct SequenceModifierData *smd)
Definition: SEQ_modifier.h:57
void(* apply)(struct SequenceModifierData *smd, struct ImBuf *ibuf, struct ImBuf *mask)
Definition: SEQ_modifier.h:63
void(* copy_data)(struct SequenceModifierData *smd, struct SequenceModifierData *target)
Definition: SEQ_modifier.h:60
ListBase modifiers
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)