Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2012-08-21 22:09:56 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-08-21 22:09:56 +0400
commit0fdc4a1d63933d5bb8bce4b860bd6517e900a09b (patch)
tree0a0eebd8fde83bd5968b62e8c9ef30345acdc75f /source/blender/blenkernel/intern
parent8512f7682547df2c541a6e59ac52dc60db034961 (diff)
parentdd21def25d2ddfa6ca04a7d11481a84b76e2c0ab (diff)
svn merge ^/trunk/blender -r50014:50094
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/brush.c5
-rw-r--r--source/blender/blenkernel/intern/colortools.c177
-rw-r--r--source/blender/blenkernel/intern/font.c113
-rw-r--r--source/blender/blenkernel/intern/image.c4
-rw-r--r--source/blender/blenkernel/intern/mask.c16
-rw-r--r--source/blender/blenkernel/intern/mask_rasterize.c45
-rw-r--r--source/blender/blenkernel/intern/node.c98
-rw-r--r--source/blender/blenkernel/intern/packedFile.c12
-rw-r--r--source/blender/blenkernel/intern/seqcache.c122
-rw-r--r--source/blender/blenkernel/intern/seqmodifier.c550
-rw-r--r--source/blender/blenkernel/intern/sequencer.c428
-rw-r--r--source/blender/blenkernel/intern/texture.c2
-rw-r--r--source/blender/blenkernel/intern/world.c3
13 files changed, 1233 insertions, 342 deletions
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 468861242d0..fde95e0767e 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -421,7 +421,7 @@ void BKE_brush_curve_preset(Brush *b, /*CurveMappingPreset*/ int preset)
b->curve->preset = preset;
curvemap_reset(cm, &b->curve->clipr, b->curve->preset, CURVEMAP_SLOPE_NEGATIVE);
- curvemapping_changed(b->curve, 0);
+ curvemapping_changed(b->curve, FALSE);
}
int BKE_brush_texture_set_nr(Brush *brush, int nr)
@@ -1253,7 +1253,9 @@ float BKE_brush_curve_strength_clamp(Brush *br, float p, const float len)
if (p >= len) return 0;
else p = p / len;
+ curvemapping_initialize(br->curve);
p = curvemapping_evaluateF(br->curve, 0, p);
+
if (p < 0.0f) p = 0.0f;
else if (p > 1.0f) p = 1.0f;
return p;
@@ -1267,6 +1269,7 @@ float BKE_brush_curve_strength(Brush *br, float p, const float len)
else
p = p / len;
+ curvemapping_initialize(br->curve);
return curvemapping_evaluateF(br->curve, 0, p);
}
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 20fae973756..85d28f68034 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -56,13 +56,11 @@
/* ***************** operations on full struct ************* */
-CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy)
+void curvemapping_set_defaults(CurveMapping *cumap, int tot, float minx, float miny, float maxx, float maxy)
{
- CurveMapping *cumap;
int a;
float clipminx, clipminy, clipmaxx, clipmaxy;
- cumap = MEM_callocN(sizeof(CurveMapping), "new curvemap");
cumap->flag = CUMA_DO_CLIP;
if (tot == 4) cumap->cur = 3; /* rhms, hack for 'col' curve? */
@@ -89,58 +87,84 @@ CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, floa
}
cumap->changed_timestamp = 0;
+}
+
+CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy)
+{
+ CurveMapping *cumap;
+
+ cumap = MEM_callocN(sizeof(CurveMapping), "new curvemap");
+
+ curvemapping_set_defaults(cumap, tot, minx, miny, maxx, maxy);
return cumap;
}
-void curvemapping_free(CurveMapping *cumap)
+void curvemapping_free_data(CurveMapping *cumap)
{
int a;
-
+
+ for (a = 0; a < CM_TOT; a++) {
+ if (cumap->cm[a].curve) MEM_freeN(cumap->cm[a].curve);
+ if (cumap->cm[a].table) MEM_freeN(cumap->cm[a].table);
+ if (cumap->cm[a].premultable) MEM_freeN(cumap->cm[a].premultable);
+ }
+}
+
+void curvemapping_free(CurveMapping *cumap)
+{
if (cumap) {
- for (a = 0; a < CM_TOT; a++) {
- if (cumap->cm[a].curve) MEM_freeN(cumap->cm[a].curve);
- if (cumap->cm[a].table) MEM_freeN(cumap->cm[a].table);
- if (cumap->cm[a].premultable) MEM_freeN(cumap->cm[a].premultable);
- }
+ curvemapping_free_data(cumap);
MEM_freeN(cumap);
}
}
-CurveMapping *curvemapping_copy(CurveMapping *cumap)
+void curvemapping_copy_data(CurveMapping *target, CurveMapping *cumap)
{
int a;
-
+
+ *target = *cumap;
+
+ for (a = 0; a < CM_TOT; a++) {
+ if (cumap->cm[a].curve)
+ target->cm[a].curve = MEM_dupallocN(cumap->cm[a].curve);
+ if (cumap->cm[a].table)
+ target->cm[a].table = MEM_dupallocN(cumap->cm[a].table);
+ if (cumap->cm[a].premultable)
+ target->cm[a].premultable = MEM_dupallocN(cumap->cm[a].premultable);
+ }
+}
+
+CurveMapping *curvemapping_copy(CurveMapping *cumap)
+{
if (cumap) {
CurveMapping *cumapn = MEM_dupallocN(cumap);
- for (a = 0; a < CM_TOT; a++) {
- if (cumap->cm[a].curve)
- cumapn->cm[a].curve = MEM_dupallocN(cumap->cm[a].curve);
- if (cumap->cm[a].table)
- cumapn->cm[a].table = MEM_dupallocN(cumap->cm[a].table);
- if (cumap->cm[a].premultable)
- cumapn->cm[a].premultable = MEM_dupallocN(cumap->cm[a].premultable);
- }
+ curvemapping_copy_data(cumapn, cumap);
return cumapn;
}
return NULL;
}
-void curvemapping_set_black_white(CurveMapping *cumap, const float black[3], const float white[3])
+void curvemapping_set_black_white_ex(const float black[3], const float white[3], float r_bwmul[3])
{
int a;
-
- if (white)
+
+ for (a = 0; a < 3; a++) {
+ const float delta = maxf(white[a] - black[a], 1e-5f);
+ r_bwmul[a] = 1.0f / delta;
+ }
+}
+
+void curvemapping_set_black_white(CurveMapping *cumap, const float black[3], const float white[3])
+{
+ if (white) {
copy_v3_v3(cumap->white, white);
- if (black)
+ }
+ if (black) {
copy_v3_v3(cumap->black, black);
-
- for (a = 0; a < 3; a++) {
- if (cumap->white[a] == cumap->black[a])
- cumap->bwmul[a] = 0.0f;
- else
- cumap->bwmul[a] = 1.0f / (cumap->white[a] - cumap->black[a]);
- }
+ }
+
+ curvemapping_set_black_white_ex(cumap->black, cumap->white, cumap->bwmul);
}
/* ***************** operations on single curve ************* */
@@ -173,7 +197,7 @@ void curvemap_remove_point(CurveMap *cuma, CurveMapPoint *point)
}
/* removes with flag set */
-void curvemap_remove(CurveMap *cuma, int flag)
+void curvemap_remove(CurveMap *cuma, const short flag)
{
CurveMapPoint *cmp = MEM_mallocN((cuma->totpoint) * sizeof(CurveMapPoint), "curve points");
int a, b, removed = 0;
@@ -416,7 +440,7 @@ static void calchandle_curvemap(BezTriple *bezt, BezTriple *prev, BezTriple *nex
/* in X, out Y.
* X is presumed to be outside first or last */
-static float curvemap_calc_extend(CurveMap *cuma, float x, const float first[2], const float last[2])
+static float curvemap_calc_extend(const CurveMap *cuma, float x, const float first[2], const float last[2])
{
if (x <= first[0]) {
if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
@@ -682,12 +706,12 @@ void curvemapping_changed(CurveMapping *cumap, int rem_doubles)
dy = cmp[a].y - cmp[a + 1].y;
if (sqrtf(dx * dx + dy * dy) < thresh) {
if (a == 0) {
- cmp[a + 1].flag |= 2;
+ cmp[a + 1].flag |= CUMA_VECTOR;
if (cmp[a + 1].flag & CUMA_SELECT)
cmp[a].flag |= CUMA_SELECT;
}
else {
- cmp[a].flag |= 2;
+ cmp[a].flag |= CUMA_VECTOR;
if (cmp[a].flag & CUMA_SELECT)
cmp[a + 1].flag |= CUMA_SELECT;
}
@@ -707,7 +731,7 @@ void curvemapping_changed_all(CurveMapping *cumap)
for (a = 0; a < CM_TOT; a++) {
if (cumap->cm[a].curve) {
cumap->cur = a;
- curvemapping_changed(cumap, 0);
+ curvemapping_changed(cumap, FALSE);
}
}
@@ -715,7 +739,7 @@ void curvemapping_changed_all(CurveMapping *cumap)
}
/* table should be verified */
-float curvemap_evaluateF(CurveMap *cuma, float value)
+float curvemap_evaluateF(const CurveMap *cuma, float value)
{
float fi;
int i;
@@ -737,49 +761,67 @@ float curvemap_evaluateF(CurveMap *cuma, float value)
}
/* works with curve 'cur' */
-float curvemapping_evaluateF(CurveMapping *cumap, int cur, float value)
+float curvemapping_evaluateF(const CurveMapping *cumap, int cur, float value)
{
- CurveMap *cuma = cumap->cm + cur;
-
- /* allocate or bail out */
- if (cuma->table == NULL) {
- curvemap_make_table(cuma, &cumap->clipr);
- if (cuma->table == NULL)
- return 1.0f - value;
- }
+ const CurveMap *cuma = cumap->cm + cur;
return curvemap_evaluateF(cuma, value);
}
/* vector case */
-void curvemapping_evaluate3F(CurveMapping *cumap, float vecout[3], const float vecin[3])
+void curvemapping_evaluate3F(const CurveMapping *cumap, float vecout[3], const float vecin[3])
{
- vecout[0] = curvemapping_evaluateF(cumap, 0, vecin[0]);
- vecout[1] = curvemapping_evaluateF(cumap, 1, vecin[1]);
- vecout[2] = curvemapping_evaluateF(cumap, 2, vecin[2]);
+ vecout[0] = curvemap_evaluateF(&cumap->cm[0], vecin[0]);
+ vecout[1] = curvemap_evaluateF(&cumap->cm[1], vecin[1]);
+ vecout[2] = curvemap_evaluateF(&cumap->cm[2], vecin[2]);
}
/* RGB case, no black/white points, no premult */
-void curvemapping_evaluateRGBF(CurveMapping *cumap, float vecout[3], const float vecin[3])
+void curvemapping_evaluateRGBF(const CurveMapping *cumap, float vecout[3], const float vecin[3])
{
- vecout[0] = curvemapping_evaluateF(cumap, 0, curvemapping_evaluateF(cumap, 3, vecin[0]));
- vecout[1] = curvemapping_evaluateF(cumap, 1, curvemapping_evaluateF(cumap, 3, vecin[1]));
- vecout[2] = curvemapping_evaluateF(cumap, 2, curvemapping_evaluateF(cumap, 3, vecin[2]));
+ vecout[0] = curvemap_evaluateF(&cumap->cm[0], curvemap_evaluateF(&cumap->cm[3], vecin[0]));
+ vecout[1] = curvemap_evaluateF(&cumap->cm[1], curvemap_evaluateF(&cumap->cm[3], vecin[1]));
+ vecout[2] = curvemap_evaluateF(&cumap->cm[2], curvemap_evaluateF(&cumap->cm[3], vecin[2]));
}
+/** same as #curvemapping_evaluate_premulRGBF
+ * but black/bwmul are passed as args for the compositor
+ * where they can change per pixel.
+ *
+ * Use in conjunction with #curvemapping_set_black_white_ex
+ *
+ * \param black Use instead of cumap->black
+ * \param bwmul Use instead of cumap->bwmul
+ */
+void curvemapping_evaluate_premulRGBF_ex(const CurveMapping *cumap, float vecout[3], const float vecin[3],
+ const float black[3], const float bwmul[3])
+{
+ vecout[0] = curvemap_evaluateF(&cumap->cm[0], (vecin[0] - black[0]) * bwmul[0]);
+ vecout[1] = curvemap_evaluateF(&cumap->cm[1], (vecin[1] - black[1]) * bwmul[1]);
+ vecout[2] = curvemap_evaluateF(&cumap->cm[2], (vecin[2] - black[2]) * bwmul[2]);
+}
/* RGB with black/white points and premult. tables are checked */
-void curvemapping_evaluate_premulRGBF(CurveMapping *cumap, float vecout[3], const float vecin[3])
+void curvemapping_evaluate_premulRGBF(const CurveMapping *cumap, float vecout[3], const float vecin[3])
{
- float fac;
-
- fac = (vecin[0] - cumap->black[0]) * cumap->bwmul[0];
- vecout[0] = curvemap_evaluateF(cumap->cm, fac);
-
- fac = (vecin[1] - cumap->black[1]) * cumap->bwmul[1];
- vecout[1] = curvemap_evaluateF(cumap->cm + 1, fac);
-
- fac = (vecin[2] - cumap->black[2]) * cumap->bwmul[2];
- vecout[2] = curvemap_evaluateF(cumap->cm + 2, fac);
+ vecout[0] = curvemap_evaluateF(&cumap->cm[0], (vecin[0] - cumap->black[0]) * cumap->bwmul[0]);
+ vecout[1] = curvemap_evaluateF(&cumap->cm[1], (vecin[1] - cumap->black[1]) * cumap->bwmul[1]);
+ vecout[2] = curvemap_evaluateF(&cumap->cm[2], (vecin[2] - cumap->black[2]) * cumap->bwmul[2]);
+}
+
+/* same as above, byte version */
+void curvemapping_evaluate_premulRGB(const CurveMapping *cumap, unsigned char vecout_byte[3], const unsigned char vecin_byte[3])
+{
+ float vecin[3], vecout[3];
+
+ vecin[0] = (float) vecin_byte[0] / 255.0f;
+ vecin[1] = (float) vecin_byte[1] / 255.0f;
+ vecin[2] = (float) vecin_byte[2] / 255.0f;
+
+ curvemapping_evaluate_premulRGBF(cumap, vecout, vecin);
+
+ vecout_byte[0] = FTOCHAR(vecout[0]);
+ vecout_byte[1] = FTOCHAR(vecout[1]);
+ vecout_byte[2] = FTOCHAR(vecout[2]);
}
@@ -840,7 +882,7 @@ void curvemapping_do_ibuf(CurveMapping *cumap, ImBuf *ibuf)
curvemapping_premultiply(cumap, 1);
}
-int curvemapping_RGBA_does_something(CurveMapping *cumap)
+int curvemapping_RGBA_does_something(const CurveMapping *cumap)
{
int a;
@@ -876,13 +918,12 @@ void curvemapping_initialize(CurveMapping *cumap)
}
}
-void curvemapping_table_RGBA(CurveMapping *cumap, float **array, int *size)
+void curvemapping_table_RGBA(const CurveMapping *cumap, float **array, int *size)
{
int a;
*size = CM_TABLE + 1;
*array = MEM_callocN(sizeof(float) * (*size) * 4, "CurveMapping");
- curvemapping_initialize(cumap);
for (a = 0; a < *size; a++) {
if (cumap->cm[0].table)
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 49c3d77a527..0ffd68c9079 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -60,10 +60,8 @@
#include "BKE_curve.h"
#include "BKE_displist.h"
-static ListBase ttfdata = {NULL, NULL};
/* The vfont code */
-
void BKE_vfont_free_data(struct VFont *vfont)
{
if (vfont->data) {
@@ -83,7 +81,10 @@ void BKE_vfont_free_data(struct VFont *vfont)
vfont->data = NULL;
}
- BKE_vfont_tmpfont_remove(vfont);
+ if (vfont->temp_pf) {
+ freePackedFile(vfont->temp_pf); /* NULL when the font file can't be found on disk */
+ vfont->temp_pf = NULL;
+ }
}
void BKE_vfont_free(struct VFont *vf)
@@ -91,7 +92,7 @@ void BKE_vfont_free(struct VFont *vf)
if (vf == NULL) return;
BKE_vfont_free_data(vf);
-
+
if (vf->packedfile) {
freePackedFile(vf->packedfile);
vf->packedfile = NULL;
@@ -128,63 +129,11 @@ static PackedFile *get_builtin_packedfile(void)
}
}
-static void vfont_tmpfont_free(struct TmpFont *tf)
-{
- if (tf->pf) {
- freePackedFile(tf->pf); /* NULL when the font file can't be found on disk */
- }
- MEM_freeN(tf);
-}
-
-void BKE_vfont_free_global_ttf(void)
-{
- struct TmpFont *tf, *tf_next;
-
- for (tf = ttfdata.first; tf; tf = tf_next) {
- tf_next = tf->next;
- vfont_tmpfont_free(tf);
- }
- ttfdata.first = ttfdata.last = NULL;
-}
-
-struct TmpFont *BKE_vfont_tmpfont_find(VFont *vfont)
-{
- struct TmpFont *tmpfnt = NULL;
-
- if (vfont == NULL) return NULL;
-
- /* Try finding the font from font list */
- for (tmpfnt = ttfdata.first; tmpfnt; tmpfnt = tmpfnt->next) {
- if (tmpfnt->vfont == vfont) {
- break;
- }
- }
-
- return tmpfnt;
-}
-
-/* assumes a VFont's tmpfont can't be in the database more then once */
-void BKE_vfont_tmpfont_remove(VFont *vfont)
-{
- struct TmpFont *tmpfnt;
-
- tmpfnt = BKE_vfont_tmpfont_find(vfont);
-
- if (tmpfnt) {
- vfont_tmpfont_free(tmpfnt);
- BLI_remlink(&ttfdata, tmpfnt);
- }
-}
-
static VFontData *vfont_get_data(Main *bmain, VFont *vfont)
{
- struct TmpFont *tmpfnt = NULL;
- PackedFile *tpf;
-
- if (vfont == NULL) return NULL;
-
- /* Try finding the font from font list */
- tmpfnt = BKE_vfont_tmpfont_find(vfont);
+ if (vfont == NULL) {
+ return NULL;
+ }
/* And then set the data */
if (!vfont->data) {
@@ -198,30 +147,15 @@ static VFontData *vfont_get_data(Main *bmain, VFont *vfont)
pf = vfont->packedfile;
/* We need to copy a tmp font to memory unless it is already there */
- if (!tmpfnt) {
- tpf = MEM_callocN(sizeof(*tpf), "PackedFile");
- tpf->data = MEM_mallocN(pf->size, "packFile");
- tpf->size = pf->size;
- memcpy(tpf->data, pf->data, pf->size);
-
- /* Add temporary packed file to globals */
- tmpfnt = (struct TmpFont *) MEM_callocN(sizeof(struct TmpFont), "temp_font");
- tmpfnt->pf = tpf;
- tmpfnt->vfont = vfont;
- BLI_addtail(&ttfdata, tmpfnt);
+ if (vfont->temp_pf == NULL) {
+ vfont->temp_pf = dupPackedFile(pf);
}
}
else {
pf = newPackedFile(NULL, vfont->name, ID_BLEND_PATH(bmain, &vfont->id));
- if (!tmpfnt) {
- tpf = newPackedFile(NULL, vfont->name, ID_BLEND_PATH(bmain, &vfont->id));
-
- /* Add temporary packed file to globals */
- tmpfnt = (struct TmpFont *) MEM_callocN(sizeof(struct TmpFont), "temp_font");
- tmpfnt->pf = tpf;
- tmpfnt->vfont = vfont;
- BLI_addtail(&ttfdata, tmpfnt);
+ if (vfont->temp_pf == NULL) {
+ vfont->temp_pf = newPackedFile(NULL, vfont->name, ID_BLEND_PATH(bmain, &vfont->id));
}
}
if (!pf) {
@@ -252,9 +186,8 @@ VFont *BKE_vfont_load(Main *bmain, const char *name)
char filename[FILE_MAXFILE];
VFont *vfont = NULL;
PackedFile *pf;
- PackedFile *tpf = NULL;
+ PackedFile *temp_pf = NULL;
int is_builtin;
- struct TmpFont *tmpfnt;
if (strcmp(name, FO_BUILTIN_NAME) == 0) {
BLI_strncpy(filename, name, sizeof(filename));
@@ -269,7 +202,7 @@ VFont *BKE_vfont_load(Main *bmain, const char *name)
BLI_splitdirstring(dir, filename);
pf = newPackedFile(NULL, name, bmain->name);
- tpf = newPackedFile(NULL, name, bmain->name);
+ temp_pf = newPackedFile(NULL, name, bmain->name);
is_builtin = FALSE;
}
@@ -295,10 +228,7 @@ VFont *BKE_vfont_load(Main *bmain, const char *name)
/* Do not add FO_BUILTIN_NAME to temporary listbase */
if (strcmp(filename, FO_BUILTIN_NAME)) {
- tmpfnt = (struct TmpFont *) MEM_callocN(sizeof(struct TmpFont), "temp_font");
- tmpfnt->pf = tpf;
- tmpfnt->vfont = vfont;
- BLI_addtail(&ttfdata, tmpfnt);
+ vfont->temp_pf = temp_pf;
}
}
@@ -306,8 +236,6 @@ VFont *BKE_vfont_load(Main *bmain, const char *name)
if (!vfont || vfont->packedfile != pf) {
freePackedFile(pf);
}
-
- //XXX waitcursor(0);
}
return vfont;
@@ -317,14 +245,14 @@ static VFont *which_vfont(Curve *cu, CharInfo *info)
{
switch (info->flag & (CU_CHINFO_BOLD | CU_CHINFO_ITALIC)) {
case CU_CHINFO_BOLD:
- if (cu->vfontb) return(cu->vfontb); else return(cu->vfont);
+ return cu->vfontb ? cu->vfontb : cu->vfont;
case CU_CHINFO_ITALIC:
- if (cu->vfonti) return(cu->vfonti); else return(cu->vfont);
+ return cu->vfonti ? cu->vfonti : cu->vfont;
case (CU_CHINFO_BOLD | CU_CHINFO_ITALIC):
- if (cu->vfontbi) return(cu->vfontbi); else return(cu->vfont);
+ return cu->vfontbi ? cu->vfontbi : cu->vfont;
default:
- return(cu->vfont);
- }
+ return cu->vfont;
+ }
}
VFont *BKE_vfont_builtin_get(void)
@@ -344,6 +272,7 @@ static VChar *find_vfont_char(VFontData *vfd, intptr_t character)
{
VChar *che = NULL;
+ /* TODO: use ghash */
for (che = vfd->characters.first; che; che = che->next) {
if (che->index == character)
break;
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index d84c20f7a94..2b2128439c7 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -2145,7 +2145,9 @@ RenderResult *BKE_image_acquire_renderresult(Scene *scene, Image *ima)
void BKE_image_release_renderresult(Scene *scene, Image *ima)
{
- if (ima->rr) ;
+ if (ima->rr) {
+ /* pass */
+ }
else if (ima->type == IMA_TYPE_R_RESULT) {
if (ima->render_slot == ima->last_render_slot)
RE_ReleaseResult(RE_GetRender(scene->id.name));
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 3c46e7bcd47..1e1cbf8610e 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -559,7 +559,7 @@ static void feather_bucket_get_diagonal(FeatherEdgesBucket *buckets, int start_b
*diagonal_bucket_b_r = &buckets[diagonal_bucket_b_index];
}
-static void spline_feather_collapse_inner_loops(MaskSpline *spline, float (*feather_points)[2], int tot_feather_point)
+void BKE_mask_spline_feather_collapse_inner_loops(MaskSpline *spline, float (*feather_points)[2], const int tot_feather_point)
{
#define BUCKET_INDEX(co) \
feather_bucket_index_from_coord(co, min, bucket_scale, buckets_per_side)
@@ -721,7 +721,8 @@ static void spline_feather_collapse_inner_loops(MaskSpline *spline, float (*feat
*/
float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(MaskSpline *spline,
int *tot_feather_point,
- const unsigned int resol
+ const unsigned int resol,
+ const int do_feather_isect
))[2]
{
MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
@@ -783,23 +784,24 @@ float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(MaskSpl
*tot_feather_point = tot;
- if (spline->flag & MASK_SPLINE_NOINTERSECT)
- spline_feather_collapse_inner_loops(spline, feather, tot);
+ if ((spline->flag & MASK_SPLINE_NOINTERSECT) && do_feather_isect) {
+ BKE_mask_spline_feather_collapse_inner_loops(spline, feather, tot);
+ }
return feather;
}
float (*BKE_mask_spline_feather_differentiated_points_with_resolution(MaskSpline *spline, int width, int height,
- int *tot_feather_point))[2]
+ int *tot_feather_point, const int do_feather_isect))[2]
{
unsigned int resol = BKE_mask_spline_feather_resolution(spline, width, height);
- return BKE_mask_spline_feather_differentiated_points_with_resolution_ex(spline, tot_feather_point, resol);
+ return BKE_mask_spline_feather_differentiated_points_with_resolution_ex(spline, tot_feather_point, resol, do_feather_isect);
}
float (*BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, int *tot_feather_point))[2]
{
- return BKE_mask_spline_feather_differentiated_points_with_resolution(spline, 0, 0, tot_feather_point);
+ return BKE_mask_spline_feather_differentiated_points_with_resolution(spline, 0, 0, tot_feather_point, TRUE);
}
float (*BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_point))[2]
diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 1fde1168999..d39be3b8ed6 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -370,8 +370,8 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size)
{
MemArena *arena = BLI_memarena_new(1 << 16, __func__);
- const float bucket_dim_x = layer->bounds.xmax - layer->bounds.xmin;
- const float bucket_dim_y = layer->bounds.ymax - layer->bounds.ymin;
+ const float bucket_dim_x = BLI_RCT_SIZE_X(&layer->bounds);
+ const float bucket_dim_y = BLI_RCT_SIZE_Y(&layer->bounds);
layer->buckets_x = (bucket_dim_x / pixel_size) / (float)BUCKET_PIXELS_PER_CELL;
layer->buckets_y = (bucket_dim_y / pixel_size) / (float)BUCKET_PIXELS_PER_CELL;
@@ -575,6 +575,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
int tot_diff_point;
float (*diff_feather_points)[2];
+ float (*diff_feather_points_flip)[2];
int tot_diff_feather_points;
const unsigned int resol_a = BKE_mask_spline_resolution(spline, width, height) / 4;
@@ -586,7 +587,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
if (do_feather) {
diff_feather_points = BKE_mask_spline_feather_differentiated_points_with_resolution_ex(
- spline, &tot_diff_feather_points, resol);
+ spline, &tot_diff_feather_points, resol, FALSE);
BLI_assert(diff_feather_points);
}
else {
@@ -649,6 +650,11 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
}
if (is_fill) {
+ /* applt intersections depending on fill settings */
+ if (spline->flag & MASK_SPLINE_NOINTERSECT) {
+ BKE_mask_spline_feather_collapse_inner_loops(spline, diff_feather_points, tot_diff_feather_points);
+ }
+
copy_v2_v2(co, diff_points[0]);
sf_vert_prev = BLI_scanfill_vert_add(&sf_ctx, co);
sf_vert_prev->tmp.u = sf_vert_tot;
@@ -710,11 +716,27 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
/* unfilled spline */
if (diff_feather_points) {
- float co_diff[3];
+ float co_diff[2];
float co_feather[3];
co_feather[2] = 1.0f;
+ if (spline->flag & MASK_SPLINE_NOINTERSECT) {
+ diff_feather_points_flip = MEM_mallocN(sizeof(float) * 2 * tot_diff_feather_points, "diff_feather_points_flip");
+
+ for (j = 0; j < tot_diff_point; j++) {
+ sub_v2_v2v2(co_diff, diff_points[j], diff_feather_points[j]);
+ add_v2_v2v2(diff_feather_points_flip[j], diff_points[j], co_diff);
+ }
+
+ BKE_mask_spline_feather_collapse_inner_loops(spline, diff_feather_points, tot_diff_feather_points);
+ BKE_mask_spline_feather_collapse_inner_loops(spline, diff_feather_points_flip, tot_diff_feather_points);
+ }
+ else {
+ diff_feather_points_flip = NULL;
+ }
+
+
open_spline_ranges[open_spline_index].vertex_offset = sf_vert_tot;
open_spline_ranges[open_spline_index].vertex_total = tot_diff_point;
@@ -738,8 +760,14 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
/* feather vert B */
- sub_v2_v2v2(co_diff, co, co_feather);
- add_v2_v2v2(co_feather, co, co_diff);
+ if (diff_feather_points_flip) {
+ copy_v2_v2(co_feather, diff_feather_points_flip[j]);
+ }
+ else {
+ sub_v2_v2v2(co_diff, co, co_feather);
+ add_v2_v2v2(co_feather, co, co_diff);
+ }
+
sf_vert = BLI_scanfill_vert_add(&sf_ctx, co_feather);
sf_vert->tmp.u = sf_vert_tot;
sf_vert->keyindex = SF_KEYINDEX_TEMP_ID;
@@ -752,6 +780,11 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
tot_feather_quads -= 2;
}
+ if (diff_feather_points_flip) {
+ MEM_freeN(diff_feather_points_flip);
+ diff_feather_points_flip = NULL;
+ }
+
/* cap ends */
/* dummy init value */
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 7cee9626c3f..62e80645a35 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1425,13 +1425,37 @@ void nodeSocketSetType(bNodeSocket *sock, int type)
/* ************** Node Clipboard *********** */
+#define USE_NODE_CB_VALIDATE
+
+#ifdef USE_NODE_CB_VALIDATE
+/**
+ * This data structure is to validate the node on creation,
+ * otherwise we may reference missing data.
+ *
+ * Currently its only used for ID's, but nodes may one day
+ * referene other pointers which need validation.
+ */
+typedef struct bNodeClipboardExtraInfo {
+ struct bNodeClipboardExtraInfo *next, *prev;
+ ID *id;
+ char id_name[MAX_ID_NAME];
+ char library_name[FILE_MAX];
+} bNodeClipboardExtraInfo;
+#endif /* USE_NODE_CB_VALIDATE */
+
+
typedef struct bNodeClipboard {
ListBase nodes;
+
+#ifdef USE_NODE_CB_VALIDATE
+ ListBase nodes_extra_info;
+#endif
+
ListBase links;
int type;
} bNodeClipboard;
-bNodeClipboard node_clipboard;
+bNodeClipboard node_clipboard = {{0}};
void BKE_node_clipboard_init(struct bNodeTree *ntree)
{
@@ -1454,11 +1478,83 @@ void BKE_node_clipboard_clear(void)
nodeFreeNode(NULL, node);
}
node_clipboard.nodes.first = node_clipboard.nodes.last = NULL;
+
+#ifdef USE_NODE_CB_VALIDATE
+ BLI_freelistN(&node_clipboard.nodes_extra_info);
+#endif
+}
+
+/* return FALSE when one or more ID's are lost */
+int BKE_node_clipboard_validate(void)
+{
+ int ok = TRUE;
+
+#ifdef USE_NODE_CB_VALIDATE
+ bNodeClipboardExtraInfo *node_info;
+ bNode *node;
+
+
+ /* lists must be aligned */
+ BLI_assert(BLI_countlist(&node_clipboard.nodes) ==
+ BLI_countlist(&node_clipboard.nodes_extra_info));
+
+ for (node = node_clipboard.nodes.first, node_info = node_clipboard.nodes_extra_info.first;
+ node;
+ node = node->next, node_info = node_info->next)
+ {
+ /* validate the node against the stored node info */
+
+ /* re-assign each loop since we may clear,
+ * open a new file where the ID is valid, and paste again */
+ node->id = node_info->id;
+
+ /* currently only validate the ID */
+ if (node->id) {
+ ListBase *lb = which_libbase(G.main, GS(node_info->id_name));
+ BLI_assert(lb != NULL);
+
+ if (BLI_findindex(lb, node_info->id) == -1) {
+ /* may assign NULL */
+ node->id = BLI_findstring(lb, node_info->id_name + 2, offsetof(ID, name) + 2);
+
+ if (node->id == NULL) {
+ ok = FALSE;
+ }
+ }
+ }
+ }
+#endif /* USE_NODE_CB_VALIDATE */
+
+ return ok;
}
void BKE_node_clipboard_add_node(bNode *node)
{
+#ifdef USE_NODE_CB_VALIDATE
+ /* add extra info */
+ bNodeClipboardExtraInfo *node_info = MEM_mallocN(sizeof(bNodeClipboardExtraInfo), STRINGIFY(bNodeClipboardExtraInfo));
+
+ node_info->id = node->id;
+ if (node->id) {
+ BLI_strncpy(node_info->id_name, node->id->name, sizeof(node_info->id_name));
+ if (node->id->lib) {
+ BLI_strncpy(node_info->library_name, node->id->lib->filepath, sizeof(node_info->library_name));
+ }
+ else {
+ node_info->library_name[0] = '\0';
+ }
+ }
+ else {
+ node_info->id_name[0] = '\0';
+ node_info->library_name[0] = '\0';
+ }
+ BLI_addtail(&node_clipboard.nodes_extra_info, node_info);
+ /* end extra info */
+#endif /* USE_NODE_CB_VALIDATE */
+
+ /* add node */
BLI_addtail(&node_clipboard.nodes, node);
+
}
void BKE_node_clipboard_add_link(bNodeLink *link)
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index f115a41d419..9787a5025f7 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -158,7 +158,17 @@ void freePackedFile(PackedFile *pf)
else
printf("freePackedFile: Trying to free a NULL pointer\n");
}
-
+
+PackedFile *dupPackedFile(const PackedFile *pf_src)
+{
+ PackedFile *pf_dst;
+
+ pf_dst = MEM_dupallocN(pf_src);
+ pf_dst->data = MEM_dupallocN(pf_src->data);
+
+ return pf_dst;
+}
+
PackedFile *newPackedFileMemory(void *mem, int memlen)
{
PackedFile *pf = MEM_callocN(sizeof(*pf), "PackedFile");
diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c
index 387ec67eb1c..e3f0226c863 100644
--- a/source/blender/blenkernel/intern/seqcache.c
+++ b/source/blender/blenkernel/intern/seqcache.c
@@ -37,8 +37,11 @@
#include "BKE_sequencer.h"
#include "IMB_moviecache.h"
+#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
+#include "BLI_listbase.h"
+
typedef struct SeqCacheKey {
struct Sequence *seq;
SeqRenderData context;
@@ -46,7 +49,25 @@ typedef struct SeqCacheKey {
seq_stripelem_ibuf_t type;
} SeqCacheKey;
+typedef struct SeqPreprocessCacheElem {
+ struct SeqPreprocessCacheElem *next, *prev;
+
+ struct Sequence *seq;
+ SeqRenderData context;
+ seq_stripelem_ibuf_t type;
+
+ ImBuf *ibuf;
+} SeqPreprocessCacheElem;
+
+typedef struct SeqPreprocessCache {
+ int cfra;
+ ListBase elems;
+} SeqPreprocessCache;
+
static struct MovieCache *moviecache = NULL;
+static struct SeqPreprocessCache *preprocess_cache = NULL;
+
+static void preprocessed_cache_destruct(void);
static int seq_cmp_render_data(const SeqRenderData *a, const SeqRenderData *b)
{
@@ -160,6 +181,8 @@ void BKE_sequencer_cache_destruct(void)
{
if (moviecache)
IMB_moviecache_free(moviecache);
+
+ preprocessed_cache_destruct();
}
void BKE_sequencer_cache_cleanup(void)
@@ -168,6 +191,8 @@ void BKE_sequencer_cache_cleanup(void)
IMB_moviecache_free(moviecache);
moviecache = IMB_moviecache_create("seqcache", sizeof(SeqCacheKey), seqcache_hashhash, seqcache_hashcmp);
}
+
+ BKE_sequencer_preprocessed_cache_cleanup();
}
static int seqcache_key_check_seq(void *userkey, void *userdata)
@@ -219,3 +244,100 @@ void BKE_sequencer_cache_put(SeqRenderData context, Sequence *seq, float cfra, s
IMB_moviecache_put(moviecache, &key, i);
}
+
+void BKE_sequencer_preprocessed_cache_cleanup(void)
+{
+ SeqPreprocessCacheElem *elem;
+
+ if (!preprocess_cache)
+ return;
+
+ for (elem = preprocess_cache->elems.first; elem; elem = elem->next) {
+ IMB_freeImBuf(elem->ibuf);
+ }
+ BLI_freelistN(&preprocess_cache->elems);
+
+ preprocess_cache->elems.first = preprocess_cache->elems.last = NULL;
+}
+
+static void preprocessed_cache_destruct(void)
+{
+ if (!preprocess_cache)
+ return;
+
+ BKE_sequencer_preprocessed_cache_cleanup();
+
+ MEM_freeN(preprocess_cache);
+ preprocess_cache = NULL;
+}
+
+ImBuf *BKE_sequencer_preprocessed_cache_get(SeqRenderData context, Sequence *seq, float cfra, seq_stripelem_ibuf_t type)
+{
+ SeqPreprocessCacheElem *elem;
+
+ if (!preprocess_cache)
+ return NULL;
+
+ if (preprocess_cache->cfra != cfra)
+ return NULL;
+
+ for (elem = preprocess_cache->elems.first; elem; elem = elem->next) {
+ if (elem->seq != seq)
+ continue;
+
+ if (elem->type != type)
+ continue;
+
+ if (seq_cmp_render_data(&elem->context, &context) != 0)
+ continue;
+
+ IMB_refImBuf(elem->ibuf);
+ return elem->ibuf;
+ }
+
+ return NULL;
+}
+
+void BKE_sequencer_preprocessed_cache_put(SeqRenderData context, Sequence *seq, float cfra, seq_stripelem_ibuf_t type, ImBuf *ibuf)
+{
+ SeqPreprocessCacheElem *elem;
+
+ if (!preprocess_cache) {
+ preprocess_cache = MEM_callocN(sizeof(SeqPreprocessCache), "sequencer preprocessed cache");
+ }
+ else {
+ if (preprocess_cache->cfra != cfra)
+ BKE_sequencer_preprocessed_cache_cleanup();
+ }
+
+ elem = MEM_callocN(sizeof(SeqPreprocessCacheElem), "sequencer preprocessed cache element");
+
+ elem->seq = seq;
+ elem->type = type;
+ elem->context = context;
+ elem->ibuf = ibuf;
+
+ preprocess_cache->cfra = cfra;
+
+ IMB_refImBuf(ibuf);
+
+ BLI_addtail(&preprocess_cache->elems, elem);
+}
+
+void BKE_sequencer_preprocessed_cache_cleanup_sequence(Sequence *seq)
+{
+ SeqPreprocessCacheElem *elem, *elem_next;
+
+ if (!preprocess_cache)
+ return;
+
+ for (elem = preprocess_cache->elems.first; elem; elem = elem_next) {
+ elem_next = elem->next;
+
+ if (elem->seq == seq) {
+ IMB_freeImBuf(elem->ibuf);
+
+ BLI_freelinkN(&preprocess_cache->elems, elem);
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c
new file mode 100644
index 00000000000..26c2fe03688
--- /dev/null
+++ b/source/blender/blenkernel/intern/seqmodifier.c
@@ -0,0 +1,550 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2012 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/seqmodifier.c
+ * \ingroup bke
+ */
+
+#include <stddef.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_listbase.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+
+#include "DNA_sequence_types.h"
+
+#include "BKE_colortools.h"
+#include "BKE_sequencer.h"
+#include "BKE_utildefines.h"
+
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+static SequenceModifierTypeInfo *modifiersTypes[NUM_SEQUENCE_MODIFIER_TYPES];
+static int modifierTypesInit = FALSE;
+
+/*********************** Modifiers *************************/
+
+typedef void (*modifier_apply_threaded_cb) (int width, int height, unsigned char *rect, float *rect_float,
+ unsigned char *mask_rect, float *mask_rect_float, void *data_v);
+
+typedef struct ModifierInitData {
+ ImBuf *ibuf;
+ ImBuf *mask;
+ void *user_data;
+
+ modifier_apply_threaded_cb apply_callback;
+} ModifierInitData;
+
+typedef struct ModifierThread {
+ int width, height;
+
+ unsigned char *rect, *mask_rect;
+ float *rect_float, *mask_rect_float;
+
+ void *user_data;
+
+ modifier_apply_threaded_cb apply_callback;
+} ModifierThread;
+
+
+static ImBuf *modifier_mask_get(SequenceModifierData *smd, SeqRenderData context, int cfra, int make_float)
+{
+ return BKE_sequencer_render_mask_input(context, smd->mask_input_type, smd->mask_sequence, smd->mask_id, cfra, make_float);
+}
+
+static void modifier_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v)
+{
+ ModifierThread *handle = (ModifierThread *) handle_v;
+ ModifierInitData *init_data = (ModifierInitData *) init_data_v;
+ ImBuf *ibuf = init_data->ibuf;
+ ImBuf *mask = init_data->mask;
+
+ int offset = 4 * start_line * ibuf->x;
+
+ memset(handle, 0, sizeof(ModifierThread));
+
+ handle->width = ibuf->x;
+ handle->height = tot_line;
+ handle->apply_callback = init_data->apply_callback;
+ handle->user_data = init_data->user_data;
+
+ if (ibuf->rect)
+ handle->rect = (unsigned char *) ibuf->rect + offset;
+
+ if (ibuf->rect_float)
+ handle->rect_float = ibuf->rect_float + offset;
+
+ if (mask) {
+ if (mask->rect)
+ handle->mask_rect = (unsigned char *) mask->rect + offset;
+
+ if (mask->rect_float)
+ handle->mask_rect_float = mask->rect_float + offset;
+ }
+ else {
+ handle->mask_rect = NULL;
+ handle->mask_rect_float = NULL;
+ }
+}
+
+static void *modifier_do_thread(void *thread_data_v)
+{
+ ModifierThread *td = (ModifierThread *) thread_data_v;
+
+ td->apply_callback(td->width, td->height, td->rect, td->rect_float, td->mask_rect, td->mask_rect_float, td->user_data);
+
+ return NULL;
+}
+
+static void modifier_apply_threaded(ImBuf *ibuf, ImBuf *mask, modifier_apply_threaded_cb apply_callback, void *user_data)
+{
+ ModifierInitData init_data;
+
+ init_data.ibuf = ibuf;
+ init_data.mask = mask;
+ init_data.user_data = user_data;
+
+ init_data.apply_callback = apply_callback;
+
+ IMB_processor_apply_threaded(ibuf->y, sizeof(ModifierThread), &init_data,
+ modifier_init_handle, modifier_do_thread);
+}
+
+/* **** Color Balance Modifier **** */
+
+void colorBalance_init_data(SequenceModifierData *smd)
+{
+ ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *) smd;
+ int c;
+
+ cbmd->color_multiply = 1.0f;
+
+ for (c = 0; c < 3; c++) {
+ cbmd->color_balance.lift[c] = 1.0f;
+ cbmd->color_balance.gamma[c] = 1.0f;
+ cbmd->color_balance.gain[c] = 1.0f;
+ }
+}
+
+ImBuf *colorBalance_apply(SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
+{
+ ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *) smd;
+ ImBuf *ibuf_new = IMB_dupImBuf(ibuf);
+
+ BKE_sequencer_color_balance_apply(&cbmd->color_balance, ibuf_new, cbmd->color_multiply, FALSE, mask);
+
+ return ibuf_new;
+}
+
+static SequenceModifierTypeInfo seqModifier_ColorBalance = {
+ "Color Balance", /* name */
+ "ColorBalanceModifierData", /* struct_name */
+ sizeof(ColorBalanceModifierData), /* struct_size */
+ colorBalance_init_data, /* init_data */
+ NULL, /* free_data */
+ NULL, /* copy_data */
+ colorBalance_apply /* apply */
+};
+
+/* **** Curves Modifier **** */
+
+void curves_init_data(SequenceModifierData *smd)
+{
+ CurvesModifierData *cmd = (CurvesModifierData *) smd;
+
+ curvemapping_set_defaults(&cmd->curve_mapping, 4, 0.0f, 0.0f, 1.0f, 1.0f);
+}
+
+void curves_free_data(SequenceModifierData *smd)
+{
+ CurvesModifierData *cmd = (CurvesModifierData *) smd;
+
+ curvemapping_free_data(&cmd->curve_mapping);
+}
+
+void curves_copy_data(SequenceModifierData *target, SequenceModifierData *smd)
+{
+ CurvesModifierData *cmd = (CurvesModifierData *) smd;
+ CurvesModifierData *cmd_target = (CurvesModifierData *) target;
+
+ curvemapping_copy_data(&cmd_target->curve_mapping, &cmd->curve_mapping);
+}
+
+void curves_apply_threaded(int width, int height, unsigned char *rect, float *rect_float,
+ unsigned char *mask_rect, float *mask_rect_float, void *data_v)
+{
+ CurveMapping *curve_mapping = (CurveMapping *) data_v;
+ int x, y;
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ int pixel_index = (y * width + x) * 4;
+
+ if (rect_float) {
+ float *pixel = rect_float + pixel_index;
+ float result[3];
+
+ curvemapping_evaluate_premulRGBF(curve_mapping, result, pixel);
+
+ if (mask_rect_float) {
+ float *m = mask_rect_float + pixel_index;
+
+ pixel[0] = pixel[0] * (1.0f - m[0]) + result[0] * m[0];
+ pixel[1] = pixel[1] * (1.0f - m[1]) + result[1] * m[1];
+ pixel[2] = pixel[2] * (1.0f - m[2]) + result[2] * m[2];
+ }
+ else {
+ pixel[0] = result[0];
+ pixel[1] = result[1];
+ pixel[2] = result[2];
+ }
+ }
+ if (rect) {
+ unsigned char *pixel = rect + pixel_index;
+ unsigned char result[3];
+
+ curvemapping_evaluate_premulRGB(curve_mapping, result, pixel);
+
+ if (mask_rect) {
+ float t[3];
+
+ rgb_uchar_to_float(t, mask_rect + pixel_index);
+
+ pixel[0] = pixel[0] * (1.0f - t[0]) + result[0] * t[0];
+ pixel[1] = pixel[1] * (1.0f - t[1]) + result[1] * t[1];
+ pixel[2] = pixel[2] * (1.0f - t[2]) + result[2] * t[2];
+ }
+ else {
+ pixel[0] = result[0];
+ pixel[1] = result[1];
+ pixel[2] = result[2];
+ }
+ }
+ }
+ }
+}
+
+ImBuf *curves_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
+{
+ CurvesModifierData *cmd = (CurvesModifierData *) smd;
+ ImBuf *ibuf_new = IMB_dupImBuf(ibuf);
+
+ float black[3] = {0.0f, 0.0f, 0.0f};
+ float white[3] = {1.0f, 1.0f, 1.0f};
+
+ curvemapping_initialize(&cmd->curve_mapping);
+
+ curvemapping_premultiply(&cmd->curve_mapping, 0);
+ curvemapping_set_black_white(&cmd->curve_mapping, black, white);
+
+ modifier_apply_threaded(ibuf_new, mask, curves_apply_threaded, &cmd->curve_mapping);
+
+ curvemapping_premultiply(&cmd->curve_mapping, 1);
+
+ return ibuf_new;
+}
+
+static SequenceModifierTypeInfo seqModifier_Curves = {
+ "Curves", /* name */
+ "CurvesModifierData", /* struct_name */
+ sizeof(CurvesModifierData), /* struct_size */
+ curves_init_data, /* init_data */
+ curves_free_data, /* free_data */
+ curves_copy_data, /* copy_data */
+ curves_apply /* apply */
+};
+
+/* **** Hue Correct Modifier **** */
+
+void hue_correct_init_data(SequenceModifierData *smd)
+{
+ HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
+ int c;
+
+ curvemapping_set_defaults(&hcmd->curve_mapping, 1, 0.0f, 0.0f, 1.0f, 1.0f);
+ hcmd->curve_mapping.preset = CURVE_PRESET_MID9;
+
+ for (c = 0; c < 3; c++) {
+ CurveMap *cuma = &hcmd->curve_mapping.cm[c];
+
+ curvemap_reset(cuma, &hcmd->curve_mapping.clipr, hcmd->curve_mapping.preset, CURVEMAP_SLOPE_POSITIVE);
+ }
+
+ /* default to showing Saturation */
+ hcmd->curve_mapping.cur = 1;
+}
+
+void hue_correct_free_data(SequenceModifierData *smd)
+{
+ HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
+
+ curvemapping_free_data(&hcmd->curve_mapping);
+}
+
+void hue_correct_copy_data(SequenceModifierData *target, SequenceModifierData *smd)
+{
+ HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
+ HueCorrectModifierData *hcmd_target = (HueCorrectModifierData *) target;
+
+ curvemapping_copy_data(&hcmd_target->curve_mapping, &hcmd->curve_mapping);
+}
+
+void hue_correct_apply_threaded(int width, int height, unsigned char *rect, float *rect_float,
+ unsigned char *mask_rect, float *mask_rect_float, void *data_v)
+{
+ CurveMapping *curve_mapping = (CurveMapping *) data_v;
+ int x, y;
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ int pixel_index = (y * width + x) * 4;
+ float pixel[3], result[3], mask[3] = {1.0f, 1.0f, 1.0f};
+ float hsv[3], f;
+
+ if (rect_float)
+ copy_v3_v3(pixel, rect_float + pixel_index);
+ else
+ rgb_uchar_to_float(pixel, rect + pixel_index);
+
+ rgb_to_hsv(pixel[0], pixel[1], pixel[2], hsv, hsv + 1, hsv + 2);
+
+ /* adjust hue, scaling returned default 0.5 up to 1 */
+ f = curvemapping_evaluateF(curve_mapping, 0, hsv[0]);
+ hsv[0] += f - 0.5f;
+
+ /* adjust saturation, scaling returned default 0.5 up to 1 */
+ f = curvemapping_evaluateF(curve_mapping, 1, hsv[0]);
+ hsv[1] *= (f * 2.0f);
+
+ /* adjust value, scaling returned default 0.5 up to 1 */
+ f = curvemapping_evaluateF(curve_mapping, 2, hsv[0]);
+ hsv[2] *= (f * 2.f);
+
+ hsv[0] = hsv[0] - floorf(hsv[0]); /* mod 1.0 */
+ CLAMP(hsv[1], 0.0f, 1.0f);
+
+ /* convert back to rgb */
+ hsv_to_rgb(hsv[0], hsv[1], hsv[2], result, result + 1, result + 2);
+
+ if (mask_rect_float)
+ copy_v3_v3(mask, mask_rect_float + pixel_index);
+ else if (mask_rect)
+ rgb_uchar_to_float(mask, mask_rect + pixel_index);
+
+ result[0] = pixel[0] * (1.0f - mask[0]) + result[0] * mask[0];
+ result[1] = pixel[1] * (1.0f - mask[1]) + result[1] * mask[1];
+ result[2] = pixel[2] * (1.0f - mask[2]) + result[2] * mask[2];
+
+ if (rect_float)
+ copy_v3_v3(rect_float + pixel_index, result);
+ else
+ rgb_float_to_uchar(rect + pixel_index, result);
+ }
+ }
+}
+
+ImBuf *hue_correct_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
+{
+ HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
+ ImBuf *ibuf_new = IMB_dupImBuf(ibuf);
+
+ curvemapping_initialize(&hcmd->curve_mapping);
+
+ modifier_apply_threaded(ibuf_new, mask, hue_correct_apply_threaded, &hcmd->curve_mapping);
+
+ return ibuf_new;
+}
+
+static SequenceModifierTypeInfo seqModifier_HueCorrect = {
+ "Hue Correct", /* name */
+ "HueCorrectModifierData", /* struct_name */
+ sizeof(HueCorrectModifierData), /* struct_size */
+ hue_correct_init_data, /* init_data */
+ hue_correct_free_data, /* free_data */
+ hue_correct_copy_data, /* copy_data */
+ hue_correct_apply /* apply */
+};
+
+/*********************** Modifier functions *************************/
+
+static void sequence_modifier_type_info_init(void)
+{
+#define INIT_TYPE(typeName) (modifiersTypes[seqModifierType_##typeName] = &seqModifier_##typeName)
+
+ INIT_TYPE(ColorBalance);
+ INIT_TYPE(Curves);
+ INIT_TYPE(HueCorrect);
+
+#undef INIT_TYPE
+}
+
+SequenceModifierTypeInfo *BKE_sequence_modifier_type_info_get(int type)
+{
+ if (!modifierTypesInit) {
+ sequence_modifier_type_info_init();
+ modifierTypesInit = TRUE;
+ }
+
+ return modifiersTypes[type];
+}
+
+SequenceModifierData *BKE_sequence_modifier_new(Sequence *seq, const char *name, int type)
+{
+ SequenceModifierData *smd;
+ SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(type);
+
+ smd = MEM_callocN(smti->struct_size, "sequence modifier");
+
+ smd->type = type;
+ smd->flag |= SEQUENCE_MODIFIER_EXPANDED;
+
+ if (!name || !name[0])
+ BLI_strncpy(smd->name, smti->name, sizeof(smd->name));
+ else
+ BLI_strncpy(smd->name, name, sizeof(smd->name));
+
+ BLI_addtail(&seq->modifiers, smd);
+
+ BKE_sequence_modifier_unique_name(seq, smd);
+
+ if (smti->init_data)
+ smti->init_data(smd);
+
+ return smd;
+}
+
+int BKE_sequence_modifier_remove(Sequence *seq, SequenceModifierData *smd)
+{
+ if (BLI_findindex(&seq->modifiers, smd) == -1)
+ return FALSE;
+
+ BLI_remlink(&seq->modifiers, smd);
+ BKE_sequence_modifier_free(smd);
+
+ return TRUE;
+}
+
+void BKE_sequence_modifier_clear(Sequence *seq)
+{
+ SequenceModifierData *smd, *smd_next;
+
+ for (smd = seq->modifiers.first; smd; smd = smd_next) {
+ smd_next = smd->next;
+ BKE_sequence_modifier_free(smd);
+ }
+
+ seq->modifiers.first = seq->modifiers.last = NULL;
+}
+
+void BKE_sequence_modifier_free(SequenceModifierData *smd)
+{
+ SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
+
+ if (smti && smti->free_data) {
+ smti->free_data(smd);
+ }
+
+ MEM_freeN(smd);
+}
+
+void BKE_sequence_modifier_unique_name(Sequence *seq, SequenceModifierData *smd)
+{
+ SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
+
+ BLI_uniquename(&seq->modifiers, smd, smti->name, '.', offsetof(SequenceModifierData, name), sizeof(smd->name));
+}
+
+SequenceModifierData *BKE_sequence_modifier_find_by_name(Sequence *seq, char *name)
+{
+ return BLI_findstring(&(seq->modifiers), name, offsetof(SequenceModifierData, name));
+}
+
+ImBuf *BKE_sequence_modifier_apply_stack(SeqRenderData context, Sequence *seq, ImBuf *ibuf, int cfra)
+{
+ SequenceModifierData *smd;
+ ImBuf *processed_ibuf = ibuf;
+
+ for (smd = seq->modifiers.first; smd; smd = smd->next) {
+ SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
+ ImBuf *ibuf_new;
+
+ /* could happen if modifier is being removed or not exists in current version of blender */
+ if (!smti)
+ continue;
+
+ /* modifier is muted, do nothing */
+ if (smd->flag & SEQUENCE_MODIFIER_MUTE)
+ continue;
+
+ if (smti->apply) {
+ ImBuf *mask = modifier_mask_get(smd, context, cfra, ibuf->rect_float != NULL);
+
+ if (processed_ibuf == ibuf)
+ processed_ibuf = IMB_dupImBuf(ibuf);
+
+ ibuf_new = smti->apply(smd, processed_ibuf, mask);
+
+ if (ibuf_new != processed_ibuf) {
+ IMB_freeImBuf(processed_ibuf);
+ processed_ibuf = ibuf_new;
+ }
+
+ if (mask)
+ IMB_freeImBuf(mask);
+ }
+ }
+
+ return processed_ibuf;
+}
+
+void BKE_sequence_modifier_list_copy(Sequence *seqn, Sequence *seq)
+{
+ SequenceModifierData *smd;
+
+ for (smd = seq->modifiers.first; smd; smd = smd->next) {
+ SequenceModifierData *smdn;
+ SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
+
+ smdn = MEM_dupallocN(smd);
+
+ if (smti && smti->copy_data)
+ smti->copy_data(smdn, smd);
+
+ smdn->next = smdn->prev = NULL;
+ BLI_addtail(&seqn->modifiers, smdn);
+ }
+}
+
+int BKE_sequence_supports_modifiers(Sequence *seq)
+{
+ return !ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD);
+}
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 9625fad69a6..3699f802c91 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -83,6 +83,7 @@
static ImBuf *seq_render_strip_stack(SeqRenderData context, ListBase *seqbasep, float cfra, int chanshown);
static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra);
static void seq_free_animdata(Scene *scene, Sequence *seq);
+static ImBuf *seq_render_mask(SeqRenderData context, Mask *mask, float nr, short make_float);
/* **** XXX ******** */
#define SELECT 1
@@ -203,7 +204,11 @@ void BKE_sequence_free(Scene *scene, Sequence *seq)
seq_free_animdata(scene, seq);
}
+ /* free modifiers */
+ BKE_sequence_modifier_clear(seq);
+
BKE_sequencer_cache_cleanup_sequence(seq);
+ BKE_sequencer_preprocessed_cache_cleanup_sequence(seq);
MEM_freeN(seq);
}
@@ -1432,7 +1437,7 @@ static void make_cb_table_float(float lift, float gain, float gamma,
}
}
-static void color_balance_byte_byte(Sequence *seq, unsigned char *rect, unsigned char *mask_rect, int width, int height, float mul)
+static void color_balance_byte_byte(StripColorBalance *cb_, unsigned char *rect, unsigned char *mask_rect, int width, int height, float mul)
{
unsigned char cb_tab[3][256];
int c;
@@ -1440,7 +1445,7 @@ static void color_balance_byte_byte(Sequence *seq, unsigned char *rect, unsigned
unsigned char *e = p + width * 4 * height;
unsigned char *m = mask_rect;
- StripColorBalance cb = calc_cb(seq->strip->color_balance);
+ StripColorBalance cb = calc_cb(cb_);
for (c = 0; c < 3; c++) {
make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c], cb_tab[c], mul);
@@ -1466,7 +1471,7 @@ static void color_balance_byte_byte(Sequence *seq, unsigned char *rect, unsigned
}
}
-static void color_balance_byte_float(Sequence *seq, unsigned char *rect, float *rect_float, unsigned char *mask_rect, int width, int height, float mul)
+static void color_balance_byte_float(StripColorBalance *cb_, unsigned char *rect, float *rect_float, unsigned char *mask_rect, int width, int height, float mul)
{
float cb_tab[4][256];
int c, i;
@@ -1478,7 +1483,7 @@ static void color_balance_byte_float(Sequence *seq, unsigned char *rect, float *
o = rect_float;
- cb = calc_cb(seq->strip->color_balance);
+ cb = calc_cb(cb_);
for (c = 0; c < 3; c++) {
make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c], cb_tab[c], mul);
@@ -1510,12 +1515,12 @@ static void color_balance_byte_float(Sequence *seq, unsigned char *rect, float *
}
}
-static void color_balance_float_float(Sequence *seq, float *rect_float, float *mask_rect_float, int width, int height, float mul)
+static void color_balance_float_float(StripColorBalance *cb_, float *rect_float, float *mask_rect_float, int width, int height, float mul)
{
float *p = rect_float;
float *e = rect_float + width * 4 * height;
float *m = mask_rect_float;
- StripColorBalance cb = calc_cb(seq->strip->color_balance);
+ StripColorBalance cb = calc_cb(cb_);
while (p < e) {
int c;
@@ -1535,20 +1540,23 @@ static void color_balance_float_float(Sequence *seq, float *rect_float, float *m
}
typedef struct ColorBalanceInitData {
- Sequence *seq;
+ StripColorBalance *cb;
ImBuf *ibuf;
float mul;
ImBuf *mask;
+ short make_float;
} ColorBalanceInitData;
typedef struct ColorBalanceThread {
- Sequence *seq;
+ StripColorBalance *cb;
float mul;
int width, height;
unsigned char *rect, *mask_rect;
float *rect_float, *mask_rect_float;
+
+ short make_float;
} ColorBalanceThread;
static void color_balance_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v)
@@ -1562,10 +1570,11 @@ static void color_balance_init_handle(void *handle_v, int start_line, int tot_li
memset(handle, 0, sizeof(ColorBalanceThread));
- handle->seq = init_data->seq;
+ handle->cb = init_data->cb;
handle->mul = init_data->mul;
handle->width = ibuf->x;
handle->height = tot_line;
+ handle->make_float = init_data->make_float;
if (ibuf->rect)
handle->rect = (unsigned char *) ibuf->rect + offset;
@@ -1589,7 +1598,7 @@ static void color_balance_init_handle(void *handle_v, int start_line, int tot_li
static void *color_balance_do_thread(void *thread_data_v)
{
ColorBalanceThread *thread_data = (ColorBalanceThread *) thread_data_v;
- Sequence *seq = thread_data->seq;
+ StripColorBalance *cb = thread_data->cb;
int width = thread_data->width, height = thread_data->height;
unsigned char *rect = thread_data->rect;
unsigned char *mask_rect = thread_data->mask_rect;
@@ -1598,48 +1607,56 @@ static void *color_balance_do_thread(void *thread_data_v)
float mul = thread_data->mul;
if (rect_float) {
- color_balance_float_float(seq, rect_float, mask_rect_float, width, height, mul);
+ color_balance_float_float(cb, rect_float, mask_rect_float, width, height, mul);
}
- else if (seq->flag & SEQ_MAKE_FLOAT) {
- color_balance_byte_float(seq, rect, rect_float, mask_rect, width, height, mul);
+ else if (thread_data->make_float) {
+ color_balance_byte_float(cb, rect, rect_float, mask_rect, width, height, mul);
}
else {
- color_balance_byte_byte(seq, rect, mask_rect, width, height, mul);
+ color_balance_byte_byte(cb, rect, mask_rect, width, height, mul);
}
return NULL;
}
-static void color_balance(SeqRenderData context, Sequence *seq, ImBuf *ibuf, float mul, int cfra)
+ImBuf *BKE_sequencer_render_mask_input(SeqRenderData context, int mask_input_type, Sequence *mask_sequence, Mask *mask_id, int cfra, int make_float)
+{
+ ImBuf *mask_input = NULL;
+
+ if (mask_input_type == SEQUENCE_MASK_INPUT_STRIP) {
+ if (mask_sequence) {
+ mask_input = seq_render_strip(context, mask_sequence, cfra);
+
+ if (make_float) {
+ if (!mask_input->rect_float)
+ IMB_float_from_rect(mask_input);
+ }
+ else {
+ if (!mask_input->rect)
+ IMB_rect_from_float(mask_input);
+ }
+ }
+ }
+ else if (mask_input_type == SEQUENCE_MASK_INPUT_ID) {
+ mask_input = seq_render_mask(context, mask_id, cfra, make_float);
+ }
+
+ return mask_input;
+}
+
+void BKE_sequencer_color_balance_apply(StripColorBalance *cb, ImBuf *ibuf, float mul, short make_float, ImBuf *mask_input)
{
ColorBalanceInitData init_data;
- if (!ibuf->rect_float && seq->flag & SEQ_MAKE_FLOAT)
+ if (!ibuf->rect_float && make_float)
imb_addrectfloatImBuf(ibuf);
- init_data.seq = seq;
+ init_data.cb = cb;
init_data.ibuf = ibuf;
init_data.mul = mul;
init_data.mask = NULL;
-
- if (seq->mask_sequence) {
- if (seq->mask_sequence != seq && !BKE_sequence_check_depend(seq, seq->mask_sequence)) {
- ImBuf *mask = seq_render_strip(context, seq->mask_sequence, cfra);
-
- if (mask) {
- if (ibuf->rect_float) {
- if (!mask->rect_float)
- IMB_float_from_rect(mask);
- }
- else {
- if (!mask->rect)
- IMB_rect_from_float(mask);
- }
-
- init_data.mask = mask;
- }
- }
- }
+ init_data.make_float = make_float;
+ init_data.mask = mask_input;
IMB_processor_apply_threaded(ibuf->y, sizeof(ColorBalanceThread), &init_data,
color_balance_init_handle, color_balance_do_thread);
@@ -1650,9 +1667,26 @@ static void color_balance(SeqRenderData context, Sequence *seq, ImBuf *ibuf, flo
*/
if (ibuf->rect_float && ibuf->rect)
imb_freerectImBuf(ibuf);
+}
+
+static void sequence_color_balance(SeqRenderData context, Sequence *seq, ImBuf *ibuf, float mul, int cfra)
+{
+ StripColorBalance *cb = seq->strip->color_balance;
+ ImBuf *mask_input = NULL;
+ short make_float = seq->flag & SEQ_MAKE_FLOAT;
+
+ if (seq->mask_sequence) {
+ if (seq->mask_sequence != seq && !BKE_sequence_check_depend(seq, seq->mask_sequence)) {
+ int make_float = ibuf->rect_float != NULL;
+
+ mask_input = BKE_sequencer_render_mask_input(context, SEQUENCE_MASK_INPUT_STRIP, seq->mask_sequence, NULL, cfra, make_float);
+ }
+ }
- if (init_data.mask)
- IMB_freeImBuf(init_data.mask);
+ BKE_sequencer_color_balance_apply(cb, ibuf, mul, make_float, mask_input);
+
+ if (mask_input)
+ IMB_freeImBuf(mask_input);
}
/*
@@ -1696,6 +1730,10 @@ int BKE_sequencer_input_have_to_preprocess(SeqRenderData UNUSED(context), Sequen
if (seq->sat != 1.0f) {
return TRUE;
}
+
+ if (seq->modifiers.first) {
+ return TRUE;
+ }
return FALSE;
}
@@ -1795,7 +1833,7 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
}
if (seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
- color_balance(context, seq, ibuf, mul, cfra);
+ sequence_color_balance(context, seq, ibuf, mul, cfra);
mul = 1.0;
}
@@ -1818,7 +1856,6 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
}
}
-
if (ibuf->x != context.rectx || ibuf->y != context.recty) {
if (context.scene->r.mode & R_OSA) {
IMB_scaleImBuf(ibuf, (short)context.rectx, (short)context.recty);
@@ -1827,6 +1864,16 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
IMB_scalefastImBuf(ibuf, (short)context.rectx, (short)context.recty);
}
}
+
+ if (seq->modifiers.first) {
+ ImBuf *ibuf_new = BKE_sequence_modifier_apply_stack(context, seq, ibuf, cfra);
+
+ if (ibuf_new != ibuf) {
+ IMB_freeImBuf(ibuf);
+ ibuf = ibuf_new;
+ }
+ }
+
return ibuf;
}
@@ -2098,23 +2145,23 @@ static ImBuf *seq_render_movieclip_strip(SeqRenderData context, Sequence *seq, f
}
-static ImBuf *seq_render_mask_strip(SeqRenderData context, Sequence *seq, float nr)
+static ImBuf *seq_render_mask(SeqRenderData context, Mask *mask, float nr, short make_float)
{
/* TODO - add option to rasterize to alpha imbuf? */
ImBuf *ibuf = NULL;
float *maskbuf;
int i;
- if (!seq->mask) {
+ if (!mask) {
return NULL;
}
else {
Mask *mask_temp;
MaskRasterHandle *mr_handle;
- mask_temp = BKE_mask_copy_nolib(seq->mask);
+ mask_temp = BKE_mask_copy_nolib(mask);
- BKE_mask_evaluate(mask_temp, seq->mask->sfra + nr, TRUE);
+ BKE_mask_evaluate(mask_temp, mask->sfra + nr, TRUE);
maskbuf = MEM_mallocN(sizeof(float) * context.rectx * context.recty, __func__);
@@ -2131,7 +2178,7 @@ static ImBuf *seq_render_mask_strip(SeqRenderData context, Sequence *seq, float
}
- if (seq->flag & SEQ_MAKE_FLOAT) {
+ if (make_float) {
/* pixels */
float *fp_src;
float *fp_dst;
@@ -2173,6 +2220,13 @@ static ImBuf *seq_render_mask_strip(SeqRenderData context, Sequence *seq, float
return ibuf;
}
+static ImBuf *seq_render_mask_strip(SeqRenderData context, Sequence *seq, float nr)
+{
+ short make_float = seq->flag & SEQ_MAKE_FLOAT;
+
+ return seq_render_mask(context, seq->mask, nr, make_float);
+}
+
static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float nr)
{
ImBuf *ibuf = NULL;
@@ -2328,160 +2382,146 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float
return ibuf;
}
-static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra)
+static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, float cfra)
{
ImBuf *ibuf = NULL;
- char name[FILE_MAX];
- int use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra);
- int is_proxy_image = FALSE;
float nr = give_stripelem_index(seq, cfra);
- /* all effects are handled similarly with the exception of speed effect */
int type = (seq->type & SEQ_TYPE_EFFECT && seq->type != SEQ_TYPE_SPEED) ? SEQ_TYPE_EFFECT : seq->type;
- int is_preprocessed = !ELEM3(type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_SCENE);
-
- ibuf = BKE_sequencer_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF);
-
- /* currently, we cache preprocessed images in SEQ_STRIPELEM_IBUF,
- * but not(!) on SEQ_STRIPELEM_IBUF_ENDSTILL and ..._STARTSTILL */
- if (ibuf)
- use_preprocess = FALSE;
-
- if (ibuf == NULL)
- ibuf = copy_from_ibuf_still(context, seq, nr);
-
- /* MOVIECLIPs have their own proxy management */
- if (ibuf == NULL && seq->type != SEQ_TYPE_MOVIECLIP) {
- ibuf = seq_proxy_fetch(context, seq, cfra);
- is_proxy_image = (ibuf != NULL);
- }
+ int use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra);
+ char name[FILE_MAX];
- if (ibuf == NULL) switch (type) {
- case SEQ_TYPE_META:
- {
- ImBuf *meta_ibuf = NULL;
+ switch (type) {
+ case SEQ_TYPE_META:
+ {
+ ImBuf *meta_ibuf = NULL;
- if (seq->seqbase.first)
- meta_ibuf = seq_render_strip_stack(
- context, &seq->seqbase,
- seq->start + nr, 0);
+ if (seq->seqbase.first)
+ meta_ibuf = seq_render_strip_stack(context, &seq->seqbase, seq->start + nr, 0);
- if (meta_ibuf) {
- ibuf = meta_ibuf;
- if (ibuf && use_preprocess) {
- ImBuf *i = IMB_dupImBuf(ibuf);
+ if (meta_ibuf) {
+ ibuf = meta_ibuf;
+ if (ibuf && use_preprocess) {
+ ImBuf *i = IMB_dupImBuf(ibuf);
- IMB_freeImBuf(ibuf);
+ IMB_freeImBuf(ibuf);
- ibuf = i;
- }
+ ibuf = i;
}
-
- break;
}
- case SEQ_TYPE_SPEED:
- {
- ImBuf *child_ibuf = NULL;
- float f_cfra;
- SpeedControlVars *s = (SpeedControlVars *)seq->effectdata;
+ break;
+ }
- BKE_sequence_effect_speed_rebuild_map(context.scene, seq, 0);
+ case SEQ_TYPE_SPEED:
+ {
+ ImBuf *child_ibuf = NULL;
- /* weeek! */
- f_cfra = seq->start + s->frameMap[(int)nr];
+ float f_cfra;
+ SpeedControlVars *s = (SpeedControlVars *)seq->effectdata;
- child_ibuf = seq_render_strip(context, seq->seq1, f_cfra);
+ BKE_sequence_effect_speed_rebuild_map(context.scene, seq, 0);
- if (child_ibuf) {
- ibuf = child_ibuf;
- if (ibuf && use_preprocess) {
- ImBuf *i = IMB_dupImBuf(ibuf);
+ /* weeek! */
+ f_cfra = seq->start + s->frameMap[(int)nr];
- IMB_freeImBuf(ibuf);
+ child_ibuf = seq_render_strip(context, seq->seq1, f_cfra);
- ibuf = i;
- }
+ if (child_ibuf) {
+ ibuf = child_ibuf;
+ if (ibuf && use_preprocess) {
+ ImBuf *i = IMB_dupImBuf(ibuf);
+
+ IMB_freeImBuf(ibuf);
+
+ ibuf = i;
}
- break;
- }
- case SEQ_TYPE_EFFECT:
- {
- ibuf = seq_render_effect_strip_impl(context, seq, seq->start + nr);
- break;
}
- case SEQ_TYPE_IMAGE:
- {
- StripElem *s_elem = BKE_sequencer_give_stripelem(seq, cfra);
+ break;
+ }
- if (s_elem) {
- BLI_join_dirfile(name, sizeof(name), seq->strip->dir, s_elem->name);
- BLI_path_abs(name, G.main->name);
- }
+ case SEQ_TYPE_EFFECT:
+ {
+ ibuf = seq_render_effect_strip_impl(context, seq, seq->start + nr);
+ break;
+ }
- if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect))) {
- /* we don't need both (speed reasons)! */
- if (ibuf->rect_float && ibuf->rect)
- imb_freerectImBuf(ibuf);
+ case SEQ_TYPE_IMAGE:
+ {
+ StripElem *s_elem = BKE_sequencer_give_stripelem(seq, cfra);
- /* all sequencer color is done in SRGB space, linear gives odd crossfades */
- if (ibuf->profile == IB_PROFILE_LINEAR_RGB)
- IMB_convert_profile(ibuf, IB_PROFILE_NONE);
+ if (s_elem) {
+ BLI_join_dirfile(name, sizeof(name), seq->strip->dir, s_elem->name);
+ BLI_path_abs(name, G.main->name);
+ }
- copy_to_ibuf_still(context, seq, nr, ibuf);
+ if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect))) {
+ /* we don't need both (speed reasons)! */
+ if (ibuf->rect_float && ibuf->rect)
+ imb_freerectImBuf(ibuf);
- s_elem->orig_width = ibuf->x;
- s_elem->orig_height = ibuf->y;
- }
- break;
+ /* all sequencer color is done in SRGB space, linear gives odd crossfades */
+ if (ibuf->profile == IB_PROFILE_LINEAR_RGB)
+ IMB_convert_profile(ibuf, IB_PROFILE_NONE);
+
+ copy_to_ibuf_still(context, seq, nr, ibuf);
+
+ s_elem->orig_width = ibuf->x;
+ s_elem->orig_height = ibuf->y;
}
- case SEQ_TYPE_MOVIE:
- {
- seq_open_anim_file(seq);
+ break;
+ }
+
+ case SEQ_TYPE_MOVIE:
+ {
+ seq_open_anim_file(seq);
- if (seq->anim) {
- IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
+ if (seq->anim) {
+ IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
- ibuf = IMB_anim_absolute(seq->anim, nr + seq->anim_startofs,
- seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN,
- seq_rendersize_to_proxysize(context.preview_render_size));
+ ibuf = IMB_anim_absolute(seq->anim, nr + seq->anim_startofs,
+ seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN,
+ seq_rendersize_to_proxysize(context.preview_render_size));
- /* we don't need both (speed reasons)! */
- if (ibuf && ibuf->rect_float && ibuf->rect)
- imb_freerectImBuf(ibuf);
- if (ibuf) {
- seq->strip->stripdata->orig_width = ibuf->x;
- seq->strip->stripdata->orig_height = ibuf->y;
- }
+ /* we don't need both (speed reasons)! */
+ if (ibuf && ibuf->rect_float && ibuf->rect)
+ imb_freerectImBuf(ibuf);
+ if (ibuf) {
+ seq->strip->stripdata->orig_width = ibuf->x;
+ seq->strip->stripdata->orig_height = ibuf->y;
}
- copy_to_ibuf_still(context, seq, nr, ibuf);
- break;
}
- case SEQ_TYPE_SCENE:
- {
- /* scene can be NULL after deletions */
- ibuf = seq_render_scene_strip(context, seq, nr);
+ copy_to_ibuf_still(context, seq, nr, ibuf);
+ break;
+ }
- /* Scene strips update all animation, so we need to restore original state.*/
- BKE_animsys_evaluate_all_animation(context.bmain, context.scene, cfra);
+ case SEQ_TYPE_SCENE:
+ {
+ /* scene can be NULL after deletions */
+ ibuf = seq_render_scene_strip(context, seq, nr);
- copy_to_ibuf_still(context, seq, nr, ibuf);
- break;
- }
- case SEQ_TYPE_MOVIECLIP:
- {
- ibuf = seq_render_movieclip_strip(context, seq, nr);
+ /* Scene strips update all animation, so we need to restore original state.*/
+ BKE_animsys_evaluate_all_animation(context.bmain, context.scene, cfra);
- if (ibuf && use_preprocess) {
- ImBuf *i = IMB_dupImBuf(ibuf);
+ copy_to_ibuf_still(context, seq, nr, ibuf);
+ break;
+ }
- IMB_freeImBuf(ibuf);
+ case SEQ_TYPE_MOVIECLIP:
+ {
+ ibuf = seq_render_movieclip_strip(context, seq, nr);
- ibuf = i;
- }
+ if (ibuf && use_preprocess) {
+ ImBuf *i = IMB_dupImBuf(ibuf);
- copy_to_ibuf_still(context, seq, nr, ibuf);
- break;
+ IMB_freeImBuf(ibuf);
+
+ ibuf = i;
}
+
+ copy_to_ibuf_still(context, seq, nr, ibuf);
+ break;
+ }
+
case SEQ_TYPE_MASK:
{
/* ibuf is alwats new */
@@ -2492,6 +2532,46 @@ static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra)
}
}
+ return ibuf;
+}
+
+static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra)
+{
+ ImBuf *ibuf = NULL;
+ int use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra);
+ int is_proxy_image = FALSE;
+ float nr = give_stripelem_index(seq, cfra);
+ /* all effects are handled similarly with the exception of speed effect */
+ int type = (seq->type & SEQ_TYPE_EFFECT && seq->type != SEQ_TYPE_SPEED) ? SEQ_TYPE_EFFECT : seq->type;
+ int is_preprocessed = !ELEM3(type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_SCENE);
+
+ ibuf = BKE_sequencer_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF);
+
+ /* currently, we cache preprocessed images in SEQ_STRIPELEM_IBUF,
+ * but not(!) on SEQ_STRIPELEM_IBUF_ENDSTILL and ..._STARTSTILL */
+ if (ibuf)
+ use_preprocess = FALSE;
+
+ if (ibuf == NULL)
+ ibuf = copy_from_ibuf_still(context, seq, nr);
+
+ if (ibuf == NULL) {
+ ibuf = BKE_sequencer_preprocessed_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF);
+
+ if (ibuf == NULL) {
+ /* MOVIECLIPs have their own proxy management */
+ if (ibuf == NULL && seq->type != SEQ_TYPE_MOVIECLIP) {
+ ibuf = seq_proxy_fetch(context, seq, cfra);
+ is_proxy_image = (ibuf != NULL);
+ }
+
+ ibuf = do_render_strip_uncached(context, seq, cfra);
+
+ if (ibuf)
+ BKE_sequencer_preprocessed_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf);
+ }
+ }
+
if (ibuf == NULL)
ibuf = IMB_allocImBuf(context.rectx, context.recty, 32, IB_rect);
@@ -2876,7 +2956,7 @@ int BKE_sequence_check_depend(Sequence *seq, Sequence *cur)
return TRUE;
}
-void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq)
+static void sequence_invalidate_cache(Scene *scene, Sequence *seq, int invalidate_preprocess)
{
Editing *ed = scene->ed;
Sequence *cur;
@@ -2884,18 +2964,33 @@ void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq)
/* invalidate cache for current sequence */
BKE_sequencer_cache_cleanup_sequence(seq);
+ if (invalidate_preprocess)
+ BKE_sequencer_preprocessed_cache_cleanup_sequence(seq);
+
/* invalidate cache for all dependent sequences */
SEQ_BEGIN (ed, cur)
{
if (cur == seq)
continue;
- if (BKE_sequence_check_depend(seq, cur))
+ if (BKE_sequence_check_depend(seq, cur)) {
BKE_sequencer_cache_cleanup_sequence(cur);
+ BKE_sequencer_preprocessed_cache_cleanup_sequence(cur);
+ }
}
SEQ_END
}
+void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq)
+{
+ sequence_invalidate_cache(scene, seq, TRUE);
+}
+
+void BKE_sequence_invalidate_cache_for_modifier(Scene *scene, Sequence *seq)
+{
+ sequence_invalidate_cache(scene, seq, FALSE);
+}
+
void BKE_sequencer_free_imbuf(Scene *scene, ListBase *seqbase, int check_mem_usage, int keep_file_handles)
{
Sequence *seq;
@@ -3941,6 +4036,12 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
seqn->strip->color_balance = MEM_dupallocN(seq->strip->color_balance);
}
+ if (seqn->modifiers.first) {
+ seqn->modifiers.first = seqn->modifiers.last = NULL;
+
+ BKE_sequence_modifier_list_copy(seqn, seq);
+ }
+
if (seq->type == SEQ_TYPE_META) {
seqn->strip->stripdata = NULL;
@@ -4060,3 +4161,4 @@ int BKE_seqence_is_valid_check(Sequence *seq)
return TRUE;
}
+
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 5bad69c2e8d..2f54fe6cebd 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -1292,7 +1292,7 @@ PointDensity *BKE_add_pointdensity(void)
pd->falloff_curve->preset = CURVE_PRESET_LINE;
pd->falloff_curve->cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
curvemap_reset(pd->falloff_curve->cm, &pd->falloff_curve->clipr, pd->falloff_curve->preset, CURVEMAP_SLOPE_POSITIVE);
- curvemapping_changed(pd->falloff_curve, 0);
+ curvemapping_changed(pd->falloff_curve, FALSE);
return pd;
}
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index 303098ea0bd..dd71e43182e 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -128,8 +128,9 @@ World *BKE_world_copy(World *wrld)
}
}
- if (wrld->nodetree)
+ if (wrld->nodetree) {
wrldn->nodetree = ntreeCopyTree(wrld->nodetree);
+ }
if (wrld->preview)
wrldn->preview = BKE_previewimg_copy(wrld->preview);