- for (ch = 0; ch < channels; ++ch)
- out.channel[ch] = (1-pos) * before.channel[ch] + pos * after.channel[ch];
+ if (channels == 1 || channels == 3) {
+ for (ch = 0; ch < channels; ++ch)
+ out.channel[ch] = (1-pos) * before.channel[ch] + pos * after.channel[ch];
+ }
+ else {
+ int total_cover = (1-pos) * before.channel[channels-1]
+ + pos * after.channel[channels-1];
+
+ total_cover = I_LIMIT_8(total_cover);
+ if (total_cover) {
+ double before_alpha = before.channel[channels-1] / 255.0;
+ double after_alpha = after.channel[channels-1] / 255.0;
+ double total_alpha = before_alpha * (1-pos) + after_alpha * pos;
+
+ for (ch = 0; ch < channels-1; ++ch) {
+ int out_level = ((1-pos) * before.channel[ch] * before_alpha +
+ pos * after.channel[ch] * after_alpha + 0.5) / total_alpha;
+
+ out.channel[ch] = I_LIMIT_8(out_level);
+ }
+ }
+
+ out.channel[channels-1] = total_cover;
+ }