Skip to content

Commit 9a2ac9f

Browse files
committed
Fix: Animate to clamp interpolated values to between start and end value.
1 parent f69bfae commit 9a2ac9f

1 file changed

Lines changed: 26 additions & 2 deletions

File tree

avs_core/filters/combine.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -936,11 +936,35 @@ PVideoFrame __stdcall Animate::GetFrame(int n, IScriptEnvironment* env)
936936
if (args_before[a].IsInt() && args_after[a].IsInt()) {
937937
// 96.32 bit arithmetic, intermediate 128 bits inside.
938938
// Uses proper rounding when returning to real integer domain.
939-
args_now[a] = Muldiv_64_32_integer_arithm(args_before[a].AsLong(), args_after[a].AsLong(), stage_int_arith);
939+
int64_t start = args_before[a].AsLong();
940+
int64_t end = args_after[a].AsLong();
941+
int64_t interpolated_value = Muldiv_64_32_integer_arithm(start, end, stage_int_arith);
942+
int64_t lower_bound = std::min(start, end);
943+
int64_t upper_bound = std::max(start, end);
944+
// rounding error can occur, so that the intermediate result is not between the two values
945+
if (interpolated_value < lower_bound) {
946+
interpolated_value = lower_bound;
947+
}
948+
else if (interpolated_value > upper_bound) {
949+
interpolated_value = upper_bound;
950+
}
951+
args_now[a] = interpolated_value;
940952
}
941953
else if (args_before[a].IsFloat() && args_after[a].IsFloat()) {
942954
// note: AsFloat() returns double
943-
args_now[a] = args_before[a].AsFloat() * (1 - stage_mod) + args_after[a].AsFloat() * stage_mod;;
955+
double start = args_before[a].AsFloat();
956+
double end = args_after[a].AsFloat();
957+
double interpolated_value = start * (1 - stage_mod) + end * stage_mod;
958+
double lower_bound = std::min(start, end);
959+
double upper_bound = std::max(start, end);
960+
// rounding error can occur, so that the intermediate result is not between the two values
961+
if (interpolated_value < lower_bound) {
962+
interpolated_value = lower_bound;
963+
}
964+
else if (interpolated_value > upper_bound) {
965+
interpolated_value = upper_bound;
966+
}
967+
args_now[a] = interpolated_value;
944968
}
945969
else {
946970
args_now[a] = args_before[a]; // bool, string, etc.. no transition

0 commit comments

Comments
 (0)