auto keyframe color prefs, colorpicker rework, ru.po update, keyframe align fixes...
[goodguy/history.git] / cinelerra-5.1 / cinelerra / overlayframe.C
index 098bf9dba97ab823475ef1c9c7d3d9fa1f2b89fa..642a936749df91cb57ab23b5f6b584a5cdd2ec57 100644 (file)
@@ -224,17 +224,61 @@ int OverlayFrame::overlay(VFrame *output, VFrame *input,
                isnan(out_x1) || isnan(out_x2) ||
                isnan(out_y1) || isnan(out_y2)) return 1;
 
-       if(in_x1 < 0) in_x1 = 0;
-       if(in_y1 < 0) in_y1 = 0;
-       if(in_x2 > input->get_w()) in_x2 = input->get_w();
-       if(in_y2 > input->get_h()) in_y2 = input->get_h();
-       if(out_x1 < 0) out_x1 = 0;
-       if(out_y1 < 0) out_y1 = 0;
-       if(out_x2 > output->get_w()) out_x2 = output->get_w();
-       if(out_y2 > output->get_h()) out_y2 = output->get_h();
+       if( in_x2 <= in_x1 || in_y2 <= in_y1 ) return 1;
+       if( out_x2 <= out_x1 || out_y2 <= out_y1 ) return 1;
 
        float xscale = (out_x2 - out_x1) / (in_x2 - in_x1);
        float yscale = (out_y2 - out_y1) / (in_y2 - in_y1);
+       int in_w = input->get_w(), in_h = input->get_h();
+       int out_w = output->get_w(), out_h = output->get_h();
+
+       if( in_x1 < 0 ) {
+               out_x1 -= in_x1 * xscale;
+               in_x1 = 0;
+       }
+       if( in_x2 > in_w ) {
+               out_x2 -= (in_x2 - in_w) * xscale;
+               in_x2 = in_w;
+       }
+       if( in_y1 < 0 ) {
+               out_y1 -= in_y1 * yscale;
+               in_y1 = 0;
+       }
+       if( in_y2 > in_h ) {
+               out_y2 -= (in_y2 - in_h) * yscale;
+               in_y2 = in_h;
+       }
+
+       if( out_x1 < 0 ) {
+               in_x1 -= out_x1 / xscale;
+               out_x1 = 0;
+       }
+       if( out_x2 > out_w ) {
+               in_x2 -= (out_x2 - out_w) / xscale;
+               out_x2 = out_w;
+       }
+       if( out_y1 < 0 ) {
+               in_y1 -= out_y1 / yscale;
+               out_y1 = 0;
+       }
+       if( out_y2 > out_h ) {
+               in_y2 -= (out_y2 - out_h) / yscale;
+               out_y2 = out_h;
+       }
+
+       if( in_x1 < 0) in_x1 = 0;
+       if( in_y1 < 0) in_y1 = 0;
+       if( in_x2 > in_w ) in_x2 = in_w;
+       if( in_y2 > in_h ) in_y2 = in_h;
+       if( out_x1 < 0) out_x1 = 0;
+       if( out_y1 < 0) out_y1 = 0;
+       if( out_x2 > out_w ) out_x2 = out_w;
+       if( out_y2 > out_h ) out_y2 = out_h;
+
+       if( in_x2 <= in_x1 || in_y2 <= in_y1 ) return 1;
+       if( out_x2 <= out_x1 || out_y2 <= out_y1 ) return 1;
+       xscale = (out_x2 - out_x1) / (in_x2 - in_x1);
+       yscale = (out_y2 - out_y1) / (in_y2 - in_y1);
 
        /* don't interpolate integer translations, or scale no-ops */
        if(xscale == 1. && yscale == 1. &&
@@ -483,13 +527,13 @@ ZTYP(int32_t);    ZTYP(uint32_t);
 ZTYP(int64_t); ZTYP(uint64_t);
 ZTYP(float);   ZTYP(double);
 
-#define ALPHA3_BLEND(FN, typ, inp, out, mx, ofs, rnd) \
-  typ inp0 = (typ)inp[0], inp1 = (typ)inp[1] - ofs; \
-  typ inp2 = (typ)inp[2] - ofs, inp3 = mx; \
-  typ out0 = (typ)out[0], out1 = (typ)out[1] - ofs; \
-  typ out2 = (typ)out[2] - ofs, out3 = mx; \
+#define ALPHA3_BLEND(FN, typ, inp, out, mx, iofs, oofs, rnd) \
+  typ inp0 = (typ)inp[0], inp1 = (typ)inp[1] - iofs; \
+  typ inp2 = (typ)inp[2] - iofs, inp3 = mx; \
+  typ out0 = (typ)out[0], out1 = (typ)out[1] - oofs; \
+  typ out2 = (typ)out[2] - oofs, out3 = mx; \
   r = COLOR_##FN(mx, inp0, inp3, out0, out3); \
-  if( ofs ) { \
+  if( oofs ) { \
     g = CHROMA_##FN(mx, inp1, inp3, out1, out3); \
     b = CHROMA_##FN(mx, inp2, inp3, out2, out3); \
   } \
@@ -498,13 +542,13 @@ ZTYP(float);      ZTYP(double);
     b = COLOR_##FN(mx, inp2, inp3, out2, out3); \
   }
 
-#define ALPHA4_BLEND(FN, typ, inp, out, mx, ofs, rnd) \
-  typ inp0 = (typ)inp[0], inp1 = (typ)inp[1] - ofs; \
-  typ inp2 = (typ)inp[2] - ofs, inp3 = inp[3]; \
-  typ out0 = (typ)out[0], out1 = (typ)out[1] - ofs; \
-  typ out2 = (typ)out[2] - ofs, out3 = out[3]; \
+#define ALPHA4_BLEND(FN, typ, inp, out, mx, iofs, oofs, rnd) \
+  typ inp0 = (typ)inp[0], inp1 = (typ)inp[1] - iofs; \
+  typ inp2 = (typ)inp[2] - iofs, inp3 = inp[3]; \
+  typ out0 = (typ)out[0], out1 = (typ)out[1] - oofs; \
+  typ out2 = (typ)out[2] - oofs, out3 = out[3]; \
   r = COLOR_##FN(mx, inp0, inp3, out0, out3); \
-  if( ofs ) { \
+  if( oofs ) { \
     g = CHROMA_##FN(mx, inp1, inp3, out1, out3); \
     b = CHROMA_##FN(mx, inp2, inp3, out2, out3); \
   } \
@@ -543,7 +587,7 @@ ZTYP(float);        ZTYP(double);
   ALPHA_STORE(out, ofs, mx); \
   out[3] = aclip(a, mx)
 
-#define XBLEND(FN, temp_type, type, max, components, chroma_offset, round) { \
+#define XBLEND(FN, temp_type, type, max, components, ofs, round) { \
        temp_type opcty = fade * max + round, trnsp = max - opcty; \
        type** output_rows = (type**)output->get_rows(); \
        type** input_rows = (type**)input->get_rows(); \
@@ -555,13 +599,13 @@ ZTYP(float);      ZTYP(double);
                for(int j = 0; j < ow; j++) { \
                        if( components == 4 ) { \
                                temp_type r, g, b, a; \
-                               ALPHA4_BLEND(FN, temp_type, in_row, output, max, chroma_offset, round); \
-                               ALPHA4_STORE(output, chroma_offset, max); \
+                               ALPHA4_BLEND(FN, temp_type, in_row, output, max, ofs, ofs, round); \
+                               ALPHA4_STORE(output, ofs, max); \
                        } \
                        else { \
                                temp_type r, g, b; \
-                               ALPHA3_BLEND(FN, temp_type, in_row, output, max, chroma_offset, round); \
-                               ALPHA3_STORE(output, chroma_offset, max); \
+                               ALPHA3_BLEND(FN, temp_type, in_row, output, max, ofs, ofs, round); \
+                               ALPHA3_STORE(output, ofs, max); \
                        } \
                        in_row += components;  output += components; \
                } \
@@ -688,7 +732,7 @@ LoadPackage* DirectEngine::new_package()
 
 /* Nearest Neighbor scale / translate / blend ********************/
 
-#define XBLEND_3NN(FN, temp_type, type, max, components, chroma_offset, round) { \
+#define XBLEND_3NN(FN, temp_type, type, max, components, ofs, round) { \
        temp_type opcty = fade * max + round, trnsp = max - opcty; \
        type** output_rows = (type**)output->get_rows(); \
        type** input_rows = (type**)input->get_rows(); \
@@ -702,13 +746,13 @@ LoadPackage* DirectEngine::new_package()
                        in_row += *lx++; \
                        if( components == 4 ) { \
                                temp_type r, g, b, a; \
-                               ALPHA4_BLEND(FN, temp_type, in_row, output, max, chroma_offset, round); \
-                               ALPHA4_STORE(output, chroma_offset, max); \
+                               ALPHA4_BLEND(FN, temp_type, in_row, output, max, ofs, ofs, round); \
+                               ALPHA4_STORE(output, ofs, max); \
                        } \
                        else { \
                                temp_type r, g, b; \
-                               ALPHA3_BLEND(FN, temp_type, in_row, output, max, chroma_offset, round); \
-                               ALPHA3_STORE(output, chroma_offset, max); \
+                               ALPHA3_BLEND(FN, temp_type, in_row, output, max, ofs, ofs, round); \
+                               ALPHA3_STORE(output, ofs, max); \
                        } \
                        output += components; \
                } \
@@ -905,7 +949,7 @@ LoadPackage* NNEngine::new_package()
 /* Fully resampled scale / translate / blend ******************************/
 /* resample into a temporary row vector, then blend */
 
-#define XSAMPLE(FN, temp_type, type, max, components, chroma_offset, round) { \
+#define XSAMPLE(FN, temp_type, type, max, components, ofs, round) { \
        float temp[oh*components]; \
        temp_type opcty = fade * max + round, trnsp = max - opcty; \
        type **output_rows = (type**)voutput->get_rows() + o1i; \
@@ -918,8 +962,8 @@ LoadPackage* NNEngine::new_package()
                        type *ip = input + i1i * components; \
                        for(int j = 0; j < oh; j++) { \
                                *tempp++ = *ip++; \
-                               *tempp++ = *ip++ - chroma_offset; \
-                               *tempp++ = *ip++ - chroma_offset; \
+                               *tempp++ = *ip++ - ofs; \
+                               *tempp++ = *ip++ - ofs; \
                                if( components == 4 ) *tempp++ = *ip++; \
                        } \
                } \
@@ -937,8 +981,8 @@ LoadPackage* NNEngine::new_package()
                                        if( components == 4 ) { awacc += kv;  kv *= ip[3]; } \
                                        wacc += kv; \
                                        racc += kv * *ip++; \
-                                       gacc += kv * (*ip++ - chroma_offset); \
-                                       bacc += kv * (*ip++ - chroma_offset); \
+                                       gacc += kv * (*ip++ - ofs); \
+                                       bacc += kv * (*ip++ - ofs); \
                                        if( components == 4 ) { aacc += kv;  ++ip; } \
                                        ki += kd; \
                                } \
@@ -965,13 +1009,13 @@ LoadPackage* NNEngine::new_package()
                        type *output = output_rows[j] + i * components; \
                        if( components == 4 ) { \
                                temp_type r, g, b, a; \
-                               ALPHA4_BLEND(FN, temp_type, tempp, output, max, 0, round); \
-                               ALPHA4_STORE(output, chroma_offset, max); \
+                               ALPHA4_BLEND(FN, temp_type, tempp, output, max, 0, ofs, round); \
+                               ALPHA4_STORE(output, ofs, max); \
                        } \
                        else { \
                                temp_type r, g, b; \
-                               ALPHA3_BLEND(FN, temp_type, tempp, output, max, 0, round); \
-                               ALPHA3_STORE(output, chroma_offset, max); \
+                               ALPHA3_BLEND(FN, temp_type, tempp, output, max, 0, ofs, round); \
+                               ALPHA3_STORE(output, ofs, max); \
                        } \
                        tempp += components; \
                } \