graphic art overlay modes, pref window resize, submenu fixes
authorGood Guy <good1.2guy@gmail.com>
Sat, 1 Oct 2016 19:29:11 +0000 (13:29 -0600)
committerGood Guy <good1.2guy@gmail.com>
Sat, 1 Oct 2016 19:29:11 +0000 (13:29 -0600)
107 files changed:
cinelerra-5.1/cinelerra/Makefile
cinelerra-5.1/cinelerra/overlaydirect.C [new file with mode: 0644]
cinelerra-5.1/cinelerra/overlayframe.C
cinelerra-5.1/cinelerra/overlayframe.C.clamp [deleted file]
cinelerra-5.1/cinelerra/overlayframe.C.float [deleted file]
cinelerra-5.1/cinelerra/overlayframe.C.floattable [deleted file]
cinelerra-5.1/cinelerra/overlayframe.C.int [deleted file]
cinelerra-5.1/cinelerra/overlayframe.h
cinelerra-5.1/cinelerra/overlayframe.h.clamp [deleted file]
cinelerra-5.1/cinelerra/overlayframe.h.float [deleted file]
cinelerra-5.1/cinelerra/overlayframe.h.floattable [deleted file]
cinelerra-5.1/cinelerra/overlayframe.h.int [deleted file]
cinelerra-5.1/cinelerra/overlayframe.inc
cinelerra-5.1/cinelerra/overlaynearest.C [new file with mode: 0644]
cinelerra-5.1/cinelerra/overlaysample.C [new file with mode: 0644]
cinelerra-5.1/cinelerra/patchbay.C
cinelerra-5.1/cinelerra/playback3d.C
cinelerra-5.1/cinelerra/preferencesthread.C
cinelerra-5.1/cinelerra/theme.C
cinelerra-5.1/cinelerra/vpatchgui.C
cinelerra-5.1/cinelerra/vpatchgui.h
cinelerra-5.1/guicast/bcmenuitem.C
cinelerra-5.1/guicast/bcmenuitem.h
cinelerra-5.1/guicast/bcmenupopup.C
cinelerra-5.1/guicast/bcwindowbase.C
cinelerra-5.1/plugins/overlay/overlay.C
cinelerra-5.1/plugins/theme_blond/data/mode_and.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond/data/mode_average.png [deleted file]
cinelerra-5.1/plugins/theme_blond/data/mode_burn.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond/data/mode_difference.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond/data/mode_dodge.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond/data/mode_hardlight.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond/data/mode_overlay.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond/data/mode_screen.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond/data/mode_softlight.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond_cv/data/mode_and.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond_cv/data/mode_average.png [deleted file]
cinelerra-5.1/plugins/theme_blond_cv/data/mode_burn.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond_cv/data/mode_difference.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond_cv/data/mode_dodge.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond_cv/data/mode_hardlight.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond_cv/data/mode_overlay.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond_cv/data/mode_screen.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond_cv/data/mode_softlight.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue/data/mode_and.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue/data/mode_average.png [deleted file]
cinelerra-5.1/plugins/theme_blue/data/mode_burn.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue/data/mode_difference.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue/data/mode_dodge.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue/data/mode_hardlight.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue/data/mode_overlay.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue/data/mode_screen.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue/data/mode_softlight.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue_dot/data/mode_and.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue_dot/data/mode_average.png [deleted file]
cinelerra-5.1/plugins/theme_blue_dot/data/mode_burn.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue_dot/data/mode_difference.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue_dot/data/mode_dodge.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue_dot/data/mode_hardlight.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue_dot/data/mode_overlay.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue_dot/data/mode_screen.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue_dot/data/mode_softlight.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_bright/data/mode_and.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_bright/data/mode_average.png [deleted file]
cinelerra-5.1/plugins/theme_bright/data/mode_burn.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_bright/data/mode_difference.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_bright/data/mode_dodge.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_bright/data/mode_hardlight.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_bright/data/mode_overlay.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_bright/data/mode_screen.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_bright/data/mode_softlight.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_hulk/data/mode_and.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_hulk/data/mode_average.png [deleted file]
cinelerra-5.1/plugins/theme_hulk/data/mode_burn.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_hulk/data/mode_difference.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_hulk/data/mode_dodge.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_hulk/data/mode_hardlight.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_hulk/data/mode_overlay.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_hulk/data/mode_screen.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_hulk/data/mode_softlight.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_pinklady/data/mode_and.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_pinklady/data/mode_average.png [deleted file]
cinelerra-5.1/plugins/theme_pinklady/data/mode_burn.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_pinklady/data/mode_difference.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_pinklady/data/mode_dodge.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_pinklady/data/mode_hardlight.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_pinklady/data/mode_overlay.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_pinklady/data/mode_screen.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_pinklady/data/mode_softlight.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_suv/data/mode_and.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_suv/data/mode_average.png [deleted file]
cinelerra-5.1/plugins/theme_suv/data/mode_burn.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_suv/data/mode_difference.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_suv/data/mode_dodge.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_suv/data/mode_hardlight.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_suv/data/mode_overlay.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_suv/data/mode_screen.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_suv/data/mode_softlight.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_unflat/data/mode_and.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_unflat/data/mode_average.png [deleted file]
cinelerra-5.1/plugins/theme_unflat/data/mode_burn.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_unflat/data/mode_difference.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_unflat/data/mode_dodge.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_unflat/data/mode_hardlight.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_unflat/data/mode_overlay.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_unflat/data/mode_screen.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_unflat/data/mode_softlight.png [new file with mode: 0644]

index f2c3debd708657cd14edef17a55a9c5e67709d0d..853ab8f1a500bacbc66f76863367b08b079df572 100644 (file)
@@ -191,7 +191,10 @@ OBJS = \
        $(OBJDIR)/nestededls.o \
        $(OBJDIR)/newfolder.o \
        $(OBJDIR)/new.o \
+       $(OBJDIR)/overlaydirect.o \
        $(OBJDIR)/overlayframe.o \
+       $(OBJDIR)/overlaynearest.o \
+       $(OBJDIR)/overlaysample.o \
        $(OBJDIR)/packagedispatcher.o \
        $(OBJDIR)/packagerenderer.o \
        $(OBJDIR)/packagingengine.o \
diff --git a/cinelerra-5.1/cinelerra/overlaydirect.C b/cinelerra-5.1/cinelerra/overlaydirect.C
new file mode 100644 (file)
index 0000000..3297fda
--- /dev/null
@@ -0,0 +1,122 @@
+#include "overlayframe.h"
+
+/* Direct translate / blend **********************************************/
+
+#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(); \
+       ix *= components;  ox *= components; \
+ \
+       for(int i = pkg->out_row1; i < pkg->out_row2; i++) { \
+               type* in_row = input_rows[i + iy] + ix; \
+               type* output = output_rows[i] + ox; \
+               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, ofs, ofs, round); \
+                               ALPHA4_STORE(output, ofs, max); \
+                       } \
+                       else { \
+                               temp_type r, g, b; \
+                               ALPHA3_BLEND(FN, temp_type, in_row, output, max, ofs, ofs, round); \
+                               ALPHA3_STORE(output, ofs, max); \
+                       } \
+                       in_row += components;  output += components; \
+               } \
+       } \
+       break; \
+}
+
+#define XBLEND_ONLY(FN) { \
+       switch(input->get_color_model()) { \
+       case BC_RGB_FLOAT:      XBLEND(FN, z_float,   z_float,    1.f,    3, 0,      0.f); \
+       case BC_RGBA_FLOAT:     XBLEND(FN, z_float,   z_float,    1.f,    4, 0,      0.f); \
+       case BC_RGB888:         XBLEND(FN, z_int32_t, z_uint8_t,  0xff,   3, 0,      .5f); \
+       case BC_YUV888:         XBLEND(FN, z_int32_t, z_uint8_t,  0xff,   3, 0x80,   .5f); \
+       case BC_RGBA8888:       XBLEND(FN, z_int32_t, z_uint8_t,  0xff,   4, 0,      .5f); \
+       case BC_YUVA8888:       XBLEND(FN, z_int32_t, z_uint8_t,  0xff,   4, 0x80,   .5f); \
+       case BC_RGB161616:      XBLEND(FN, z_int64_t, z_uint16_t, 0xffff, 3, 0,      .5f); \
+       case BC_YUV161616:      XBLEND(FN, z_int64_t, z_uint16_t, 0xffff, 3, 0x8000, .5f); \
+       case BC_RGBA16161616:   XBLEND(FN, z_int64_t, z_uint16_t, 0xffff, 4, 0,      .5f); \
+       case BC_YUVA16161616:   XBLEND(FN, z_int64_t, z_uint16_t, 0xffff, 4, 0x8000, .5f); \
+       } \
+       break; \
+}
+
+DirectPackage::DirectPackage()
+{
+}
+
+DirectUnit::DirectUnit(DirectEngine *server)
+ : LoadClient(server)
+{
+       this->engine = server;
+}
+
+DirectUnit::~DirectUnit()
+{
+}
+
+void DirectUnit::process_package(LoadPackage *package)
+{
+       DirectPackage *pkg = (DirectPackage*)package;
+
+       VFrame *output = engine->output;
+       VFrame *input = engine->input;
+       int mode = engine->mode;
+       float fade =
+               BC_CModels::has_alpha(input->get_color_model()) &&
+               mode == TRANSFER_REPLACE ? 1.f : engine->alpha;
+
+       int ix = engine->in_x1;
+       int ox = engine->out_x1;
+       int ow = engine->out_x2 - ox;
+       int iy = engine->in_y1 - engine->out_y1;
+
+       BLEND_SWITCH(XBLEND_ONLY);
+}
+
+DirectEngine::DirectEngine(int cpus)
+ : LoadServer(cpus, cpus)
+{
+}
+
+DirectEngine::~DirectEngine()
+{
+}
+
+void DirectEngine::init_packages()
+{
+       if(in_x1 < 0) { out_x1 -= in_x1; in_x1 = 0; }
+       if(in_y1 < 0) { out_y1 -= in_y1; in_y1 = 0; }
+       if(out_x1 < 0) { in_x1 -= out_x1; out_x1 = 0; }
+       if(out_y1 < 0) { in_y1 -= out_y1; 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();
+       int out_w = out_x2 - out_x1;
+       int out_h = out_y2 - out_y1;
+       if( !out_w || !out_h ) return;
+
+       int rows = out_h;
+       int pkgs = get_total_packages();
+       int row1 = out_y1, row2 = row1;
+       for(int i = 0; i < pkgs; row1=row2 ) {
+               DirectPackage *package = (DirectPackage*)get_package(i);
+               row2 = ++i * rows / pkgs + out_y1;
+               package->out_row1 = row1;
+               package->out_row2 = row2;
+       }
+}
+
+LoadClient* DirectEngine::new_client()
+{
+       return new DirectUnit(this);
+}
+
+LoadPackage* DirectEngine::new_package()
+{
+       return new DirectPackage;
+}
+
+
index 642a936749df91cb57ab23b5f6b584a5cdd2ec57..849912fd4c93bee7c1bf40cdc342d3bfcfa032d0 100644 (file)
  * 
  */
 
-#include <math.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <unistd.h>
-
 #include "clip.h"
 #include "edl.inc"
 #include "mutex.h"
 #include "overlayframe.h"
 #include "units.h"
-#include "vframe.h"
-
-static inline int   mabs(int32_t v) { return abs(v); }
-static inline int   mabs(int64_t v) { return llabs(v); }
-static inline float mabs(float v)   { return fabsf(v); }
-
-static inline int32_t aclip(int32_t v, int mx) {
-       return v < 0 ? 0 : v > mx ? mx : v;
-}
-static inline int64_t aclip(int64_t v, int mx) {
-       return v < 0 ? 0 : v > mx ? mx : v;
-}
-static inline float   aclip(float v, float mx) {
-       return v < 0 ? 0 : v > mx ? mx : v;
-}
-static inline float   aclip(float v, int mx) {
-       return v < 0 ? 0 : v > mx ? mx : v;
-}
-static inline int   aclip(int v, float mx) {
-       return v < 0 ? 0 : v > mx ? mx : v;
-}
-static inline int32_t cclip(int32_t v, int mx) {
-       return v > (mx/=2) ? mx : v < (mx=(-mx-1)) ? mx : v;
-}
-static inline int64_t cclip(int64_t v, int mx) {
-       return v > (mx/=2) ? mx : v < (mx=(-mx-1)) ? mx : v;
-}
-static inline float   cclip(float v, float mx) {
-       return v > (mx/=2) ? mx : v < (mx=(-mx)) ? mx : v;
-}
-static inline float   cclip(float v, int mx) {
-       return v > (mx/=2) ? mx : v < (mx=(-mx-1)) ? mx : v;
-}
-static inline int   cclip(int v, float mx) {
-       return v > (mx/=2) ? mx : v < (mx=(-mx-1)) ? mx : v;
-}
 
 /*
  * New resampler code; replace the original somehwat blurry engine
@@ -107,19 +64,11 @@ static inline int   cclip(int v, float mx) {
  *    output_alpha = output_alpha + ((max - output_alpha) * input_alpha) / max;
  */
 
-#define TRANSFORM_SPP    (4096)    /* number of data pts per unit x in lookup table */
-#define INDEX_FRACTION   (8)       /* bits of fraction past TRANSFORM_SPP on kernel
-                                      index accumulation */
-#define TRANSFORM_MIN    (.5 / TRANSFORM_SPP)
-
 /* Sinc needed for Lanczos kernel */
 static float sinc(const float x)
 {
+       if(fabsf(x) < TRANSFORM_MIN) return 1.0f;
        float y = x * M_PI;
-
-       if(fabsf(x) < TRANSFORM_MIN)
-               return 1.0f;
-
        return sinf(y) / y;
 }
 
@@ -405,852 +354,4 @@ int OverlayFrame::overlay(VFrame *output, VFrame *input,
        return 0;
 }
 
-// NORMAL      [Sa + Da * (1 - Sa), Sc * Sa + Dc * (1 - Sa)])
-#define ALPHA_NORMAL(mx, Sa, Da) (Sa + (Da * (mx - Sa)) / mx)
-#define COLOR_NORMAL(mx, Sc, Sa, Dc, Da) ((Sc * Sa + Dc * (mx - Sa)) / mx)
-#define CHROMA_NORMAL COLOR_NORMAL
-
-// ADDITION    [(Sa + Da), (Sc + Dc)]
-#define ALPHA_ADDITION(mx, Sa, Da) (Sa + Da)
-#define COLOR_ADDITION(mx, Sc, Sa, Dc, Da) (Sc + Dc)
-#define CHROMA_ADDITION(mx, Sc, Sa, Dc, Da) (Sc + Dc)
-
-// SUBTRACT    [(Sa - Da), (Sc - Dc)]
-#define ALPHA_SUBTRACT(mx, Sa, Da) (Sa - Da)
-#define COLOR_SUBTRACT(mx, Sc, Sa, Dc, Da) (Sc - Dc)
-#define CHROMA_SUBTRACT(mx, Sc, Sa, Dc, Da) (Sc - Dc)
-
-// MULTIPLY    [(Sa * Da), Sc * Dc]
-#define ALPHA_MULTIPLY(mx, Sa, Da) ((Sa * Da) / mx)
-#define COLOR_MULTIPLY(mx, Sc, Sa, Dc, Da) ((Sc * Dc) / mx)
-#define CHROMA_MULTIPLY(mx, Sc, Sa, Dc, Da) ((Sc * Dc) / mx)
-
-// DIVIDE      [(Sa / Da), (Sc / Dc)]
-#define ALPHA_DIVIDE(mx, Sa, Da) (Da ? ((Sa * mx) / Da) : mx)
-#define COLOR_DIVIDE(mx, Sc, Sa, Dc, Da) (Dc ? ((Sc * mx) / Dc) : mx)
-#define CHROMA_DIVIDE(mx, Sc, Sa, Dc, Da) (Dc ? ((Sc * mx) / Dc) : mx)
-
-// REPLACE     [Sa, Sc] (fade = 1)
-#define ALPHA_REPLACE(mx, Sa, Da) Sa
-#define COLOR_REPLACE(mx, Sc, Sa, Dc, Da) Sc
-#define CHROMA_REPLACE COLOR_REPLACE
-
-// MAX         [max(Sa, Da), MAX(Sc, Dc)]
-#define ALPHA_MAX(mx, Sa, Da) (Sa > Da ? Sa : Da)
-#define COLOR_MAX(mx, Sc, Sa, Dc, Da) (Sc > Dc ? Sc : Dc)
-#define CHROMA_MAX(mx, Sc, Sa, Dc, Da) (mabs(Sc) > mabs(Dc) ? Sc : Dc)
-
-// MIN         [min(Sa, Da), MIN(Sc, Dc)]
-#define ALPHA_MIN(mx, Sa, Da) (Sa < Da ? Sa : Da)
-#define COLOR_MIN(mx, Sc, Sa, Dc, Da) (Sc < Dc ? Sc : Dc)
-#define CHROMA_MIN(mx, Sc, Sa, Dc, Da) (mabs(Sc) < mabs(Dc) ? Sc : Dc)
-
-// AVERAGE     [(Sa + Da) * 0.5, (Sc + Dc) * 0.5]
-#define ALPHA_AVERAGE(mx, Sa, Da) ((Sa + Da) / 2)
-#define COLOR_AVERAGE(mx, Sc, Sa, Dc, Da) ((Sc + Dc) / 2)
-#define CHROMA_AVERAGE COLOR_AVERAGE
-
-// DARKEN      [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)]  
-#define ALPHA_DARKEN(mx, Sa, Da) (Sa + Da - (Sa * Da) / mx)
-#define COLOR_DARKEN(mx, Sc, Sa, Dc, Da) ((Sc * (mx - Da) + Dc * (mx - Sa)) / mx + (Sc < Dc ? Sc : Dc))
-#define CHROMA_DARKEN(mx, Sc, Sa, Dc, Da) ((Sc * (mx - Da) + Dc * (mx - Sa)) / mx + (mabs(Sc) < mabs(Dc) ? Sc : Dc))
-
-// LIGHTEN     [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)]  
-#define ALPHA_LIGHTEN(mx, Sa, Da) (Sa + Da - Sa * Da / mx)
-#define COLOR_LIGHTEN(mx, Sc, Sa, Dc, Da) ((Sc * (mx - Da) + Dc * (mx - Sa)) / mx + (Sc > Dc ? Sc : Dc))
-#define CHROMA_LIGHTEN(mx, Sc, Sa, Dc, Da) ((Sc * (mx - Da) + Dc * (mx - Sa)) / mx + (mabs(Sc) > mabs(Dc) ? Sc : Dc))
-
-// DST         [Da, Dc]  
-#define ALPHA_DST(mx, Sa, Da) Da
-#define COLOR_DST(mx, Sc, Sa, Dc, Da) Dc
-#define CHROMA_DST COLOR_DST
-
-// DST_ATOP    [Sa, Sc * (1 - Da) + Dc * Sa]
-#define ALPHA_DST_ATOP(mx, Sa, Da) Sa
-#define COLOR_DST_ATOP(mx, Sc, Sa, Dc, Da) ((Sc * (mx - Da) + Dc * Sa) / mx)
-#define CHROMA_DST_ATOP COLOR_DST_ATOP
-
-// DST_IN      [Da * Sa, Dc * Sa]  
-#define ALPHA_DST_IN(mx, Sa, Da) ((Da * Sa) / mx)
-#define COLOR_DST_IN(mx, Sc, Sa, Dc, Da) ((Dc * Sa) / mx)
-#define CHROMA_DST_IN COLOR_DST_IN
-
-// DST_OUT     [Da * (1 - Sa), Dc * (1 - Sa)]  
-#define ALPHA_DST_OUT(mx, Sa, Da) (Da * (mx - Sa) / mx)
-#define COLOR_DST_OUT(mx, Sc, Sa, Dc, Da) (Dc * (mx - Sa) / mx)
-#define CHROMA_DST_OUT COLOR_DST_OUT
-
-// DST_OVER    [Sa * (1 - Da) + Da, Sc * (1 - Da) + Dc]  
-#define ALPHA_DST_OVER(mx, Sa, Da) ((Sa * (mx - Da)) / mx + Da)
-#define COLOR_DST_OVER(mx, Sc, Sa, Dc, Da) (Sc * (mx - Da)/ mx + Dc)
-#define CHROMA_DST_OVER COLOR_DST_OVER
-
-// SRC                 [Sa, Sc]  
-#define ALPHA_SRC(mx, Sa, Da) Sa
-#define COLOR_SRC(mx, Sc, Sa, Dc, Da) Sc
-#define CHROMA_SRC COLOR_SRC
-
-// SRC_ATOP    [Da, Sc * Da + Dc * (1 - Sa)]  
-#define ALPHA_SRC_ATOP(mx, Sa, Da) Da
-#define COLOR_SRC_ATOP(mx, Sc, Sa, Dc, Da) ((Sc * Da + Dc * (mx - Sa)) / mx)
-#define CHROMA_SRC_ATOP COLOR_SRC_ATOP
-
-// SRC_IN      [Sa * Da, Sc * Da]  
-#define ALPHA_SRC_IN(mx, Sa, Da) ((Sa * Da) / mx)
-#define COLOR_SRC_IN(mx, Sc, Sa, Dc, Da) (Sc * Da / mx)
-#define CHROMA_SRC_IN COLOR_SRC_IN
-
-// SRC_OUT     [Sa * (1 - Da), Sc * (1 - Da)]  
-#define ALPHA_SRC_OUT(mx, Sa, Da) (Sa * (mx - Da) / mx)
-#define COLOR_SRC_OUT(mx, Sc, Sa, Dc, Da) (Sc * (mx - Da) / mx)
-#define CHROMA_SRC_OUT COLOR_SRC_OUT
-
-// SRC_OVER    [Sa + Da * (1 - Sa), Sc + (1 - Sa) * Dc]  
-#define ALPHA_SRC_OVER(mx, Sa, Da) (Sa + Da * (mx - Sa) / mx)
-#define COLOR_SRC_OVER(mx, Sc, Sa, Dc, Da) (Sc + Dc * (mx - Sa) / mx)
-#define CHROMA_SRC_OVER COLOR_SRC_OVER
-
-// OR          [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc]   
-#define ALPHA_OR(mx, Sa, Da) (Sa + Da - (Sa * Da) / mx)
-#define COLOR_OR(mx, Sc, Sa, Dc, Da) (Sc + Dc - (Sc * Dc) / mx)
-#define CHROMA_OR COLOR_OR
-
-// XOR         [Sa * (1 - Da) + Da * (1 - Sa), Sc * (1 - Da) + Dc * (1 - Sa)]   
-#define ALPHA_XOR(mx, Sa, Da) ((Sa * (mx - Da) + Da * (mx - Sa)) / mx)
-#define COLOR_XOR(mx, Sc, Sa, Dc, Da) ((Sc * (mx - Da) + Dc * (mx - Sa)) / mx)
-#define CHROMA_XOR COLOR_XOR
-
-#define ZTYP(ty) typedef ty z_##ty __attribute__ ((__unused__))
-ZTYP(int8_t);  ZTYP(uint8_t);
-ZTYP(int16_t); ZTYP(uint16_t);
-ZTYP(int32_t); ZTYP(uint32_t);
-ZTYP(int64_t); ZTYP(uint64_t);
-ZTYP(float);   ZTYP(double);
-
-#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( oofs ) { \
-    g = CHROMA_##FN(mx, inp1, inp3, out1, out3); \
-    b = CHROMA_##FN(mx, inp2, inp3, out2, out3); \
-  } \
-  else { \
-    g = COLOR_##FN(mx, inp1, inp3, out1, out3); \
-    b = COLOR_##FN(mx, inp2, inp3, out2, out3); \
-  }
-
-#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( oofs ) { \
-    g = CHROMA_##FN(mx, inp1, inp3, out1, out3); \
-    b = CHROMA_##FN(mx, inp2, inp3, out2, out3); \
-  } \
-  else { \
-    g = COLOR_##FN(mx, inp1, inp3, out1, out3); \
-    b = COLOR_##FN(mx, inp2, inp3, out2, out3); \
-  } \
-  a = ALPHA_##FN(mx, inp3, out3)
-
-#define ALPHA_STORE(out, ofs, mx) \
-  out[0] = r; \
-  out[1] = g + ofs; \
-  out[2] = b + ofs
-
-#define ALPHA3_STORE(out, ofs, mx) \
-  r = aclip(r, mx); \
-  g = ofs ? cclip(g, mx) : aclip(g, mx); \
-  b = ofs ? cclip(b, mx) : aclip(b, mx); \
-  if( trnsp ) { \
-    r = (r * opcty + out0 * trnsp) / mx; \
-    g = (g * opcty + out1 * trnsp) / mx; \
-    b = (b * opcty + out2 * trnsp) / mx; \
-  } \
-  ALPHA_STORE(out, ofs, mx)
-
-#define ALPHA4_STORE(out, ofs, mx) \
-  r = aclip(r, mx); \
-  g = ofs ? cclip(g, mx) : aclip(g, mx); \
-  b = ofs ? cclip(b, mx) : aclip(b, mx); \
-  if( trnsp ) { \
-    r = (r * opcty + out0 * trnsp) / mx; \
-    g = (g * opcty + out1 * trnsp) / mx; \
-    b = (b * opcty + out2 * trnsp) / mx; \
-    a = (a * opcty + out3 * trnsp) / mx; \
-  } \
-  ALPHA_STORE(out, ofs, mx); \
-  out[3] = aclip(a, mx)
-
-#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(); \
-       ix *= components;  ox *= components; \
- \
-       for(int i = pkg->out_row1; i < pkg->out_row2; i++) { \
-               type* in_row = input_rows[i + iy] + ix; \
-               type* output = output_rows[i] + ox; \
-               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, ofs, ofs, round); \
-                               ALPHA4_STORE(output, ofs, max); \
-                       } \
-                       else { \
-                               temp_type r, g, b; \
-                               ALPHA3_BLEND(FN, temp_type, in_row, output, max, ofs, ofs, round); \
-                               ALPHA3_STORE(output, ofs, max); \
-                       } \
-                       in_row += components;  output += components; \
-               } \
-       } \
-       break; \
-}
-
-#define XBLEND_ONLY(FN) { \
-       switch(input->get_color_model()) { \
-       case BC_RGB_FLOAT:      XBLEND(FN, z_float,   z_float,    1.f,    3, 0,      0.f); \
-       case BC_RGBA_FLOAT:     XBLEND(FN, z_float,   z_float,    1.f,    4, 0,      0.f); \
-       case BC_RGB888:         XBLEND(FN, z_int32_t, z_uint8_t,  0xff,   3, 0,      .5f); \
-       case BC_YUV888:         XBLEND(FN, z_int32_t, z_uint8_t,  0xff,   3, 0x80,   .5f); \
-       case BC_RGBA8888:       XBLEND(FN, z_int32_t, z_uint8_t,  0xff,   4, 0,      .5f); \
-       case BC_YUVA8888:       XBLEND(FN, z_int32_t, z_uint8_t,  0xff,   4, 0x80,   .5f); \
-       case BC_RGB161616:      XBLEND(FN, z_int64_t, z_uint16_t, 0xffff, 3, 0,      .5f); \
-       case BC_YUV161616:      XBLEND(FN, z_int64_t, z_uint16_t, 0xffff, 3, 0x8000, .5f); \
-       case BC_RGBA16161616:   XBLEND(FN, z_int64_t, z_uint16_t, 0xffff, 4, 0,      .5f); \
-       case BC_YUVA16161616:   XBLEND(FN, z_int64_t, z_uint16_t, 0xffff, 4, 0x8000, .5f); \
-       } \
-       break; \
-}
-
-/* Direct translate / blend **********************************************/
-
-DirectPackage::DirectPackage()
-{
-}
-
-DirectUnit::DirectUnit(DirectEngine *server)
- : LoadClient(server)
-{
-       this->engine = server;
-}
-
-DirectUnit::~DirectUnit()
-{
-}
-
-void DirectUnit::process_package(LoadPackage *package)
-{
-       DirectPackage *pkg = (DirectPackage*)package;
-
-       VFrame *output = engine->output;
-       VFrame *input = engine->input;
-       int mode = engine->mode;
-       float fade =
-               BC_CModels::has_alpha(input->get_color_model()) &&
-               mode == TRANSFER_REPLACE ? 1.f : engine->alpha;
-
-       int ix = engine->in_x1;
-       int ox = engine->out_x1;
-       int ow = engine->out_x2 - ox;
-       int iy = engine->in_y1 - engine->out_y1;
-
-       switch( mode ) {
-        case TRANSFER_NORMAL:          XBLEND_ONLY(NORMAL);
-        case TRANSFER_ADDITION:                XBLEND_ONLY(ADDITION);
-        case TRANSFER_SUBTRACT:                XBLEND_ONLY(SUBTRACT);
-        case TRANSFER_MULTIPLY:                XBLEND_ONLY(MULTIPLY);
-        case TRANSFER_DIVIDE:          XBLEND_ONLY(DIVIDE);
-        case TRANSFER_REPLACE:                 XBLEND_ONLY(REPLACE);
-        case TRANSFER_MAX:             XBLEND_ONLY(MAX);
-        case TRANSFER_MIN:             XBLEND_ONLY(MIN);
-       case TRANSFER_AVERAGE:          XBLEND_ONLY(AVERAGE);
-       case TRANSFER_DARKEN:           XBLEND_ONLY(DARKEN);
-       case TRANSFER_LIGHTEN:          XBLEND_ONLY(LIGHTEN);
-       case TRANSFER_DST:              XBLEND_ONLY(DST);
-       case TRANSFER_DST_ATOP:         XBLEND_ONLY(DST_ATOP);
-       case TRANSFER_DST_IN:           XBLEND_ONLY(DST_IN);
-       case TRANSFER_DST_OUT:          XBLEND_ONLY(DST_OUT);
-       case TRANSFER_DST_OVER:         XBLEND_ONLY(DST_OVER);
-       case TRANSFER_SRC:              XBLEND_ONLY(SRC);
-       case TRANSFER_SRC_ATOP:         XBLEND_ONLY(SRC_ATOP);
-       case TRANSFER_SRC_IN:           XBLEND_ONLY(SRC_IN);
-       case TRANSFER_SRC_OUT:          XBLEND_ONLY(SRC_OUT);
-       case TRANSFER_SRC_OVER:         XBLEND_ONLY(SRC_OVER);
-       case TRANSFER_OR:               XBLEND_ONLY(OR);
-       case TRANSFER_XOR:              XBLEND_ONLY(XOR);
-       }
-}
-
-DirectEngine::DirectEngine(int cpus)
- : LoadServer(cpus, cpus)
-{
-}
-
-DirectEngine::~DirectEngine()
-{
-}
-
-void DirectEngine::init_packages()
-{
-       if(in_x1 < 0) { out_x1 -= in_x1; in_x1 = 0; }
-       if(in_y1 < 0) { out_y1 -= in_y1; in_y1 = 0; }
-       if(out_x1 < 0) { in_x1 -= out_x1; out_x1 = 0; }
-       if(out_y1 < 0) { in_y1 -= out_y1; 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();
-       int out_w = out_x2 - out_x1;
-       int out_h = out_y2 - out_y1;
-       if( !out_w || !out_h ) return;
-
-       int rows = out_h;
-       int pkgs = get_total_packages();
-       int row1 = out_y1, row2 = row1;
-       for(int i = 0; i < pkgs; row1=row2 ) {
-               DirectPackage *package = (DirectPackage*)get_package(i);
-               row2 = ++i * rows / pkgs + out_y1;
-               package->out_row1 = row1;
-               package->out_row2 = row2;
-       }
-}
-
-LoadClient* DirectEngine::new_client()
-{
-       return new DirectUnit(this);
-}
-
-LoadPackage* DirectEngine::new_package()
-{
-       return new DirectPackage;
-}
-
-/* Nearest Neighbor scale / translate / blend ********************/
-
-#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(); \
-       ox *= components; \
- \
-       for(int i = pkg->out_row1; i < pkg->out_row2; i++) { \
-               int *lx = engine->in_lookup_x; \
-               type* in_row = input_rows[*ly++]; \
-               type* output = output_rows[i] + ox; \
-               for(int j = 0; j < ow; j++) { \
-                       in_row += *lx++; \
-                       if( components == 4 ) { \
-                               temp_type r, g, b, a; \
-                               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, ofs, ofs, round); \
-                               ALPHA3_STORE(output, ofs, max); \
-                       } \
-                       output += components; \
-               } \
-       } \
-       break; \
-}
-
-#define XBLEND_NN(FN) { \
-       switch(input->get_color_model()) { \
-       case BC_RGB_FLOAT:      XBLEND_3NN(FN, z_float,   z_float,    1.f,    3, 0,       0.f); \
-       case BC_RGBA_FLOAT:     XBLEND_3NN(FN, z_float,   z_float,    1.f,    4, 0,       0.f); \
-       case BC_RGB888:         XBLEND_3NN(FN, z_int32_t, z_uint8_t,  0xff,   3, 0,      .5f); \
-       case BC_YUV888:         XBLEND_3NN(FN, z_int32_t, z_uint8_t,  0xff,   3, 0x80,   .5f); \
-       case BC_RGBA8888:       XBLEND_3NN(FN, z_int32_t, z_uint8_t,  0xff,   4, 0,      .5f); \
-       case BC_YUVA8888:       XBLEND_3NN(FN, z_int32_t, z_uint8_t,  0xff,   4, 0x80,   .5f); \
-       case BC_RGB161616:      XBLEND_3NN(FN, z_int64_t, z_uint16_t, 0xffff, 3, 0,      .5f); \
-       case BC_YUV161616:      XBLEND_3NN(FN, z_int64_t, z_uint16_t, 0xffff, 3, 0x8000, .5f); \
-       case BC_RGBA16161616:   XBLEND_3NN(FN, z_int64_t, z_uint16_t, 0xffff, 4, 0,      .5f); \
-       case BC_YUVA16161616:   XBLEND_3NN(FN, z_int64_t, z_uint16_t, 0xffff, 4, 0x8000, .5f); \
-       } \
-       break; \
-}
-
-NNPackage::NNPackage()
-{
-}
-
-NNUnit::NNUnit(NNEngine *server)
- : LoadClient(server)
-{
-       this->engine = server;
-}
-
-NNUnit::~NNUnit()
-{
-}
-
-void NNUnit::process_package(LoadPackage *package)
-{
-       NNPackage *pkg = (NNPackage*)package;
-       VFrame *output = engine->output;
-       VFrame *input = engine->input;
-       int mode = engine->mode;
-       float fade =
-               BC_CModels::has_alpha(input->get_color_model()) &&
-               mode == TRANSFER_REPLACE ? 1.f : engine->alpha;
 
-       int ox = engine->out_x1i;
-       int ow = engine->out_x2i - ox;
-       int *ly = engine->in_lookup_y + pkg->out_row1;
-
-       switch( mode ) {
-        case TRANSFER_NORMAL:          XBLEND_NN(NORMAL);
-        case TRANSFER_ADDITION:                XBLEND_NN(ADDITION);
-        case TRANSFER_SUBTRACT:                XBLEND_NN(SUBTRACT);
-        case TRANSFER_MULTIPLY:                XBLEND_NN(MULTIPLY);
-        case TRANSFER_DIVIDE:          XBLEND_NN(DIVIDE);
-        case TRANSFER_REPLACE:                 XBLEND_NN(REPLACE);
-        case TRANSFER_MAX:             XBLEND_NN(MAX);
-        case TRANSFER_MIN:             XBLEND_NN(MIN);
-       case TRANSFER_AVERAGE:          XBLEND_NN(AVERAGE);
-       case TRANSFER_DARKEN:           XBLEND_NN(DARKEN);
-       case TRANSFER_LIGHTEN:          XBLEND_NN(LIGHTEN);
-       case TRANSFER_DST:              XBLEND_NN(DST);
-       case TRANSFER_DST_ATOP:         XBLEND_NN(DST_ATOP);
-       case TRANSFER_DST_IN:           XBLEND_NN(DST_IN);
-       case TRANSFER_DST_OUT:          XBLEND_NN(DST_OUT);
-       case TRANSFER_DST_OVER:         XBLEND_NN(DST_OVER);
-       case TRANSFER_SRC:              XBLEND_NN(SRC);
-       case TRANSFER_SRC_ATOP:         XBLEND_NN(SRC_ATOP);
-       case TRANSFER_SRC_IN:           XBLEND_NN(SRC_IN);
-       case TRANSFER_SRC_OUT:          XBLEND_NN(SRC_OUT);
-       case TRANSFER_SRC_OVER:         XBLEND_NN(SRC_OVER);
-       case TRANSFER_OR:               XBLEND_NN(OR);
-       case TRANSFER_XOR:              XBLEND_NN(XOR);
-       }
-}
-
-NNEngine::NNEngine(int cpus)
- : LoadServer(cpus, cpus)
-{
-       in_lookup_x = 0;
-       in_lookup_y = 0;
-}
-
-NNEngine::~NNEngine()
-{
-       if(in_lookup_x)
-               delete[] in_lookup_x;
-       if(in_lookup_y)
-               delete[] in_lookup_y;
-}
-
-void NNEngine::init_packages()
-{
-       int in_w = input->get_w();
-       int in_h = input->get_h();
-       int out_w = output->get_w();
-       int out_h = output->get_h();
-
-       float in_subw = in_x2 - in_x1;
-       float in_subh = in_y2 - in_y1;
-       float out_subw = out_x2 - out_x1;
-       float out_subh = out_y2 - out_y1;
-       int first, last, count, i;
-       int components = 3;
-
-       out_x1i = rint(out_x1);
-       out_x2i = rint(out_x2);
-       if(out_x1i < 0) out_x1i = 0;
-       if(out_x1i > out_w) out_x1i = out_w;
-       if(out_x2i < 0) out_x2i = 0;
-       if(out_x2i > out_w) out_x2i = out_w;
-       int out_wi = out_x2i - out_x1i;
-       if( !out_wi ) return;
-
-       delete[] in_lookup_x;
-       in_lookup_x = new int[out_wi];
-       delete[] in_lookup_y;
-       in_lookup_y = new int[out_h];
-
-       switch(input->get_color_model()) {
-       case BC_RGBA_FLOAT:
-       case BC_RGBA8888:
-       case BC_YUVA8888:
-       case BC_RGBA16161616:
-               components = 4;
-               break;
-       }
-
-       first = count = 0;
-
-       for(i = out_x1i; i < out_x2i; i++) {
-               int in = (i - out_x1 + .5) * in_subw / out_subw + in_x1;
-               if(in < in_x1)
-                       in = in_x1;
-               if(in > in_x2)
-                       in = in_x2;
-
-               if(in >= 0 && in < in_w && in >= in_x1 && i >= 0 && i < out_w) {
-                       if(count == 0) {
-                               first = i;
-                               in_lookup_x[0] = in * components;
-                       }
-                       else {
-                               in_lookup_x[count] = (in-last)*components;
-                       }
-                       last = in;
-                       count++;
-               }
-               else if(count)
-                       break;
-       }
-       out_x1i = first;
-       out_x2i = first + count;
-       first = count = 0;
-
-       for(i = out_y1; i < out_y2; i++) {
-               int in = (i - out_y1+.5) * in_subh / out_subh + in_y1;
-               if(in < in_y1) in = in_y1;
-               if(in > in_y2) in = in_y2;
-               if(in >= 0 && in < in_h && i >= 0 && i < out_h) {
-                       if(count == 0) first = i;
-                       in_lookup_y[i] = in;
-                       count++;
-               }
-               else if(count)
-                       break;
-       }
-       out_y1 = first;
-       out_y2 = first + count;
-
-       int rows = count;
-       int pkgs = get_total_packages();
-       int row1 = out_y1, row2 = row1;
-       for(int i = 0; i < pkgs; row1=row2 ) {
-               NNPackage *package = (NNPackage*)get_package(i);
-               row2 = ++i * rows / pkgs + out_y1;
-               package->out_row1 = row1;
-               package->out_row2 = row2;
-       }
-}
-
-LoadClient* NNEngine::new_client()
-{
-       return new NNUnit(this);
-}
-
-LoadPackage* NNEngine::new_package()
-{
-       return new NNPackage;
-}
-
-/* Fully resampled scale / translate / blend ******************************/
-/* resample into a temporary row vector, then blend */
-
-#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; \
-       type **input_rows = (type**)vinput->get_rows(); \
- \
-       for(int i = pkg->out_col1; i < pkg->out_col2; i++) { \
-               type *input = input_rows[i - engine->col_out1 + engine->row_in]; \
-               float *tempp = temp; \
-               if( !k ) { /* direct copy case */ \
-                       type *ip = input + i1i * components; \
-                       for(int j = 0; j < oh; j++) { \
-                               *tempp++ = *ip++; \
-                               *tempp++ = *ip++ - ofs; \
-                               *tempp++ = *ip++ - ofs; \
-                               if( components == 4 ) *tempp++ = *ip++; \
-                       } \
-               } \
-               else { /* resample */ \
-                       for(int j = 0; j < oh; j++) { \
-                               float racc=0.f, gacc=0.f, bacc=0.f, aacc=0.f; \
-                               int ki = lookup_sk[j], x = lookup_sx0[j]; \
-                               type *ip = input + x * components; \
-                               float wacc = 0, awacc = 0; \
-                               while(x++ < lookup_sx1[j]) { \
-                                       float kv = k[abs(ki >> INDEX_FRACTION)]; \
-                                       /* handle fractional pixels on edges of input */ \
-                                       if(x == i1i) kv *= i1f; \
-                                       if(x + 1 == i2i) kv *= i2f; \
-                                       if( components == 4 ) { awacc += kv;  kv *= ip[3]; } \
-                                       wacc += kv; \
-                                       racc += kv * *ip++; \
-                                       gacc += kv * (*ip++ - ofs); \
-                                       bacc += kv * (*ip++ - ofs); \
-                                       if( components == 4 ) { aacc += kv;  ++ip; } \
-                                       ki += kd; \
-                               } \
-                               if(wacc > 0.) wacc = 1. / wacc; \
-                               *tempp++ = racc * wacc; \
-                               *tempp++ = gacc * wacc; \
-                               *tempp++ = bacc * wacc; \
-                               if( components == 4 ) { \
-                                       if(awacc > 0.) awacc = 1. / awacc; \
-                                       *tempp++ = aacc * awacc; \
-                               } \
-                       } \
-               } \
- \
-               /* handle fractional pixels on edges of output */ \
-               temp[0] *= o1f;   temp[1] *= o1f;   temp[2] *= o1f; \
-               if( components == 4 ) temp[3] *= o1f; \
-               tempp = temp + (oh-1)*components; \
-               tempp[0] *= o2f;  tempp[1] *= o2f;  tempp[2] *= o2f; \
-               if( components == 4 ) tempp[3] *= o2f; \
-               tempp = temp; \
-               /* blend output */ \
-               for(int j = 0; j < oh; j++) { \
-                       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, ofs, round); \
-                               ALPHA4_STORE(output, ofs, max); \
-                       } \
-                       else { \
-                               temp_type r, g, b; \
-                               ALPHA3_BLEND(FN, temp_type, tempp, output, max, 0, ofs, round); \
-                               ALPHA3_STORE(output, ofs, max); \
-                       } \
-                       tempp += components; \
-               } \
-       } \
-       break; \
-}
-
-#define XBLEND_SAMPLE(FN) { \
-        switch(vinput->get_color_model()) { \
-        case BC_RGB_FLOAT:      XSAMPLE(FN, z_float,   z_float,    1.f,    3, 0.f,    0.f); \
-        case BC_RGBA_FLOAT:     XSAMPLE(FN, z_float,   z_float,    1.f,    4, 0.f,    0.f); \
-        case BC_RGB888:         XSAMPLE(FN, z_int32_t, z_uint8_t,  0xff,   3, 0,      .5f); \
-        case BC_YUV888:         XSAMPLE(FN, z_int32_t, z_uint8_t,  0xff,   3, 0x80,   .5f); \
-        case BC_RGBA8888:       XSAMPLE(FN, z_int32_t, z_uint8_t,  0xff,   4, 0,      .5f); \
-        case BC_YUVA8888:       XSAMPLE(FN, z_int32_t, z_uint8_t,  0xff,   4, 0x80,   .5f); \
-        case BC_RGB161616:      XSAMPLE(FN, z_int64_t, z_uint16_t, 0xffff, 3, 0,      .5f); \
-        case BC_YUV161616:      XSAMPLE(FN, z_int64_t, z_uint16_t, 0xffff, 3, 0x8000, .5f); \
-        case BC_RGBA16161616:   XSAMPLE(FN, z_int64_t, z_uint16_t, 0xffff, 4, 0,      .5f); \
-        case BC_YUVA16161616:   XSAMPLE(FN, z_int64_t, z_uint16_t, 0xffff, 4, 0x8000, .5f); \
-        } \
-        break; \
-}
-
-
-SamplePackage::SamplePackage()
-{
-}
-
-SampleUnit::SampleUnit(SampleEngine *server)
- : LoadClient(server)
-{
-       this->engine = server;
-}
-
-SampleUnit::~SampleUnit()
-{
-}
-
-void SampleUnit::process_package(LoadPackage *package)
-{
-       SamplePackage *pkg = (SamplePackage*)package;
-
-       float i1  = engine->in1;
-       float i2  = engine->in2;
-       float o1  = engine->out1;
-       float o2  = engine->out2;
-
-       if(i2 - i1 <= 0 || o2 - o1 <= 0)
-               return;
-
-       VFrame *voutput = engine->output;
-       VFrame *vinput = engine->input;
-       int mode = engine->mode;
-       float fade =
-               BC_CModels::has_alpha(vinput->get_color_model()) &&
-               mode == TRANSFER_REPLACE ? 1.f : engine->alpha;
-
-       //int   iw  = vinput->get_w();
-       int   i1i = floor(i1);
-       int   i2i = ceil(i2);
-       float i1f = 1.f - i1 + i1i;
-       float i2f = 1.f - i2i + i2;
-
-       int   o1i = floor(o1);
-       int   o2i = ceil(o2);
-       float o1f = 1.f - o1 + o1i;
-       float o2f = 1.f - o2i + o2;
-       int   oh  = o2i - o1i;
-
-       float *k  = engine->kernel->lookup;
-       //float kw  = engine->kernel->width;
-       //int   kn  = engine->kernel->n;
-       int   kd = engine->kd;
-
-       int *lookup_sx0 = engine->lookup_sx0;
-       int *lookup_sx1 = engine->lookup_sx1;
-       int *lookup_sk = engine->lookup_sk;
-       //float *lookup_wacc = engine->lookup_wacc;
-
-       switch( mode ) {
-        case TRANSFER_NORMAL:          XBLEND_SAMPLE(NORMAL);
-        case TRANSFER_ADDITION:                XBLEND_SAMPLE(ADDITION);
-        case TRANSFER_SUBTRACT:                XBLEND_SAMPLE(SUBTRACT);
-        case TRANSFER_MULTIPLY:                XBLEND_SAMPLE(MULTIPLY);
-        case TRANSFER_DIVIDE:          XBLEND_SAMPLE(DIVIDE);
-        case TRANSFER_REPLACE:                 XBLEND_SAMPLE(REPLACE);
-        case TRANSFER_MAX:             XBLEND_SAMPLE(MAX);
-        case TRANSFER_MIN:             XBLEND_SAMPLE(MIN);
-       case TRANSFER_AVERAGE:          XBLEND_SAMPLE(AVERAGE);
-       case TRANSFER_DARKEN:           XBLEND_SAMPLE(DARKEN);
-       case TRANSFER_LIGHTEN:          XBLEND_SAMPLE(LIGHTEN);
-       case TRANSFER_DST:              XBLEND_SAMPLE(DST);
-       case TRANSFER_DST_ATOP:         XBLEND_SAMPLE(DST_ATOP);
-       case TRANSFER_DST_IN:           XBLEND_SAMPLE(DST_IN);
-       case TRANSFER_DST_OUT:          XBLEND_SAMPLE(DST_OUT);
-       case TRANSFER_DST_OVER:         XBLEND_SAMPLE(DST_OVER);
-       case TRANSFER_SRC:              XBLEND_SAMPLE(SRC);
-       case TRANSFER_SRC_ATOP:         XBLEND_SAMPLE(SRC_ATOP);
-       case TRANSFER_SRC_IN:           XBLEND_SAMPLE(SRC_IN);
-       case TRANSFER_SRC_OUT:          XBLEND_SAMPLE(SRC_OUT);
-       case TRANSFER_SRC_OVER:         XBLEND_SAMPLE(SRC_OVER);
-       case TRANSFER_OR:               XBLEND_SAMPLE(OR);
-       case TRANSFER_XOR:              XBLEND_SAMPLE(XOR);
-       }
-}
-
-
-SampleEngine::SampleEngine(int cpus)
- : LoadServer(cpus, cpus)
-{
-       lookup_sx0 = 0;
-       lookup_sx1 = 0;
-       lookup_sk = 0;
-       lookup_wacc = 0;
-       kd = 0;
-}
-
-SampleEngine::~SampleEngine()
-{
-       if(lookup_sx0) delete [] lookup_sx0;
-       if(lookup_sx1) delete [] lookup_sx1;
-       if(lookup_sk) delete [] lookup_sk;
-       if(lookup_wacc) delete [] lookup_wacc;
-}
-
-/*
- * unlike the Direct and NN engines, the Sample engine works across
- * output columns (it makes for more economical memory addressing
- * during convolution)
- */
-void SampleEngine::init_packages()
-{
-       int   iw  = input->get_w();
-       int   i1i = floor(in1);
-       int   i2i = ceil(in2);
-       float i1f = 1.f - in1 + i1i;
-       float i2f = 1.f - i2i + in2;
-
-       int   oy  = floor(out1);
-       float oyf = out1 - oy;
-       int   oh  = ceil(out2) - oy;
-
-       float *k  = kernel->lookup;
-       float kw  = kernel->width;
-       int   kn  = kernel->n;
-
-       if(in2 - in1 <= 0 || out2 - out1 <= 0)
-               return;
-
-       /* determine kernel spatial coverage */
-       float scale = (out2 - out1) / (in2 - in1);
-       float iscale = (in2 - in1) / (out2 - out1);
-       float coverage = fabs(1.f / scale);
-       float bound = (coverage < 1.f ? kw : kw * coverage) - (.5f / TRANSFORM_SPP);
-       float coeff = (coverage < 1.f ? 1.f : scale) * TRANSFORM_SPP;
-
-       delete [] lookup_sx0;
-       delete [] lookup_sx1;
-       delete [] lookup_sk;
-       delete [] lookup_wacc;
-
-       lookup_sx0 = new int[oh];
-       lookup_sx1 = new int[oh];
-       lookup_sk = new int[oh];
-       lookup_wacc = new float[oh];
-
-       kd = (double)coeff * (1 << INDEX_FRACTION) + .5;
-
-       /* precompute kernel values and weight sums */
-       for(int i = 0; i < oh; i++) {
-               /* map destination back to source */
-               double sx = (i - oyf + .5) * iscale + in1 - .5;
-
-               /*
-                * clip iteration to source area but not source plane. Points
-                * outside the source plane count as transparent. Points outside
-                * the source area don't count at all.  The actual convolution
-                * later will be clipped to both, but we need to compute
-                * weights.
-                */
-               int sx0 = MAX((int)floor(sx - bound) + 1, i1i);
-               int sx1 = MIN((int)ceil(sx + bound), i2i);
-               int ki = (double)(sx0 - sx) * coeff * (1 << INDEX_FRACTION)
-                               + (1 << (INDEX_FRACTION - 1)) + .5;
-               float wacc=0.;
-
-               lookup_sx0[i] = -1;
-               lookup_sx1[i] = -1;
-
-               for(int j= sx0; j < sx1; j++) {
-                       int kv = (ki >> INDEX_FRACTION);
-                       if(kv > kn) break;
-                       if(kv >= -kn) {
-                               /*
-                                * the contribution of the first and last input pixel (if
-                                * fractional) are linearly weighted by the fraction
-                                */
-                               if(j == i1i)
-                                       wacc += k[abs(kv)] * i1f;
-                               else if(j + 1 == i2i)
-                                       wacc += k[abs(kv)] * i2f;
-                               else
-                                       wacc += k[abs(kv)];
-
-                               /* this is where we clip the kernel convolution to the source plane */
-                               if(j >= 0 && j < iw) {
-                                       if(lookup_sx0[i] == -1) {
-                                               lookup_sx0[i] = j;
-                                               lookup_sk[i] = ki;
-                                       }
-                                       lookup_sx1[i] = j + 1;
-                               }
-                       }
-                       ki += kd;
-               }
-               lookup_wacc[i] = wacc > 0. ? 1. / wacc : 0.;
-       }
-
-       int cols = col_out2 - col_out1;
-       int pkgs = get_total_packages();
-       int col1 = col_out1, col2 = col1;
-       for(int i = 0; i < pkgs; col1=col2 ) {
-               SamplePackage *package = (SamplePackage*)get_package(i);
-               col2 = ++i * cols / pkgs + col_out1;
-               package->out_col1 = col1;
-               package->out_col2 = col2;
-       }
-}
-
-LoadClient* SampleEngine::new_client()
-{
-       return new SampleUnit(this);
-}
-
-LoadPackage* SampleEngine::new_package()
-{
-       return new SamplePackage;
-}
diff --git a/cinelerra-5.1/cinelerra/overlayframe.C.clamp b/cinelerra-5.1/cinelerra/overlayframe.C.clamp
deleted file mode 100644 (file)
index c3ce4f1..0000000
+++ /dev/null
@@ -1,1796 +0,0 @@
-#include <math.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-
-#include "clip.h"
-#include "edl.inc"
-#include "mutex.h"
-#include "overlayframe.h"
-#include "vframe.h"
-
-OverlayFrame::OverlayFrame(int cpus)
-{
-       temp_frame = 0;
-       blend_engine = 0;
-       scale_engine = 0;
-       scaletranslate_engine = 0;
-       translate_engine = 0;
-       this->cpus = cpus;
-}
-
-OverlayFrame::~OverlayFrame()
-{
-//printf("OverlayFrame::~OverlayFrame 1\n");
-       if(temp_frame) delete temp_frame;
-       if(scale_engine) delete scale_engine;
-       if(translate_engine) delete translate_engine;
-       if(blend_engine) delete blend_engine;
-       if(scaletranslate_engine) delete scaletranslate_engine;
-//printf("OverlayFrame::~OverlayFrame 2\n");
-}
-
-
-
-
-
-
-
-
-// Verification: 
-
-// (255 * 255 + 0 * 0) / 255 = 255
-// (255 * 127 + 255 * (255 - 127)) / 255 = 255
-
-// (65535 * 65535 + 0 * 0) / 65535 = 65535
-// (65535 * 32767 + 65535 * (65535 - 32767)) / 65535 = 65535
-
-
-// Branch prediction 4 U
-
-#define BLEND_3(max, type) \
-{ \
-       int64_t r, g, b; \
- \
-/* if(mode != TRANSFER_NORMAL) printf("BLEND mode = %d\n", mode); */ \
-       switch(mode) \
-       { \
-               case TRANSFER_DIVIDE: \
-                       r = output[0] ? (((int64_t)input1 * max) / output[0]) : max; \
-                       g = output[1] ? (((int64_t)input2 * max) / output[1]) : max; \
-                       b = output[2] ? (((int64_t)input3 * max) / output[2]) : max; \
-                       r = (r * opacity + output[0] * transparency) / max; \
-                       g = (g * opacity + output[1] * transparency) / max; \
-                       b = (b * opacity + output[2] * transparency) / max; \
-                       break; \
-               case TRANSFER_MULTIPLY: \
-                       r = ((int64_t)input1 * output[0]) / max; \
-                       g = ((int64_t)input2 * output[1]) / max; \
-                       b = ((int64_t)input3 * output[2]) / max; \
-                       r = (r * opacity + output[0] * transparency) / max; \
-                       g = (g * opacity + output[1] * transparency) / max; \
-                       b = (b * opacity + output[2] * transparency) / max; \
-                       break; \
-               case TRANSFER_SUBTRACT: \
-                       r = (((int64_t)input1 - output[0]) * opacity + output[0] * transparency) / max; \
-                       g = (((int64_t)input2 - output[1]) * opacity + output[1] * transparency) / max; \
-                       b = (((int64_t)input3 - output[2]) * opacity + output[2] * transparency) / max; \
-                       break; \
-               case TRANSFER_ADDITION: \
-                       r = (((int64_t)input1 + output[0]) * opacity + output[0] * transparency) / max; \
-                       g = (((int64_t)input2 + output[1]) * opacity + output[1] * transparency) / max; \
-                       b = (((int64_t)input3 + output[2]) * opacity + output[2] * transparency) / max; \
-                       break; \
-               case TRANSFER_REPLACE: \
-                       r = input1; \
-                       g = input2; \
-                       b = input3; \
-                       break; \
-               case TRANSFER_NORMAL: \
-                       r = ((int64_t)input1 * opacity + output[0] * transparency) / max; \
-                       g = ((int64_t)input2 * opacity + output[1] * transparency) / max; \
-                       b = ((int64_t)input3 * opacity + output[2] * transparency) / max; \
-                       break; \
-       } \
- \
-       output[0] = (type)CLIP(r, 0, max); \
-       output[1] = (type)CLIP(g, 0, max); \
-       output[2] = (type)CLIP(b, 0, max); \
-}
-
-
-
-
-
-// Blending equations are drastically different for 3 and 4 components
-#define BLEND_4(max, type) \
-{ \
-       int64_t r, g, b, a; \
-       int64_t pixel_opacity, pixel_transparency; \
- \
-       pixel_opacity = opacity * input4 / max; \
-       pixel_transparency = (max - pixel_opacity) * output[3] / max; \
- \
-       switch(mode) \
-       { \
-               case TRANSFER_DIVIDE: \
-                       r = output[0] ? (((int64_t)input1 * max) / output[0]) : max; \
-                       g = output[1] ? (((int64_t)input2 * max) / output[1]) : max; \
-                       b = output[2] ? (((int64_t)input3 * max) / output[2]) : max; \
-                       r = (r * pixel_opacity + output[0] * pixel_transparency) / max; \
-                       g = (g * pixel_opacity + output[1] * pixel_transparency) / max; \
-                       b = (b * pixel_opacity + output[2] * pixel_transparency) / max; \
-                       a = input4 > output[3] ? input4 : output[3]; \
-                       break; \
-               case TRANSFER_MULTIPLY: \
-                       r = ((int64_t)input1 * output[0]) / max; \
-                       g = ((int64_t)input2 * output[1]) / max; \
-                       b = ((int64_t)input3 * output[2]) / max; \
-                       r = (r * pixel_opacity + output[0] * pixel_transparency) / max; \
-                       g = (g * pixel_opacity + output[1] * pixel_transparency) / max; \
-                       b = (b * pixel_opacity + output[2] * pixel_transparency) / max; \
-                       a = input4 > output[3] ? input4 : output[3]; \
-                       break; \
-               case TRANSFER_SUBTRACT: \
-                       r = (((int64_t)input1 - output[0]) * pixel_opacity + output[0] * pixel_transparency) / max; \
-                       g = (((int64_t)input2 - output[1]) * pixel_opacity + output[1] * pixel_transparency) / max; \
-                       b = (((int64_t)input3 - output[2]) * pixel_opacity + output[2] * pixel_transparency) / max; \
-                       a = input4 > output[3] ? input4 : output[3]; \
-                       break; \
-               case TRANSFER_ADDITION: \
-                       r = (((int64_t)input1 + output[0]) * pixel_opacity + output[0] * pixel_transparency) / max; \
-                       g = (((int64_t)input2 + output[1]) * pixel_opacity + output[1] * pixel_transparency) / max; \
-                       b = (((int64_t)input3 + output[2]) * pixel_opacity + output[2] * pixel_transparency) / max; \
-                       a = input4 > output[3] ? input4 : output[3]; \
-                       break; \
-               case TRANSFER_REPLACE: \
-                       r = input1; \
-                       g = input2; \
-                       b = input3; \
-                       a = input4; \
-                       break; \
-               case TRANSFER_NORMAL: \
-                       r = ((int64_t)input1 * pixel_opacity + output[0] * pixel_transparency) / max; \
-                       g = ((int64_t)input2 * pixel_opacity + output[1] * pixel_transparency) / max; \
-                       b = ((int64_t)input3 * pixel_opacity + output[2] * pixel_transparency) / max; \
-                       a = input4 > output[3] ? input4 : output[3]; \
-                       break; \
-       } \
- \
-       output[0] = (type)CLIP(r, 0, max); \
-       output[1] = (type)CLIP(g, 0, max); \
-       output[2] = (type)CLIP(b, 0, max); \
-       output[3] = (type)a; \
-}
-
-
-
-
-
-
-
-
-// Bicubic algorithm using multiprocessors
-// input -> scale nearest integer boundaries -> temp -> translation -> blend -> output
-
-// Nearest neighbor algorithm using multiprocessors for blending
-// input -> scale + translate -> blend -> output
-
-
-int OverlayFrame::overlay(VFrame *output, 
-       VFrame *input, 
-       float in_x1, 
-       float in_y1, 
-       float in_x2, 
-       float in_y2, 
-       float out_x1, 
-       float out_y1, 
-       float out_x2, 
-       float out_y2, 
-       float alpha,       // 0 - 1
-       int mode,
-       int interpolation_type)
-{
-       float w_scale = (out_x2 - out_x1) / (in_x2 - in_x1);
-       float h_scale = (out_y2 - out_y1) / (in_y2 - in_y1);
-
-//printf("OverlayFrame::overlay 1 %d %f\n", mode, alpha);
-// Limit values
-       if(in_x1 < 0)
-       {
-               out_x1 += -in_x1 * w_scale;
-               in_x1 = 0;
-       }
-       else
-       if(in_x1 >= input->get_w())
-       {
-               out_x1 -= (in_x1 - input->get_w()) * w_scale;
-               in_x1 = input->get_w();
-       }
-
-       if(in_y1 < 0)
-       {
-               out_y1 += -in_y1 * h_scale;
-               in_y1 = 0;
-       }
-       else
-       if(in_y1 >= input->get_h())
-       {
-               out_y1 -= (in_y1 - input->get_h()) * h_scale;
-               in_y1 = input->get_h();
-       }
-
-       if(in_x2 < 0)
-       {
-               out_x2 += -in_x2 * w_scale;
-               in_x2 = 0;
-       }
-       else
-       if(in_x2 >= input->get_w())
-       {
-               out_x2 -= (in_x2 - input->get_w()) * w_scale;
-               in_x2 = input->get_w();
-       }
-
-       if(in_y2 < 0)
-       {
-               out_y2 += -in_y2 * h_scale;
-               in_y2 = 0;
-       }
-       else
-       if(in_y2 >= input->get_h())
-       {
-               out_y2 -= (in_y2 - input->get_h()) * h_scale;
-               in_y2 = input->get_h();
-       }
-
-       if(out_x1 < 0)
-       {
-               in_x1 += -out_x1 / w_scale;
-               out_x1 = 0;
-       }
-       else
-       if(out_x1 >= output->get_w())
-       {
-               in_x1 -= (out_x1 - output->get_w()) / w_scale;
-               out_x1 = output->get_w();
-       }
-
-       if(out_y1 < 0)
-       {
-               in_y1 += -out_y1 / h_scale;
-               out_y1 = 0;
-       }
-       else
-       if(out_y1 >= output->get_h())
-       {
-               in_y1 -= (out_y1 - output->get_h()) / h_scale;
-               out_y1 = output->get_h();
-       }
-
-       if(out_x2 < 0)
-       {
-               in_x2 += -out_x2 / w_scale;
-               out_x2 = 0;
-       }
-       else
-       if(out_x2 >= output->get_w())
-       {
-               in_x2 -= (out_x2 - output->get_w()) / w_scale;
-               out_x2 = output->get_w();
-       }
-
-       if(out_y2 < 0)
-       {
-               in_y2 += -out_y2 / h_scale;
-               out_y2 = 0;
-       }
-       else
-       if(out_y2 >= output->get_h())
-       {
-               in_y2 -= (out_y2 - output->get_h()) / h_scale;
-               out_y2 = output->get_h();
-       }
-
-
-
-
-
-       float in_w = in_x2 - in_x1;
-       float in_h = in_y2 - in_y1;
-       float out_w = out_x2 - out_x1;
-       float out_h = out_y2 - out_y1;
-// Input for translation operation
-       VFrame *translation_input = input;
-
-
-
-// printf("OverlayFrame::overlay %f %f %f %f -> %f %f %f %f\n", in_x1,
-//                     in_y1,
-//                     in_x2,
-//                     in_y2,
-//                     out_x1,
-//                     out_y1,
-//                     out_x2,
-//                     out_y2);
-
-
-
-
-
-// ****************************************************************************
-// Transfer to temp buffer by scaling nearest integer boundaries
-// ****************************************************************************
-       if(interpolation_type != NEAREST_NEIGHBOR &&
-               (!EQUIV(w_scale, 1) || !EQUIV(h_scale, 1)))
-       {
-// Create integer boundaries for interpolation
-               int in_x1_int = (int)in_x1;
-               int in_y1_int = (int)in_y1;
-               int in_x2_int = MIN((int)ceil(in_x2), input->get_w());
-               int in_y2_int = MIN((int)ceil(in_y2), input->get_h());
-
-// Dimensions of temp frame.  Integer boundaries scaled.
-               int temp_w = (int)ceil(w_scale * (in_x2_int - in_x1_int));
-               int temp_h = (int)ceil(h_scale * (in_y2_int - in_y1_int));
-               VFrame *scale_output;
-
-
-
-#define NO_TRANSLATION1 \
-       (EQUIV(in_x1, 0) && \
-       EQUIV(in_y1, 0) && \
-       EQUIV(out_x1, 0) && \
-       EQUIV(out_y1, 0) && \
-       EQUIV(in_x2, in_x2_int) && \
-       EQUIV(in_y2, in_y2_int) && \
-       EQUIV(out_x2, temp_w) && \
-       EQUIV(out_y2, temp_h))
-
-
-#define NO_BLEND \
-       (EQUIV(alpha, 1) && \
-       (mode == TRANSFER_REPLACE || \
-       (mode == TRANSFER_NORMAL && cmodel_components(input->get_color_model()) == 3)))
-
-
-
-
-
-// Prepare destination for operation
-
-// No translation and no blending.  The blending operation is built into the
-// translation unit but not the scaling unit.
-// input -> output
-               if(NO_TRANSLATION1 &&
-                       NO_BLEND)
-               {
-// printf("OverlayFrame::overlay input -> output\n");
-
-                       scale_output = output;
-                       translation_input = 0;
-               }
-               else
-// If translation or blending
-// input -> nearest integer boundary temp
-               {
-                       if(temp_frame && 
-                               (temp_frame->get_w() != temp_w ||
-                                       temp_frame->get_h() != temp_h))
-                       {
-                               delete temp_frame;
-                               temp_frame = 0;
-                       }
-
-                       if(!temp_frame)
-                       {
-                               temp_frame = new VFrame(0,
-                                       temp_w,
-                                       temp_h,
-                                       input->get_color_model(),
-                                       -1);
-                       }
-//printf("OverlayFrame::overlay input -> temp\n");
-
-
-                       temp_frame->clear_frame();
-
-// printf("OverlayFrame::overlay 4 temp_w=%d temp_h=%d\n",
-//     temp_w, temp_h);
-                       scale_output = temp_frame;
-                       translation_input = scale_output;
-
-// Adjust input coordinates to reflect new scaled coordinates.
-                       in_x1 = (in_x1 - in_x1_int) * w_scale;
-                       in_y1 = (in_y1 - in_y1_int) * h_scale;
-                       in_x2 = (in_x2 - in_x1_int) * w_scale;
-                       in_y2 = (in_y2 - in_y1_int) * h_scale;
-               }
-
-
-
-//printf("Overlay 1\n");
-
-// Scale input -> scale_output
-               if(!scale_engine) scale_engine = new ScaleEngine(this, cpus);
-               scale_engine->scale_output = scale_output;
-               scale_engine->scale_input = input;
-               scale_engine->w_scale = w_scale;
-               scale_engine->h_scale = h_scale;
-               scale_engine->in_x1_int = in_x1_int;
-               scale_engine->in_y1_int = in_y1_int;
-               scale_engine->out_w_int = temp_w;
-               scale_engine->out_h_int = temp_h;
-               scale_engine->interpolation_type = interpolation_type;
-//printf("Overlay 2\n");
-
-//printf("OverlayFrame::overlay ScaleEngine 1 %d\n", out_h_int);
-               scale_engine->process_packages();
-//printf("OverlayFrame::overlay ScaleEngine 2\n");
-
-
-
-       }
-
-// printf("OverlayFrame::overlay 1  %.2f %.2f %.2f %.2f -> %.2f %.2f %.2f %.2f\n", 
-//     in_x1, 
-//     in_y1, 
-//     in_x2, 
-//     in_y2, 
-//     out_x1, 
-//     out_y1, 
-//     out_x2, 
-//     out_y2);
-
-
-
-
-
-#define NO_TRANSLATION2 \
-       (EQUIV(in_x1, 0) && \
-       EQUIV(in_y1, 0) && \
-       EQUIV(in_x2, translation_input->get_w()) && \
-       EQUIV(in_y2, translation_input->get_h()) && \
-       EQUIV(out_x1, 0) && \
-       EQUIV(out_y1, 0) && \
-       EQUIV(out_x2, output->get_w()) && \
-       EQUIV(out_y2, output->get_h())) \
-
-#define NO_SCALE \
-       (EQUIV(out_x2 - out_x1, in_x2 - in_x1) && \
-       EQUIV(out_y2 - out_y1, in_y2 - in_y1))
-
-       
-
-
-//printf("OverlayFrame::overlay 4 %d\n", mode);
-
-
-
-
-       if(translation_input)
-       {
-// Direct copy
-               if( NO_TRANSLATION2 &&
-                       NO_SCALE &&
-                       NO_BLEND)
-               {
-//printf("OverlayFrame::overlay direct copy\n");
-                       output->copy_from(translation_input);
-               }
-               else
-// Blend only
-               if( NO_TRANSLATION2 &&
-                       NO_SCALE)
-               {
-                       if(!blend_engine) blend_engine = new BlendEngine(this, cpus);
-
-
-                       blend_engine->output = output;
-                       blend_engine->input = translation_input;
-                       blend_engine->alpha = alpha;
-                       blend_engine->mode = mode;
-
-                       blend_engine->process_packages();
-               }
-               else
-// Scale and translate using nearest neighbor
-// Translation is exactly on integer boundaries
-               if(interpolation_type == NEAREST_NEIGHBOR ||
-                       EQUIV(in_x1, (int)in_x1) &&
-                       EQUIV(in_y1, (int)in_y1) &&
-                       EQUIV(in_x2, (int)in_x2) &&
-                       EQUIV(in_y2, (int)in_y2) &&
-
-                       EQUIV(out_x1, (int)out_x1) &&
-                       EQUIV(out_y1, (int)out_y1) &&
-                       EQUIV(out_x2, (int)out_x2) &&
-                       EQUIV(out_y2, (int)out_y2))
-               {
-//printf("OverlayFrame::overlay NEAREST_NEIGHBOR 1\n");
-                       if(!scaletranslate_engine) scaletranslate_engine = new ScaleTranslateEngine(this, cpus);
-
-
-                       scaletranslate_engine->output = output;
-                       scaletranslate_engine->input = translation_input;
-                       scaletranslate_engine->in_x1 = (int)in_x1;
-                       scaletranslate_engine->in_y1 = (int)in_y1;
-                       scaletranslate_engine->in_x2 = (int)in_x2;
-                       scaletranslate_engine->in_y2 = (int)in_y2;
-                       scaletranslate_engine->out_x1 = (int)out_x1;
-                       scaletranslate_engine->out_y1 = (int)out_y1;
-                       scaletranslate_engine->out_x2 = (int)out_x2;
-                       scaletranslate_engine->out_y2 = (int)out_y2;
-                       scaletranslate_engine->alpha = alpha;
-                       scaletranslate_engine->mode = mode;
-
-                       scaletranslate_engine->process_packages();
-               }
-               else
-// Fractional translation
-               {
-// Use fractional translation
-// printf("OverlayFrame::overlay temp -> output  %.2f %.2f %.2f %.2f -> %.2f %.2f %.2f %.2f\n", 
-//     in_x1, 
-//     in_y1, 
-//     in_x2, 
-//     in_y2, 
-//     out_x1, 
-//     out_y1, 
-//     out_x2, 
-//     out_y2);
-
-//printf("Overlay 3\n");
-                       if(!translate_engine) translate_engine = new TranslateEngine(this, cpus);
-                       translate_engine->translate_output = output;
-                       translate_engine->translate_input = translation_input;
-                       translate_engine->translate_in_x1 = in_x1;
-                       translate_engine->translate_in_y1 = in_y1;
-                       translate_engine->translate_in_x2 = in_x2;
-                       translate_engine->translate_in_y2 = in_y2;
-                       translate_engine->translate_out_x1 = out_x1;
-                       translate_engine->translate_out_y1 = out_y1;
-                       translate_engine->translate_out_x2 = out_x2;
-                       translate_engine->translate_out_y2 = out_y2;
-                       translate_engine->translate_alpha = alpha;
-                       translate_engine->translate_mode = mode;
-//printf("Overlay 4\n");
-
-//printf("OverlayFrame::overlay 5 %d\n", mode);
-                       translate_engine->process_packages();
-
-               }
-       }
-//printf("OverlayFrame::overlay 2\n");
-
-       return 0;
-}
-
-
-
-
-
-
-
-ScalePackage::ScalePackage()
-{
-}
-
-
-
-
-ScaleUnit::ScaleUnit(ScaleEngine *server, OverlayFrame *overlay)
- : LoadClient(server)
-{
-       this->overlay = overlay;
-       this->engine = server;
-}
-
-ScaleUnit::~ScaleUnit()
-{
-}
-
-
-
-#define BILINEAR(max, type, components) \
-{ \
-       float k_y = 1.0 / scale_h; \
-       float k_x = 1.0 / scale_w; \
-       type **in_rows = (type**)input->get_rows(); \
-       type **out_rows = (type**)output->get_rows(); \
-       int out_h = pkg->out_row2 - pkg->out_row1; \
-       int in_h_int = input->get_h(); \
-       int in_w_int = input->get_w(); \
-       int *table_int_x1, *table_int_y1; \
-       int *table_int_x2, *table_int_y2; \
-       float *table_frac_x, *table_antifrac_x, *table_frac_y, *table_antifrac_y; \
- \
-       tabulate_blinear(table_int_x1,  \
-               table_int_x2,  \
-               table_frac_x,  \
-               table_antifrac_x,  \
-               k_x,  \
-               0,  \
-               out_w_int, \
-               in_x1_int,  \
-               in_w_int); \
-       tabulate_blinear(table_int_y1,  \
-               table_int_y2,  \
-               table_frac_y,  \
-               table_antifrac_y,  \
-               k_y,  \
-               pkg->out_row1,  \
-               pkg->out_row2,  \
-               in_y1_int, \
-               in_h_int); \
- \
-       for(int i = 0; i < out_h; i++) \
-       { \
-               int i_y1 = table_int_y1[i]; \
-               int i_y2 = table_int_y2[i]; \
-               float a = table_frac_y[i]; \
-        float anti_a = table_antifrac_y[i]; \
-               type *in_row1 = in_rows[i_y1]; \
-               type *in_row2 = in_rows[i_y2]; \
-               type *out_row = out_rows[i + pkg->out_row1]; \
- \
-               for(int j = 0; j < out_w_int; j++) \
-               { \
-                       int i_x1 = table_int_x1[j]; \
-                       int i_x2 = table_int_x2[j]; \
-                       float b = table_frac_x[j]; \
-                       float anti_b = table_antifrac_x[j]; \
-                       float output1r, output1g, output1b, output1a; \
-                       float output2r, output2g, output2b, output2a; \
-                       float output3r, output3g, output3b, output3a; \
-                       float output4r, output4g, output4b, output4a; \
- \
-                       output1r = in_row1[i_x1 * components]; \
-                       output1g = in_row1[i_x1 * components + 1]; \
-                       output1b = in_row1[i_x1 * components + 2]; \
-                       if(components == 4) output1a = in_row1[i_x1 * components + 3]; \
- \
-                       output2r = in_row1[i_x2 * components]; \
-                       output2g = in_row1[i_x2 * components + 1]; \
-                       output2b = in_row1[i_x2 * components + 2]; \
-                       if(components == 4) output2a = in_row1[i_x2 * components + 3]; \
- \
-                       output3r = in_row2[i_x1 * components]; \
-                       output3g = in_row2[i_x1 * components + 1]; \
-                       output3b = in_row2[i_x1 * components + 2]; \
-                       if(components == 4) output3a = in_row2[i_x1 * components + 3]; \
-\
-                       output4r = in_row2[i_x2 * components]; \
-                       output4g = in_row2[i_x2 * components + 1]; \
-                       output4b = in_row2[i_x2 * components + 2]; \
-                       if(components == 4) output4a = in_row2[i_x2 * components + 3]; \
- \
-                       out_row[j * components] =  \
-                               (type)((anti_a) * (((anti_b) * output1r) +  \
-                               (b * output2r)) +  \
-                a * (((anti_b) * output3r) +  \
-                               (b * output4r))); \
-                       out_row[j * components + 1] =   \
-                               (type)((anti_a) * (((anti_b) * output1g) +  \
-                               (b * output2g)) +  \
-                a * (((anti_b) * output3g) +  \
-                               (b * output4g))); \
-                       out_row[j * components + 2] =   \
-                               (type)((anti_a) * (((anti_b) * output1b) +  \
-                               (b * output2b)) +  \
-                a * (((anti_b) * output3b) +  \
-                               (b * output4b))); \
-                       if(components == 4) \
-                               out_row[j * components + 3] =   \
-                                       (type)((anti_a) * (((anti_b) * output1a) +  \
-                                       (b * output2a)) +  \
-                       a * (((anti_b) * output3a) +  \
-                                       (b * output4a))); \
-               } \
-       } \
- \
- \
-       delete [] table_int_x1; \
-       delete [] table_int_x2; \
-       delete [] table_frac_x; \
-       delete [] table_antifrac_x; \
-       delete [] table_int_y1; \
-       delete [] table_int_y2; \
-       delete [] table_frac_y; \
-       delete [] table_antifrac_y; \
- \
-}
-
-
-#define BICUBIC(max, type, components) \
-{ \
-       float k_y = 1.0 / scale_h; \
-       float k_x = 1.0 / scale_w; \
-       type **in_rows = (type**)input->get_rows(); \
-       type **out_rows = (type**)output->get_rows(); \
-       float *bspline_x, *bspline_y; \
-       int *in_x_table, *in_y_table; \
-       int in_h_int = input->get_h(); \
-       int in_w_int = input->get_w(); \
- \
-       tabulate_bicubic(bspline_x,  \
-               in_x_table, \
-               k_x, \
-               in_x1_int, \
-               out_w_int, \
-               in_w_int, \
-               -1); \
- \
-       tabulate_bicubic(bspline_y,  \
-               in_y_table, \
-               k_y, \
-               in_y1_int, \
-               out_h_int, \
-               in_h_int, \
-               1); \
- \
-       for(int i = pkg->out_row1; i < pkg->out_row2; i++) \
-       { \
-               for(int j = 0; j < out_w_int; j++) \
-               { \
-                       int i_x = (int)(k_x * j); \
-                       float output1, output2, output3, output4; \
-                       output1 = 0; \
-                       output2 = 0; \
-                       output3 = 0; \
-                       if(components == 4) \
-                               output4 = 0; \
-                       int table_y = i * 4; \
- \
-/* Kernel */ \
-                       for(int m = -1; m < 3; m++) \
-                       { \
-                               float r1 = bspline_y[table_y]; \
-                               int y = in_y_table[table_y]; \
-                               int table_x = j * 4; \
- \
-                               for(int n = -1; n < 3; n++) \
-                               { \
-                                       float r2 = bspline_x[table_x]; \
-                                       int x = in_x_table[table_x]; \
-                                       float r_square = r1 * r2; \
- \
-                                       output1 += r_square * in_rows[y][x * components]; \
-                                       output2 += r_square * in_rows[y][x * components + 1]; \
-                                       output3 += r_square * in_rows[y][x * components + 2]; \
-                                       if(components == 4) \
-                                               output4 += r_square * in_rows[y][x * components + 3]; \
- \
-                                       table_x++; \
-                               } \
-                               table_y++; \
-                       } \
- \
- \
-                       out_rows[i][j * components] = (type)output1; \
-                       out_rows[i][j * components + 1] = (type)output2; \
-                       out_rows[i][j * components + 2] = (type)output3; \
-                       if(components == 4) \
-                               out_rows[i][j * components + 3] = (type)output4; \
- \
-               } \
-       } \
- \
-       delete [] bspline_x; \
-       delete [] bspline_y; \
-       delete [] in_x_table; \
-       delete [] in_y_table; \
-}
-
-
-
-
-// Pow function is not thread safe in Compaqt C
-#define CUBE(x) ((x) * (x) * (x))
-
-float ScaleUnit::cubic_bspline(float x)
-{
-       float a, b, c, d;
-
-       if((x + 2.0F) <= 0.0F) 
-       {
-       a = 0.0F;
-       }
-       else 
-       {
-       a = CUBE(x + 2.0F);
-       }
-
-
-       if((x + 1.0F) <= 0.0F) 
-       {
-       b = 0.0F;
-       }
-       else 
-       {
-       b = CUBE(x + 1.0F);
-       }    
-
-       if(x <= 0) 
-       {
-       c = 0.0F;
-       }
-       else 
-       {
-       c = CUBE(x);
-       }  
-
-       if((x - 1.0F) <= 0.0F) 
-       {
-       d = 0.0F;
-       }
-       else 
-       {
-       d = CUBE(x - 1.0F);
-       }
-
-
-       return (a - (4.0F * b) + (6.0F * c) - (4.0F * d)) / 6.0;
-}
-
-
-void ScaleUnit::tabulate_bicubic(float* &coef_table, 
-       int* &coord_table,
-       float scale,
-       int start, 
-       int pixels,
-       int total_pixels,
-       float coefficient)
-{
-       coef_table = new float[pixels * 4];
-       coord_table = new int[pixels * 4];
-       for(int i = 0, j = 0; i < pixels; i++)
-       {
-               float f_x = (float)i * scale;
-               float a = f_x - floor(f_x);
-               
-               for(float m = -1; m < 3; m++)
-               {
-                       coef_table[j] = cubic_bspline(coefficient * (m - a));
-                       coord_table[j] = start + (int)f_x + m;
-                       CLAMP(coord_table[j], 0, total_pixels - 1);
-                       j++;
-               }
-               
-       }
-}
-
-void ScaleUnit::tabulate_blinear(int* &table_int1,
-               int* &table_int2,
-               float* &table_frac,
-               float* &table_antifrac,
-               float scale,
-               int pixel1,
-               int pixel2,
-               int start,
-               int total_pixels)
-{
-       table_int1 = new int[pixel2 - pixel1];
-       table_int2 = new int[pixel2 - pixel1];
-       table_frac = new float[pixel2 - pixel1];
-       table_antifrac = new float[pixel2 - pixel1];
-
-       for(int i = pixel1, j = 0; i < pixel2; i++, j++)
-       {
-               float f_x = (float)i * scale;
-               int i_x = (int)floor(f_x);
-               float a = (f_x - floor(f_x));
-
-               table_int1[j] = i_x + start;
-               table_int2[j] = i_x + start + 1;
-               CLAMP(table_int1[j], 0, total_pixels - 1);
-               CLAMP(table_int2[j], 0, total_pixels - 1);
-               table_frac[j] = a;
-               table_antifrac[j] = 1.0F - a;
-//printf("ScaleUnit::tabulate_blinear %d %d %d\n", j, table_int1[j], table_int2[j]);
-       }
-}
-
-void ScaleUnit::process_package(LoadPackage *package)
-{
-       ScalePackage *pkg = (ScalePackage*)package;
-
-//printf("ScaleUnit::process_package 1\n");
-// Arguments for macros
-       VFrame *output = engine->scale_output;
-       VFrame *input = engine->scale_input;
-       float scale_w = engine->w_scale;
-       float scale_h = engine->h_scale;
-       int in_x1_int = engine->in_x1_int;
-       int in_y1_int = engine->in_y1_int;
-       int out_h_int = engine->out_h_int;
-       int out_w_int = engine->out_w_int;
-       int do_yuv = 
-               (input->get_color_model() == BC_YUV888 ||
-               input->get_color_model() == BC_YUVA8888 ||
-               input->get_color_model() == BC_YUV161616 ||
-               input->get_color_model() == BC_YUVA16161616);
-
-//printf("ScaleUnit::process_package 2\n");
-       if(engine->interpolation_type == CUBIC_CUBIC || 
-               (engine->interpolation_type == CUBIC_LINEAR 
-                       && engine->w_scale > 1 && 
-                       engine->h_scale > 1))
-       {
-       
-               switch(engine->scale_input->get_color_model())
-               {
-                       case BC_RGB888:
-                       case BC_YUV888:
-                               BICUBIC(0xff, unsigned char, 3);
-                               break;
-
-                       case BC_RGBA8888:
-                       case BC_YUVA8888:
-                               BICUBIC(0xff, unsigned char, 4);
-                               break;
-
-                       case BC_RGB161616:
-                       case BC_YUV161616:
-                               BICUBIC(0xffff, uint16_t, 3);
-                               break;
-
-                       case BC_RGBA16161616:
-                       case BC_YUVA16161616:
-                               BICUBIC(0xffff, uint16_t, 4);
-                               break;
-               }
-       }
-       else
-// Perform bilinear scaling input -> scale_output
-       {
-               switch(engine->scale_input->get_color_model())
-               {
-                       case BC_RGB888:
-                       case BC_YUV888:
-                               BILINEAR(0xff, unsigned char, 3);
-                               break;
-
-                       case BC_RGBA8888:
-                       case BC_YUVA8888:
-                               BILINEAR(0xff, unsigned char, 4);
-                               break;
-
-                       case BC_RGB161616:
-                       case BC_YUV161616:
-                               BILINEAR(0xffff, uint16_t, 3);
-                               break;
-
-                       case BC_RGBA16161616:
-                       case BC_YUVA16161616:
-                               BILINEAR(0xffff, uint16_t, 4);
-                               break;
-               }
-       }
-//printf("ScaleUnit::process_package 3\n");
-
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-ScaleEngine::ScaleEngine(OverlayFrame *overlay, int cpus)
- : LoadServer(cpus, cpus)
-{
-       this->overlay = overlay;
-}
-
-ScaleEngine::~ScaleEngine()
-{
-}
-
-void ScaleEngine::init_packages()
-{
-       for(int i = 0; i < total_packages; i++)
-       {
-               ScalePackage *package = (ScalePackage*)packages[i];
-               package->out_row1 = out_h_int / total_packages * i;
-               package->out_row2 = package->out_row1 + out_h_int / total_packages;
-
-               if(i >= total_packages - 1)
-                       package->out_row2 = out_h_int;
-       }
-}
-
-LoadClient* ScaleEngine::new_client()
-{
-       return new ScaleUnit(this, overlay);
-}
-
-LoadPackage* ScaleEngine::new_package()
-{
-       return new ScalePackage;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-TranslatePackage::TranslatePackage()
-{
-}
-
-
-
-TranslateUnit::TranslateUnit(TranslateEngine *server, OverlayFrame *overlay)
- : LoadClient(server)
-{
-       this->overlay = overlay;
-       this->engine = server;
-}
-
-TranslateUnit::~TranslateUnit()
-{
-}
-
-
-
-void TranslateUnit::translation_array(transfer_table* &table, 
-       float out_x1, 
-       float out_x2,
-       float in_x1,
-       float in_x2,
-       int in_total, 
-       int out_total, 
-       int &out_x1_int,
-       int &out_x2_int)
-{
-       int out_w_int;
-       float offset = out_x1 - in_x1;
-
-       out_x1_int = (int)out_x1;
-       out_x2_int = MIN((int)ceil(out_x2), out_total);
-       out_w_int = out_x2_int - out_x1_int;
-
-       table = new transfer_table[out_w_int];
-       bzero(table, sizeof(transfer_table) * out_w_int);
-
-
-//printf("OverlayFrame::translation_array 1 %f %f -> %f %f\n", in_x1, in_x2, out_x1, out_x2);
-
-       float in_x = in_x1;
-       for(int out_x = out_x1_int; out_x < out_x2_int; out_x++)
-       {
-               transfer_table *entry = &table[out_x - out_x1_int];
-
-               entry->in_x1 = (int)in_x;
-               entry->in_x2 = (int)in_x + 1;
-
-// Get fraction of output pixel to fill
-               entry->output_fraction = 1;
-
-               if(out_x1 > out_x)
-               {
-                       entry->output_fraction -= out_x1 - out_x;
-               }
-
-               if(out_x2 < out_x + 1)
-               {
-                       entry->output_fraction = (out_x2 - out_x);
-               }
-
-// Advance in_x until out_x_fraction is filled
-               float out_x_fraction = entry->output_fraction;
-               float in_x_fraction = floor(in_x + 1) - in_x;
-
-               if(out_x_fraction <= in_x_fraction)
-               {
-                       entry->in_fraction1 = out_x_fraction;
-                       entry->in_fraction2 = 0.0;
-                       in_x += out_x_fraction;
-               }
-               else
-               {
-                       entry->in_fraction1 = in_x_fraction;
-                       in_x += out_x_fraction;
-                       entry->in_fraction2 = in_x - floor(in_x);
-               }
-
-// Clip in_x and zero out fraction.  This doesn't work for YUV.
-               if(entry->in_x2 >= in_total)
-               {
-                       entry->in_x2 = in_total - 1;
-                       entry->in_fraction2 = 0.0;
-               }
-               
-               if(entry->in_x1 >= in_total)
-               {
-                       entry->in_x1 = in_total - 1;
-                       entry->in_fraction1 = 0.0;
-               }
-// printf("OverlayFrame::translation_array 2 %d %d %d %f %f %f\n", 
-//     out_x, 
-//     entry->in_x1, 
-//     entry->in_x2, 
-//     entry->in_fraction1, 
-//     entry->in_fraction2, 
-//     entry->output_fraction);
-       }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#define TRANSLATE(max, type, components, do_yuv) \
-{ \
- \
-       type **in_rows = (type**)input->get_rows(); \
-       type **out_rows = (type**)output->get_rows(); \
- \
-/* printf("OverlayFrame::translate 1  %.2f %.2f %.2f %.2f -> %.2f %.2f %.2f %.2f\n",  */ \
-/*     (in_x1),  in_y1,  in_x2,  in_y2,  out_x1,  out_y1, out_x2,  out_y2); */ \
- \
-       unsigned int master_opacity = (int)(alpha * max + 0.5); \
-       unsigned int master_transparency = max - master_opacity; \
-       float zero_r, zero_g, zero_b; \
-       zero_r = 0; \
-       zero_b = ((max + 1) >> 1) * (do_yuv); \
-       zero_g = ((max + 1) >> 1) * (do_yuv); \
- \
-/* printf("TRANSLATE %d\n", mode); */ \
- \
-       for(int i = row1; i < row2; i++) \
-       { \
-               int in_y1 = y_table[i - out_y1_int].in_x1; \
-               int in_y2 = y_table[i - out_y1_int].in_x2; \
-               float y_fraction1 = y_table[i - out_y1_int].in_fraction1; \
-               float y_fraction2 = y_table[i - out_y1_int].in_fraction2; \
-               float y_output_fraction = y_table[i - out_y1_int].output_fraction; \
-               type *in_row1 = in_rows[(in_y1)]; \
-               type *in_row2 = in_rows[(in_y2)]; \
-               type *out_row = out_rows[i]; \
- \
-               for(int j = out_x1_int; j < out_x2_int; j++) \
-               { \
-                       int in_x1 = x_table[j - out_x1_int].in_x1; \
-                       int in_x2 = x_table[j - out_x1_int].in_x2; \
-                       float x_fraction1 = x_table[j - out_x1_int].in_fraction1; \
-                       float x_fraction2 = x_table[j - out_x1_int].in_fraction2; \
-                       float x_output_fraction = x_table[j - out_x1_int].output_fraction; \
-                       type *output = &out_row[j * components]; \
-                       int input1, input2, input3, input4; \
-                       float fraction1 = x_fraction1 * y_fraction1; \
-                       float fraction2 = x_fraction2 * y_fraction1; \
-                       float fraction3 = x_fraction1 * y_fraction2; \
-                       float fraction4 = x_fraction2 * y_fraction2; \
- \
-                       input1 = (int)(in_row1[in_x1 * components] * fraction1 +  \
-                               in_row1[in_x2 * components] * fraction2 +  \
-                               in_row2[in_x1 * components] * fraction3 +  \
-                               in_row2[in_x2 * components] * fraction4 + 0.5); \
- \
-/* Add chroma to fractional pixels */ \
-                       if(do_yuv) \
-                       { \
-                               float extra_chroma = (1.0F - \
-                                       fraction1 - \
-                                       fraction2 - \
-                                       fraction3 - \
-                                       fraction4) * zero_b; \
-                               input2 = (int)(in_row1[in_x1 * components + 1] * fraction1 +  \
-                                       in_row1[in_x2 * components + 1] * fraction2 +  \
-                                       in_row2[in_x1 * components + 1] * fraction3 +  \
-                                       in_row2[in_x2 * components + 1] * fraction4 + \
-                                       extra_chroma + 0.5); \
-                               input3 = (int)(in_row1[in_x1 * components + 2] * fraction1 +  \
-                                       in_row1[in_x2 * components + 2] * fraction2 +  \
-                                       in_row2[in_x1 * components + 2] * fraction3 +  \
-                                       in_row2[in_x2 * components + 2] * fraction4 +  \
-                                       extra_chroma + 0.5); \
-                       } \
-                       else \
-                       { \
-                               input2 = (int)(in_row1[in_x1 * components + 1] * fraction1 +  \
-                                       in_row1[in_x2 * components + 1] * fraction2 +  \
-                                       in_row2[in_x1 * components + 1] * fraction3 +  \
-                                       in_row2[in_x2 * components + 1] * fraction4 + 0.5); \
-                               input3 = (int)(in_row1[in_x1 * components + 2] * fraction1 +  \
-                                       in_row1[in_x2 * components + 2] * fraction2 +  \
-                                       in_row2[in_x1 * components + 2] * fraction3 +  \
-                                       in_row2[in_x2 * components + 2] * fraction4 + 0.5); \
-                       } \
- \
-                       if(components == 4) \
-                               input4 = (int)(in_row1[in_x1 * components + 3] * fraction1 +  \
-                                       in_row1[in_x2 * components + 3] * fraction2 +  \
-                                       in_row2[in_x1 * components + 3] * fraction3 +  \
-                                       in_row2[in_x2 * components + 3] * fraction4 + 0.5); \
- \
-                       unsigned int opacity = (int)(master_opacity *  \
-                               y_output_fraction *  \
-                               x_output_fraction + 0.5); \
-                       unsigned int transparency = max - opacity; \
- \
-/* if(opacity != max) printf("TRANSLATE %x %d %d\n", opacity, j, i); */ \
- \
-                       if(components == 3) \
-                       { \
-                               BLEND_3(max, type); \
-                       } \
-                       else \
-                       { \
-                               BLEND_4(max, type); \
-                       } \
-               } \
-       } \
-}
-
-void TranslateUnit::process_package(LoadPackage *package)
-{
-       TranslatePackage *pkg = (TranslatePackage*)package;
-       int out_y1_int; 
-       int out_y2_int; 
-       int out_x1_int; 
-       int out_x2_int; 
-
-
-// Variables for TRANSLATE
-       VFrame *input = engine->translate_input;
-       VFrame *output = engine->translate_output;
-       float in_x1 = engine->translate_in_x1;
-       float in_y1 = engine->translate_in_y1;
-       float in_x2 = engine->translate_in_x2;
-       float in_y2 = engine->translate_in_y2;
-       float out_x1 = engine->translate_out_x1;
-       float out_y1 = engine->translate_out_y1;
-       float out_x2 = engine->translate_out_x2;
-       float out_y2 = engine->translate_out_y2;
-       float alpha = engine->translate_alpha;
-       int row1 = pkg->out_row1;
-       int row2 = pkg->out_row2;
-       int mode = engine->translate_mode;
-       int in_total_x = input->get_w();
-       int in_total_y = input->get_h();
-       int do_yuv = 
-               (engine->translate_input->get_color_model() == BC_YUV888 ||
-               engine->translate_input->get_color_model() == BC_YUVA8888 ||
-               engine->translate_input->get_color_model() == BC_YUV161616 ||
-               engine->translate_input->get_color_model() == BC_YUVA16161616);
-
-       transfer_table *x_table; 
-       transfer_table *y_table; 
-       translation_array(x_table,  
-               out_x1,  
-               out_x2, 
-               in_x1, 
-               in_x2, 
-               in_total_x,  
-               output->get_w(),  
-               out_x1_int, 
-               out_x2_int); 
-       translation_array(y_table,  
-               out_y1,  
-               out_y2, 
-               in_y1, 
-               in_y2, 
-               in_total_y,  
-               output->get_h(),  
-               out_y1_int, 
-               out_y2_int); 
-       switch(engine->translate_input->get_color_model())
-       {
-               case BC_RGB888:
-                       TRANSLATE(0xff, unsigned char, 3, 0);
-                       break;
-
-               case BC_RGBA8888:
-                       TRANSLATE(0xff, unsigned char, 4, 0);
-                       break;
-
-               case BC_RGB161616:
-                       TRANSLATE(0xffff, uint16_t, 3, 0);
-                       break;
-
-               case BC_RGBA16161616:
-                       TRANSLATE(0xffff, uint16_t, 4, 0);
-                       break;
-
-               case BC_YUV888:
-                       TRANSLATE(0xff, unsigned char, 3, 1);
-                       break;
-
-               case BC_YUVA8888:
-                       TRANSLATE(0xff, unsigned char, 4, 1);
-                       break;
-
-               case BC_YUV161616:
-                       TRANSLATE(0xffff, uint16_t, 3, 1);
-                       break;
-
-               case BC_YUVA16161616:
-                       TRANSLATE(0xffff, uint16_t, 4, 1);
-                       break;
-       }
-       delete [] x_table; 
-       delete [] y_table; 
-}
-
-
-
-
-
-
-
-
-
-
-TranslateEngine::TranslateEngine(OverlayFrame *overlay, int cpus)
- : LoadServer(cpus, cpus)
-{
-       this->overlay = overlay;
-}
-
-TranslateEngine::~TranslateEngine()
-{
-}
-
-void TranslateEngine::init_packages()
-{
-       int out_y1_int = (int)translate_out_y1;
-       int out_y2_int = MIN((int)ceil(translate_out_y2), translate_output->get_h());
-       int out_h = out_y2_int - out_y1_int;
-
-       for(int i = 0; i < total_packages; i++)
-       {
-               TranslatePackage *package = (TranslatePackage*)packages[i];
-               package->out_row1 = (int)(out_y1_int + out_h / 
-                       total_packages * 
-                       i);
-               package->out_row2 = (int)((float)package->out_row1 + 
-                       out_h / 
-                       total_packages);
-               if(i >= total_packages - 1)
-                       package->out_row2 = out_y2_int;
-       }
-}
-
-LoadClient* TranslateEngine::new_client()
-{
-       return new TranslateUnit(this, overlay);
-}
-
-LoadPackage* TranslateEngine::new_package()
-{
-       return new TranslatePackage;
-}
-
-
-
-
-
-
-
-
-#define SCALE_TRANSLATE(max, type, components) \
-{ \
-       int64_t opacity = (int)(alpha * max + 0.5); \
-       int64_t transparency = max - opacity; \
-       int out_w = out_x2 - out_x1; \
- \
-       for(int i = pkg->out_row1; i < pkg->out_row2; i++) \
-       { \
-               int in_y = y_table[i - out_y1]; \
-               type *in_row = (type*)in_rows[in_y] + in_x1 * components; \
-               type *out_row = (type*)out_rows[i] + out_x1 * components; \
- \
-/* X direction is scaled and requires a table lookup */ \
-               if(out_w != in_x2 - in_x1) \
-               { \
-                       for(int j = 0; j < out_w; j++) \
-                       { \
-                               int in_x = x_table[j]; \
-                               int input1, input2, input3, input4; \
-                               type *output = out_row + j * components; \
-        \
-                               input1 = in_row[in_x * components]; \
-                               input2 = in_row[in_x * components + 1]; \
-                               input3 = in_row[in_x * components + 2]; \
-                               if(components == 4) \
-                                       input4 = in_row[in_x * components + 3]; \
-        \
-                               if(components == 3) \
-                               { \
-                                       BLEND_3(max, type); \
-                               } \
-                               else \
-                               { \
-                                       BLEND_4(max, type); \
-                               } \
-                       } \
-               } \
-               else \
-/* X direction is not scaled */ \
-               { \
-                       for(int j = 0; j < out_w; j++) \
-                       { \
-                               int input1, input2, input3, input4; \
-                               type *output = out_row + j * components; \
-        \
-                               input1 = in_row[j * components]; \
-                               input2 = in_row[j * components + 1]; \
-                               input3 = in_row[j * components + 2]; \
-                               if(components == 4) \
-                                       input4 = in_row[j * components + 3]; \
-        \
-                               if(components == 3) \
-                               { \
-                                       BLEND_3(max, type); \
-                               } \
-                               else \
-                               { \
-                                       BLEND_4(max, type); \
-                               } \
-                       } \
-               } \
-       } \
-}
-
-
-
-ScaleTranslateUnit::ScaleTranslateUnit(ScaleTranslateEngine *server, OverlayFrame *overlay)
- : LoadClient(server)
-{
-       this->overlay = overlay;
-       this->scale_translate = server;
-}
-
-ScaleTranslateUnit::~ScaleTranslateUnit()
-{
-}
-
-void ScaleTranslateUnit::scale_array(int* &table, 
-       int out_x1, 
-       int out_x2,
-       int in_x1,
-       int in_x2,
-       int is_x)
-{
-       float scale = (float)(out_x2 - out_x1) / (in_x2 - in_x1);
-
-       table = new int[out_x2 - out_x1];
-       
-       if(!is_x)
-       {
-               for(int i = 0; i < out_x2 - out_x1; i++)
-               {
-                       table[i] = (int)((float)i / scale + in_x1);
-               }
-       }
-       else
-       {       
-               for(int i = 0; i < out_x2 - out_x1; i++)
-               {
-                       table[i] = (int)((float)i / scale);
-               }
-       }
-}
-
-
-void ScaleTranslateUnit::process_package(LoadPackage *package)
-{
-       ScaleTranslatePackage *pkg = (ScaleTranslatePackage*)package;
-
-// Args for NEAREST_NEIGHBOR_MACRO
-       VFrame *output = scale_translate->output;
-       VFrame *input = scale_translate->input;
-       int in_x1 = scale_translate->in_x1;
-       int in_y1 = scale_translate->in_y1;
-       int in_x2 = scale_translate->in_x2;
-       int in_y2 = scale_translate->in_y2;
-       int out_x1 = scale_translate->out_x1;
-       int out_y1 = scale_translate->out_y1;
-       int out_x2 = scale_translate->out_x2;
-       int out_y2 = scale_translate->out_y2;
-       float alpha = scale_translate->alpha;
-       int mode = scale_translate->mode;
-
-       int *x_table;
-       int *y_table;
-       unsigned char **in_rows = input->get_rows();
-       unsigned char **out_rows = output->get_rows();
-
-       scale_array(x_table, 
-               out_x1, 
-               out_x2,
-               in_x1,
-               in_x2,
-               1);
-       scale_array(y_table, 
-               out_y1, 
-               out_y2,
-               in_y1,
-               in_y2,
-               0);
-
-
-       switch(input->get_color_model())
-       {
-               case BC_RGB888:
-               case BC_YUV888:
-                       SCALE_TRANSLATE(0xff, uint8_t, 3);
-                       break;
-
-               case BC_RGBA8888:
-               case BC_YUVA8888:
-                       SCALE_TRANSLATE(0xff, uint8_t, 4);
-                       break;
-
-
-               case BC_RGB161616:
-               case BC_YUV161616:
-                       SCALE_TRANSLATE(0xffff, uint16_t, 3);
-                       break;
-
-               case BC_RGBA16161616:
-               case BC_YUVA16161616:
-                       SCALE_TRANSLATE(0xffff, uint16_t, 4);
-                       break;
-       }
-       
-       delete [] x_table;
-       delete [] y_table;
-
-};
-
-
-
-
-
-
-
-
-
-ScaleTranslateEngine::ScaleTranslateEngine(OverlayFrame *overlay, int cpus)
- : LoadServer(cpus, cpus)
-{
-       this->overlay = overlay;
-}
-
-ScaleTranslateEngine::~ScaleTranslateEngine()
-{
-}
-
-void ScaleTranslateEngine::init_packages()
-{
-       int out_h = out_y2 - out_y1;
-
-       for(int i = 0; i < total_packages; i++)
-       {
-               ScaleTranslatePackage *package = (ScaleTranslatePackage*)packages[i];
-               package->out_row1 = (int)(out_y1 + out_h / 
-                       total_packages * 
-                       i);
-               package->out_row2 = (int)((float)package->out_row1 + 
-                       out_h / 
-                       total_packages);
-               if(i >= total_packages - 1)
-                       package->out_row2 = out_y2;
-       }
-}
-
-LoadClient* ScaleTranslateEngine::new_client()
-{
-       return new ScaleTranslateUnit(this, overlay);
-}
-
-LoadPackage* ScaleTranslateEngine::new_package()
-{
-       return new ScaleTranslatePackage;
-}
-
-
-ScaleTranslatePackage::ScaleTranslatePackage()
-{
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#define BLEND_ONLY(type, max, components) \
-{ \
-       int64_t opacity = (int)(alpha * max + 0.5); \
-       int64_t transparency = max - opacity; \
- \
-       type** output_rows = (type**)output->get_rows(); \
-       type** input_rows = (type**)input->get_rows(); \
-       int w = input->get_w(); \
-       int h = input->get_h(); \
- \
-       for(int i = pkg->out_row1; i < pkg->out_row2; i++) \
-       { \
-               type* in_row = input_rows[i]; \
-               type* output = output_rows[i]; \
- \
-               for(int j = 0; j < w; j++) \
-               { \
-                       int input1, input2, input3, input4; \
-                       input1 = in_row[j * components]; \
-                       input2 = in_row[j * components + 1]; \
-                       input3 = in_row[j * components + 2]; \
-                       if(components == 4) input4 = in_row[j * components + 3]; \
- \
- \
-                       if(components == 3) \
-                       { \
-                               BLEND_3(max, type); \
-                       } \
-                       else \
-                       { \
-                               BLEND_4(max, type); \
-                       } \
- \
-                       input += components; \
-                       output += components; \
-               } \
-       } \
-}
-
-
-
-
-BlendUnit::BlendUnit(BlendEngine *server, OverlayFrame *overlay)
- : LoadClient(server)
-{
-       this->overlay = overlay;
-       this->blend_engine = server;
-}
-
-BlendUnit::~BlendUnit()
-{
-}
-
-void BlendUnit::process_package(LoadPackage *package)
-{
-       BlendPackage *pkg = (BlendPackage*)package;
-
-
-       VFrame *output = blend_engine->output;
-       VFrame *input = blend_engine->input;
-       float alpha = blend_engine->alpha;
-       int mode = blend_engine->mode;
-
-       switch(input->get_color_model())
-       {
-               case BC_RGB888:
-               case BC_YUV888:
-                       BLEND_ONLY(unsigned char, 0xff, 3);
-                       break;
-               case BC_RGBA8888:
-               case BC_YUVA8888:
-                       BLEND_ONLY(unsigned char, 0xff, 4);
-                       break;
-               case BC_RGB161616:
-               case BC_YUV161616:
-                       BLEND_ONLY(uint16_t, 0xffff, 3);
-                       break;
-               case BC_RGBA16161616:
-               case BC_YUVA16161616:
-                       BLEND_ONLY(uint16_t, 0xffff, 4);
-                       break;
-       }
-}
-
-
-
-BlendEngine::BlendEngine(OverlayFrame *overlay, int cpus)
- : LoadServer(cpus, cpus)
-{
-       this->overlay = overlay;
-}
-
-BlendEngine::~BlendEngine()
-{
-}
-
-void BlendEngine::init_packages()
-{
-       for(int i = 0; i < total_packages; i++)
-       {
-               BlendPackage *package = (BlendPackage*)packages[i];
-               package->out_row1 = (int)(input->get_h() / 
-                       total_packages * 
-                       i);
-               package->out_row2 = (int)((float)package->out_row1 +
-                       input->get_h() / 
-                       total_packages);
-
-               if(i >= total_packages - 1)
-                       package->out_row2 = input->get_h();
-       }
-}
-
-LoadClient* BlendEngine::new_client()
-{
-       return new BlendUnit(this, overlay);
-}
-
-LoadPackage* BlendEngine::new_package()
-{
-       return new BlendPackage;
-}
-
-
-BlendPackage::BlendPackage()
-{
-}
-
-
diff --git a/cinelerra-5.1/cinelerra/overlayframe.C.float b/cinelerra-5.1/cinelerra/overlayframe.C.float
deleted file mode 100644 (file)
index 24c7781..0000000
+++ /dev/null
@@ -1,1723 +0,0 @@
-#include <math.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-
-#include "clip.h"
-#include "edl.inc"
-#include "overlayframe.h"
-#include "vframe.h"
-
-OverlayFrame::OverlayFrame(int cpus)
-{
-       temp_frame = 0;
-       blend_engine = 0;
-       scale_engine = 0;
-       scaletranslate_engine = 0;
-       translate_engine = 0;
-       this->cpus = cpus;
-}
-
-OverlayFrame::~OverlayFrame()
-{
-//printf("OverlayFrame::~OverlayFrame 1\n");
-       if(temp_frame) delete temp_frame;
-       if(scale_engine) delete scale_engine;
-       if(translate_engine) delete translate_engine;
-       if(blend_engine) delete blend_engine;
-       if(scaletranslate_engine) delete scaletranslate_engine;
-//printf("OverlayFrame::~OverlayFrame 2\n");
-}
-
-
-
-
-
-
-
-
-// Verification: 
-
-// (255 * 255 + 0 * 0) / 255 = 255
-// (255 * 127 + 255 * (255 - 127)) / 255 = 255
-
-// (65535 * 65535 + 0 * 0) / 65535 = 65535
-// (65535 * 32767 + 65535 * (65535 - 32767)) / 65535 = 65535
-
-
-// Branch prediction 4 U
-
-#define BLEND_3(max, type) \
-{ \
-       int64_t r, g, b; \
- \
-/* if(mode != TRANSFER_NORMAL) printf("BLEND mode = %d\n", mode); */ \
-       switch(mode) \
-       { \
-               case TRANSFER_DIVIDE: \
-                       r = output[0] ? (((int64_t)input1 * max) / output[0]) : max; \
-                       g = output[1] ? (((int64_t)input2 * max) / output[1]) : max; \
-                       b = output[2] ? (((int64_t)input3 * max) / output[2]) : max; \
-                       r = (r * opacity + output[0] * transparency) / max; \
-                       g = (g * opacity + output[1] * transparency) / max; \
-                       b = (b * opacity + output[2] * transparency) / max; \
-                       break; \
-               case TRANSFER_MULTIPLY: \
-                       r = ((int64_t)input1 * output[0]) / max; \
-                       g = ((int64_t)input2 * output[1]) / max; \
-                       b = ((int64_t)input3 * output[2]) / max; \
-                       r = (r * opacity + output[0] * transparency) / max; \
-                       g = (g * opacity + output[1] * transparency) / max; \
-                       b = (b * opacity + output[2] * transparency) / max; \
-                       break; \
-               case TRANSFER_SUBTRACT: \
-                       r = (((int64_t)input1 - output[0]) * opacity + output[0] * transparency) / max; \
-                       g = (((int64_t)input2 - output[1]) * opacity + output[1] * transparency) / max; \
-                       b = (((int64_t)input3 - output[2]) * opacity + output[2] * transparency) / max; \
-                       break; \
-               case TRANSFER_ADDITION: \
-                       r = (((int64_t)input1 + output[0]) * opacity + output[0] * transparency) / max; \
-                       g = (((int64_t)input2 + output[1]) * opacity + output[1] * transparency) / max; \
-                       b = (((int64_t)input3 + output[2]) * opacity + output[2] * transparency) / max; \
-                       break; \
-               case TRANSFER_REPLACE: \
-                       r = input1; \
-                       g = input2; \
-                       b = input3; \
-                       break; \
-               case TRANSFER_NORMAL: \
-                       r = ((int64_t)input1 * opacity + output[0] * transparency) / max; \
-                       g = ((int64_t)input2 * opacity + output[1] * transparency) / max; \
-                       b = ((int64_t)input3 * opacity + output[2] * transparency) / max; \
-                       break; \
-       } \
- \
-       output[0] = (type)CLIP(r, 0, max); \
-       output[1] = (type)CLIP(g, 0, max); \
-       output[2] = (type)CLIP(b, 0, max); \
-}
-
-
-
-
-
-// Blending equations are drastically different for 3 and 4 components
-#define BLEND_4(max, type) \
-{ \
-       int64_t r, g, b, a; \
-       int64_t pixel_opacity, pixel_transparency; \
- \
-       pixel_opacity = opacity * input4 / max; \
-       pixel_transparency = (max - pixel_opacity) * output[3] / max; \
- \
-       switch(mode) \
-       { \
-               case TRANSFER_DIVIDE: \
-                       r = output[0] ? (((int64_t)input1 * max) / output[0]) : max; \
-                       g = output[1] ? (((int64_t)input2 * max) / output[1]) : max; \
-                       b = output[2] ? (((int64_t)input3 * max) / output[2]) : max; \
-                       r = (r * pixel_opacity + output[0] * pixel_transparency) / max; \
-                       g = (g * pixel_opacity + output[1] * pixel_transparency) / max; \
-                       b = (b * pixel_opacity + output[2] * pixel_transparency) / max; \
-                       a = input4 > output[3] ? input4 : output[3]; \
-                       break; \
-               case TRANSFER_MULTIPLY: \
-                       r = ((int64_t)input1 * output[0]) / max; \
-                       g = ((int64_t)input2 * output[1]) / max; \
-                       b = ((int64_t)input3 * output[2]) / max; \
-                       r = (r * pixel_opacity + output[0] * pixel_transparency) / max; \
-                       g = (g * pixel_opacity + output[1] * pixel_transparency) / max; \
-                       b = (b * pixel_opacity + output[2] * pixel_transparency) / max; \
-                       a = input4 > output[3] ? input4 : output[3]; \
-                       break; \
-               case TRANSFER_SUBTRACT: \
-                       r = (((int64_t)input1 - output[0]) * pixel_opacity + output[0] * pixel_transparency) / max; \
-                       g = (((int64_t)input2 - output[1]) * pixel_opacity + output[1] * pixel_transparency) / max; \
-                       b = (((int64_t)input3 - output[2]) * pixel_opacity + output[2] * pixel_transparency) / max; \
-                       a = input4 > output[3] ? input4 : output[3]; \
-                       break; \
-               case TRANSFER_ADDITION: \
-                       r = (((int64_t)input1 + output[0]) * pixel_opacity + output[0] * pixel_transparency) / max; \
-                       g = (((int64_t)input2 + output[1]) * pixel_opacity + output[1] * pixel_transparency) / max; \
-                       b = (((int64_t)input3 + output[2]) * pixel_opacity + output[2] * pixel_transparency) / max; \
-                       a = input4 > output[3] ? input4 : output[3]; \
-                       break; \
-               case TRANSFER_REPLACE: \
-                       r = input1; \
-                       g = input2; \
-                       b = input3; \
-                       a = input4; \
-                       break; \
-               case TRANSFER_NORMAL: \
-                       r = ((int64_t)input1 * pixel_opacity + output[0] * pixel_transparency) / max; \
-                       g = ((int64_t)input2 * pixel_opacity + output[1] * pixel_transparency) / max; \
-                       b = ((int64_t)input3 * pixel_opacity + output[2] * pixel_transparency) / max; \
-                       a = input4 > output[3] ? input4 : output[3]; \
-                       break; \
-       } \
- \
-       output[0] = (type)CLIP(r, 0, max); \
-       output[1] = (type)CLIP(g, 0, max); \
-       output[2] = (type)CLIP(b, 0, max); \
-       output[3] = (type)a; \
-}
-
-
-
-
-
-
-
-
-// Bicubic algorithm using multiprocessors
-// input -> scale nearest integer boundaries -> temp -> translation -> blend -> output
-
-// Nearest neighbor algorithm using multiprocessors for blending
-// input -> scale + translate -> blend -> output
-
-
-int OverlayFrame::overlay(VFrame *output, 
-       VFrame *input, 
-       float in_x1, 
-       float in_y1, 
-       float in_x2, 
-       float in_y2, 
-       float out_x1, 
-       float out_y1, 
-       float out_x2, 
-       float out_y2, 
-       float alpha,       // 0 - 1
-       int mode,
-       int interpolation_type)
-{
-       float w_scale = (out_x2 - out_x1) / (in_x2 - in_x1);
-       float h_scale = (out_y2 - out_y1) / (in_y2 - in_y1);
-
-//printf("OverlayFrame::overlay 1 %d %f\n", mode, alpha);
-// Limit values
-       if(in_x1 < 0)
-       {
-               out_x1 += -in_x1 * w_scale;
-               in_x1 = 0;
-       }
-       else
-       if(in_x1 >= input->get_w())
-       {
-               out_x1 -= (in_x1 - input->get_w()) * w_scale;
-               in_x1 = input->get_w();
-       }
-
-       if(in_y1 < 0)
-       {
-               out_y1 += -in_y1 * h_scale;
-               in_y1 = 0;
-       }
-       else
-       if(in_y1 >= input->get_h())
-       {
-               out_y1 -= (in_y1 - input->get_h()) * h_scale;
-               in_y1 = input->get_h();
-       }
-
-       if(in_x2 < 0)
-       {
-               out_x2 += -in_x2 * w_scale;
-               in_x2 = 0;
-       }
-       else
-       if(in_x2 >= input->get_w())
-       {
-               out_x2 -= (in_x2 - input->get_w()) * w_scale;
-               in_x2 = input->get_w();
-       }
-
-       if(in_y2 < 0)
-       {
-               out_y2 += -in_y2 * h_scale;
-               in_y2 = 0;
-       }
-       else
-       if(in_y2 >= input->get_h())
-       {
-               out_y2 -= (in_y2 - input->get_h()) * h_scale;
-               in_y2 = input->get_h();
-       }
-
-       if(out_x1 < 0)
-       {
-               in_x1 += -out_x1 / w_scale;
-               out_x1 = 0;
-       }
-       else
-       if(out_x1 >= output->get_w())
-       {
-               in_x1 -= (out_x1 - output->get_w()) / w_scale;
-               out_x1 = output->get_w();
-       }
-
-       if(out_y1 < 0)
-       {
-               in_y1 += -out_y1 / h_scale;
-               out_y1 = 0;
-       }
-       else
-       if(out_y1 >= output->get_h())
-       {
-               in_y1 -= (out_y1 - output->get_h()) / h_scale;
-               out_y1 = output->get_h();
-       }
-
-       if(out_x2 < 0)
-       {
-               in_x2 += -out_x2 / w_scale;
-               out_x2 = 0;
-       }
-       else
-       if(out_x2 >= output->get_w())
-       {
-               in_x2 -= (out_x2 - output->get_w()) / w_scale;
-               out_x2 = output->get_w();
-       }
-
-       if(out_y2 < 0)
-       {
-               in_y2 += -out_y2 / h_scale;
-               out_y2 = 0;
-       }
-       else
-       if(out_y2 >= output->get_h())
-       {
-               in_y2 -= (out_y2 - output->get_h()) / h_scale;
-               out_y2 = output->get_h();
-       }
-
-
-
-
-
-       float in_w = in_x2 - in_x1;
-       float in_h = in_y2 - in_y1;
-       float out_w = out_x2 - out_x1;
-       float out_h = out_y2 - out_y1;
-// Input for translation operation
-       VFrame *translation_input = input;
-
-
-
-// printf("OverlayFrame::overlay %f %f %f %f -> %f %f %f %f\n", in_x1,
-//                     in_y1,
-//                     in_x2,
-//                     in_y2,
-//                     out_x1,
-//                     out_y1,
-//                     out_x2,
-//                     out_y2);
-
-
-
-
-
-// ****************************************************************************
-// Transfer to temp buffer by scaling nearest integer boundaries
-// ****************************************************************************
-       if(interpolation_type != NEAREST_NEIGHBOR &&
-               (!EQUIV(w_scale, 1) || !EQUIV(h_scale, 1)))
-       {
-// Create integer boundaries for interpolation
-               int in_x1_int = (int)in_x1;
-               int in_y1_int = (int)in_y1;
-               int in_x2_int = MIN((int)ceil(in_x2), input->get_w());
-               int in_y2_int = MIN((int)ceil(in_y2), input->get_h());
-
-// Dimensions of temp frame.  Integer boundaries scaled.
-               int temp_w = (int)ceil(w_scale * (in_x2_int - in_x1_int));
-               int temp_h = (int)ceil(h_scale * (in_y2_int - in_y1_int));
-               VFrame *scale_output;
-
-
-
-#define NO_TRANSLATION1 \
-       (EQUIV(in_x1, 0) && \
-       EQUIV(in_y1, 0) && \
-       EQUIV(out_x1, 0) && \
-       EQUIV(out_y1, 0) && \
-       EQUIV(in_x2, in_x2_int) && \
-       EQUIV(in_y2, in_y2_int) && \
-       EQUIV(out_x2, temp_w) && \
-       EQUIV(out_y2, temp_h))
-
-
-#define NO_BLEND \
-       (EQUIV(alpha, 1) && \
-       (mode == TRANSFER_REPLACE || \
-       (mode == TRANSFER_NORMAL && cmodel_components(input->get_color_model()) == 3)))
-
-
-
-
-
-// Prepare destination for operation
-
-// No translation and no blending.  The blending operation is built into the
-// translation unit but not the scaling unit.
-// input -> output
-               if(NO_TRANSLATION1 &&
-                       NO_BLEND)
-               {
-// printf("OverlayFrame::overlay input -> output\n");
-
-                       scale_output = output;
-                       translation_input = 0;
-               }
-               else
-// If translation or blending
-// input -> nearest integer boundary temp
-               {
-                       if(temp_frame && 
-                               (temp_frame->get_w() != temp_w ||
-                                       temp_frame->get_h() != temp_h))
-                       {
-                               delete temp_frame;
-                               temp_frame = 0;
-                       }
-
-                       if(!temp_frame)
-                       {
-                               temp_frame = new VFrame(0,
-                                       temp_w,
-                                       temp_h,
-                                       input->get_color_model(),
-                                       -1);
-                       }
-//printf("OverlayFrame::overlay input -> temp\n");
-
-
-                       temp_frame->clear_frame();
-
-// printf("OverlayFrame::overlay 4 temp_w=%d temp_h=%d\n",
-//     temp_w, temp_h);
-                       scale_output = temp_frame;
-                       translation_input = scale_output;
-
-// Adjust input coordinates to reflect new scaled coordinates.
-                       in_x1 = (in_x1 - in_x1_int) * w_scale;
-                       in_y1 = (in_y1 - in_y1_int) * h_scale;
-                       in_x2 = (in_x2 - in_x1_int) * w_scale;
-                       in_y2 = (in_y2 - in_y1_int) * h_scale;
-               }
-
-
-
-
-// Scale input -> scale_output
-               this->scale_output = scale_output;
-               this->scale_input = input;
-               this->w_scale = w_scale;
-               this->h_scale = h_scale;
-               this->in_x1_int = in_x1_int;
-               this->in_y1_int = in_y1_int;
-               this->out_w_int = temp_w;
-               this->out_h_int = temp_h;
-               this->interpolation_type = interpolation_type;
-
-//printf("OverlayFrame::overlay ScaleEngine 1 %d\n", out_h_int);
-               if(!scale_engine) scale_engine = new ScaleEngine(this, cpus);
-               scale_engine->process_packages();
-//printf("OverlayFrame::overlay ScaleEngine 2\n");
-
-
-
-       }
-
-// printf("OverlayFrame::overlay 1  %.2f %.2f %.2f %.2f -> %.2f %.2f %.2f %.2f\n", 
-//     in_x1, 
-//     in_y1, 
-//     in_x2, 
-//     in_y2, 
-//     out_x1, 
-//     out_y1, 
-//     out_x2, 
-//     out_y2);
-
-
-
-
-
-#define NO_TRANSLATION2 \
-       (EQUIV(in_x1, 0) && \
-       EQUIV(in_y1, 0) && \
-       EQUIV(in_x2, translation_input->get_w()) && \
-       EQUIV(in_y2, translation_input->get_h()) && \
-       EQUIV(out_x1, 0) && \
-       EQUIV(out_y1, 0) && \
-       EQUIV(out_x2, output->get_w()) && \
-       EQUIV(out_y2, output->get_h())) \
-
-#define NO_SCALE \
-       (EQUIV(out_x2 - out_x1, in_x2 - in_x1) && \
-       EQUIV(out_y2 - out_y1, in_y2 - in_y1))
-
-       
-
-
-//printf("OverlayFrame::overlay 4 %d\n", mode);
-
-
-
-
-       if(translation_input)
-       {
-// Direct copy
-               if( NO_TRANSLATION2 &&
-                       NO_SCALE &&
-                       NO_BLEND)
-               {
-//printf("OverlayFrame::overlay direct copy\n");
-                       output->copy_from(translation_input);
-               }
-               else
-// Blend only
-               if( NO_TRANSLATION2 &&
-                       NO_SCALE)
-               {
-                       if(!blend_engine) blend_engine = new BlendEngine(this, cpus);
-
-
-                       blend_engine->output = output;
-                       blend_engine->input = translation_input;
-                       blend_engine->alpha = alpha;
-                       blend_engine->mode = mode;
-
-                       blend_engine->process_packages();
-               }
-               else
-// Scale and translate using nearest neighbor
-// Translation is exactly on integer boundaries
-               if(interpolation_type == NEAREST_NEIGHBOR ||
-                       EQUIV(in_x1, (int)in_x1) &&
-                       EQUIV(in_y1, (int)in_y1) &&
-                       EQUIV(in_x2, (int)in_x2) &&
-                       EQUIV(in_y2, (int)in_y2) &&
-
-                       EQUIV(out_x1, (int)out_x1) &&
-                       EQUIV(out_y1, (int)out_y1) &&
-                       EQUIV(out_x2, (int)out_x2) &&
-                       EQUIV(out_y2, (int)out_y2))
-               {
-//printf("OverlayFrame::overlay NEAREST_NEIGHBOR 1\n");
-                       if(!scaletranslate_engine) scaletranslate_engine = new ScaleTranslateEngine(this, cpus);
-
-
-                       scaletranslate_engine->output = output;
-                       scaletranslate_engine->input = translation_input;
-                       scaletranslate_engine->in_x1 = (int)in_x1;
-                       scaletranslate_engine->in_y1 = (int)in_y1;
-                       scaletranslate_engine->in_x2 = (int)in_x2;
-                       scaletranslate_engine->in_y2 = (int)in_y2;
-                       scaletranslate_engine->out_x1 = (int)out_x1;
-                       scaletranslate_engine->out_y1 = (int)out_y1;
-                       scaletranslate_engine->out_x2 = (int)out_x2;
-                       scaletranslate_engine->out_y2 = (int)out_y2;
-                       scaletranslate_engine->alpha = alpha;
-                       scaletranslate_engine->mode = mode;
-
-                       scaletranslate_engine->process_packages();
-               }
-               else
-// Fractional translation
-               {
-// Use fractional translation
-// printf("OverlayFrame::overlay temp -> output  %.2f %.2f %.2f %.2f -> %.2f %.2f %.2f %.2f\n", 
-//     in_x1, 
-//     in_y1, 
-//     in_x2, 
-//     in_y2, 
-//     out_x1, 
-//     out_y1, 
-//     out_x2, 
-//     out_y2);
-                       this->translate_output = output;
-                       this->translate_input = translation_input;
-                       this->translate_in_x1 = in_x1;
-                       this->translate_in_y1 = in_y1;
-                       this->translate_in_x2 = in_x2;
-                       this->translate_in_y2 = in_y2;
-                       this->translate_out_x1 = out_x1;
-                       this->translate_out_y1 = out_y1;
-                       this->translate_out_x2 = out_x2;
-                       this->translate_out_y2 = out_y2;
-                       this->translate_alpha = alpha;
-                       this->translate_mode = mode;
-
-//printf("OverlayFrame::overlay 5 %d\n", mode);
-                       if(!translate_engine) translate_engine = new TranslateEngine(this, cpus);
-                       translate_engine->process_packages();
-
-               }
-       }
-//printf("OverlayFrame::overlay 2\n");
-
-       return 0;
-}
-
-
-
-
-
-
-
-ScalePackage::ScalePackage()
-{
-}
-
-
-
-
-ScaleUnit::ScaleUnit(ScaleEngine *server, OverlayFrame *overlay)
- : LoadClient(server)
-{
-       this->overlay = overlay;
-}
-
-ScaleUnit::~ScaleUnit()
-{
-}
-
-
-
-#define BILINEAR(max, type, components) \
-{ \
-       float k_y = 1.0 / scale_h; \
-       float k_x = 1.0 / scale_w; \
-       type **in_rows = (type**)input->get_rows(); \
-       type **out_rows = (type**)output->get_rows(); \
-       type zero_r, zero_g, zero_b, zero_a; \
-       int in_h_int = input->get_h(); \
-       int in_w_int = input->get_w(); \
- \
-       zero_r = 0; \
-       zero_g = ((max + 1) >> 1) * (do_yuv); \
-       zero_b = ((max + 1) >> 1) * (do_yuv); \
-       if(components == 4) zero_a = 0; \
- \
- \
-       for(int i = pkg->out_row1; i < pkg->out_row2; i++) \
-       { \
-               float f_y = (float)i * k_y; \
-               int i_y = (int)floor(f_y); \
-               float a = f_y - floor(f_y); \
-               type *in_row1 = in_rows[i_y + in_y1_int]; \
-               type *in_row2 = (i_y + in_y1_int < in_h_int - 1) ?  \
-                       in_rows[i_y + in_y1_int + 1] : \
-                       0; \
-               type *out_row = out_rows[i]; \
- \
-               for(int j = 0; j < out_w_int; j++) \
-               { \
-                       float f_x = (float)j * k_x; \
-                       int i_x = (int)floor(f_x); \
-                       float b = f_x - floor(f_x); \
-                       int x = i_x + in_x1_int; \
-                       float output1r, output1g, output1b, output1a; \
-                       float output2r, output2g, output2b, output2a; \
-                       float output3r, output3g, output3b, output3a; \
-                       float output4r, output4g, output4b, output4a; \
- \
-                       output1r = in_row1[x * components]; \
-                       output1g = in_row1[x * components + 1]; \
-                       output1b = in_row1[x * components + 2]; \
-                       if(components == 4) output1a = in_row1[x * components + 3]; \
- \
-                       if(x < in_w_int - 1) \
-                       { \
-                               output2r = in_row1[x * components + components]; \
-                               output2g = in_row1[x * components + components + 1]; \
-                               output2b = in_row1[x * components + components + 2]; \
-                               if(components == 4) output2a = in_row1[x * components + components + 3]; \
- \
-                               if(in_row2) \
-                               { \
-                                       output4r = in_row2[x * components + components]; \
-                                       output4g = in_row2[x * components + components + 1]; \
-                                       output4b = in_row2[x * components + components + 2]; \
-                                       if(components == 4) output4a = in_row2[x * components + components + 3]; \
-                               } \
-                               else \
-                               { \
-                                       output4r = zero_r; \
-                                       output4g = zero_g; \
-                                       output4b = zero_b; \
-                                       if(components == 4) output4a = zero_a; \
-                               } \
-                       } \
-                       else \
-                       { \
-                               output2r = zero_r; \
-                               output2g = zero_g; \
-                               output2b = zero_b; \
-                               if(components == 4) output2a = zero_a; \
-                               output4r = zero_r; \
-                               output4g = zero_g; \
-                               output4b = zero_b; \
-                               if(components == 4) output4a = zero_a; \
-                       } \
- \
-                       if(in_row2) \
-                       { \
-                               output3r = in_row2[x * components]; \
-                               output3g = in_row2[x * components + 1]; \
-                               output3b = in_row2[x * components + 2]; \
-                               if(components == 4) output3a = in_row2[x * components + 3]; \
-                       } \
-                       else \
-                       { \
-                               output3r = zero_r; \
-                               output3g = zero_g; \
-                               output3b = zero_b; \
-                               if(components == 4) output3a = zero_a; \
-                       } \
- \
-            float anti_a = 1.0F - a; \
-                       float anti_b = 1.0F - b; \
-                       out_row[j * components] =  \
-                               (type)((anti_a) * (((anti_b) * output1r) +  \
-                               (b * output2r)) +  \
-                a * (((anti_b) * output3r) +  \
-                               (b * output4r))); \
-                       out_row[j * components + 1] =   \
-                               (type)((anti_a) * (((anti_b) * output1g) +  \
-                               (b * output2g)) +  \
-                a * (((anti_b) * output3g) +  \
-                               (b * output4g))); \
-                       out_row[j * components + 2] =   \
-                               (type)((anti_a) * (((anti_b) * output1b) +  \
-                               (b * output2b)) +  \
-                a * (((anti_b) * output3b) +  \
-                               (b * output4b))); \
-                       if(components == 4) \
-                               out_row[j * components + 3] =   \
-                                       (type)((anti_a) * (((anti_b) * output1a) +  \
-                                       (b * output2a)) +  \
-                       a * (((anti_b) * output3a) +  \
-                                       (b * output4a))); \
-               } \
-       } \
- \
- \
-}
-
-
-#define BICUBIC(max, type, components) \
-{ \
-       float k_y = 1.0 / scale_h; \
-       float k_x = 1.0 / scale_w; \
-       type **in_rows = (type**)input->get_rows(); \
-       type **out_rows = (type**)output->get_rows(); \
-       float *bspline_x, *bspline_y; \
-       int in_h_int = input->get_h(); \
-       int in_w_int = input->get_w(); \
-       type zero_r, zero_g, zero_b, zero_a; \
- \
-       zero_r = 0; \
-       zero_b = ((max + 1) >> 1) * (do_yuv); \
-       zero_g = ((max + 1) >> 1) * (do_yuv); \
-       if(components == 4) \
-               zero_a = 0; \
- \
-       tabulate_bspline(bspline_x,  \
-               k_x, \
-               out_w_int, \
-               -1); \
- \
-       tabulate_bspline(bspline_y,  \
-               k_y, \
-               out_h_int, \
-               1); \
- \
-       for(int i = pkg->out_row1; i < pkg->out_row2; i++) \
-       { \
-               float f_y = (float)i * k_y; \
-               int i_y = (int)floor(f_y); \
-               float a = f_y - floor(f_y); \
- \
- \
-               for(int j = 0; j < out_w_int; j++) \
-               { \
-                       float f_x = (float)j * k_x; \
-                       int i_x = (int)floor(f_x); \
-                       float b = f_x - floor(f_x); \
-                       float output1, output2, output3, output4; \
-                       output1 = 0; \
-                       output2 = 0; \
-                       output3 = 0; \
-                       if(components == 4) \
-                               output4 = 0; \
-                       int table_y = i * 4; \
- \
-/* Kernel */ \
-                       for(int m = -1; m < 3; m++) \
-                       { \
-                               float r1 = bspline_y[table_y++]; \
-                               int y = in_y1_int + i_y + m; \
-                               int table_x = j * 4; \
- \
-                               for(int n = -1; n < 3; n++) \
-                               { \
-                                       float r2 = bspline_x[table_x++]; \
-                                       int x = in_x1_int + i_x + n; \
-                                       float r_square = r1 * r2; \
- \
-/* Inside boundary. */ \
-                                       if(x >= 0 && \
-                                               x < in_w_int && \
-                                               y >= 0 && \
-                                               y < in_h_int) \
-                                       { \
-                                               output1 += r_square * in_rows[y][x * components]; \
-                                               output2 += r_square * in_rows[y][x * components + 1]; \
-                                               output3 += r_square * in_rows[y][x * components + 2]; \
-                                               if(components == 4) \
-                                                       output4 += r_square * in_rows[y][x * components + 3]; \
-                                       } \
-                                       else \
-                                       { \
-                                               output1 += r_square * zero_r; \
-                                               output2 += r_square * zero_g; \
-                                               output3 += r_square * zero_b; \
-                                               if(components == 4) \
-                                                       output4 += r_square * zero_a; \
-                                       } \
-                               } \
-                       } \
- \
- \
-                       out_rows[i][j * components] = (type)output1; \
-                       out_rows[i][j * components + 1] = (type)output2; \
-                       out_rows[i][j * components + 2] = (type)output3; \
-                       if(components == 4) \
-                               out_rows[i][j * components + 3] = (type)output4; \
- \
-               } \
-       } \
- \
-       delete [] bspline_x; \
-       delete [] bspline_y; \
-}
-
-
-
-// Pow function is not thread safe in Compaqt C
-#define CUBE(x) ((x) * (x) * (x))
-
-float ScaleUnit::cubic_bspline(float x)
-{
-       float a, b, c, d;
-
-       if((x + 2.0F) <= 0.0F) 
-       {
-       a = 0.0F;
-       }
-       else 
-       {
-       a = CUBE(x + 2.0F);
-       }
-
-
-       if((x + 1.0F) <= 0.0F) 
-       {
-       b = 0.0F;
-       }
-       else 
-       {
-       b = CUBE(x + 1.0F);
-       }    
-
-       if(x <= 0) 
-       {
-       c = 0.0F;
-       }
-       else 
-       {
-       c = CUBE(x);
-       }  
-
-       if((x - 1.0F) <= 0.0F) 
-       {
-       d = 0.0F;
-       }
-       else 
-       {
-       d = CUBE(x - 1.0F);
-       }
-
-       return (a - (4.0F * b) + (6.0F * c) - (4.0F * d)) / 6.0;
-}
-
-
-void ScaleUnit::tabulate_bspline(float* &table, 
-       float scale,
-       int pixels,
-       float coefficient)
-{
-       table = new float[pixels * 4];
-
-       for(int i = 0, j = 0; i < pixels; i++)
-       {
-               float f_x = (float)i * scale;
-               float a = f_x - floor(f_x);
-               
-               for(float m = -1; m < 3; m++)
-               {
-                       table[j++] = cubic_bspline(coefficient * (m - a));
-               }
-       }
-}
-
-void ScaleUnit::process_package(LoadPackage *package)
-{
-       ScalePackage *pkg = (ScalePackage*)package;
-
-// Arguments for macros
-       VFrame *output = overlay->scale_output;
-       VFrame *input = overlay->scale_input;
-       float scale_w = overlay->w_scale;
-       float scale_h = overlay->h_scale;
-       int in_x1_int = overlay->in_x1_int;
-       int in_y1_int = overlay->in_y1_int;
-       int out_h_int = overlay->out_h_int;
-       int out_w_int = overlay->out_w_int;
-       int do_yuv = 
-               (overlay->scale_input->get_color_model() == BC_YUV888 ||
-               overlay->scale_input->get_color_model() == BC_YUVA8888 ||
-               overlay->scale_input->get_color_model() == BC_YUV161616 ||
-               overlay->scale_input->get_color_model() == BC_YUVA16161616);
-
-       if(overlay->interpolation_type == CUBIC_CUBIC || 
-               (overlay->interpolation_type == CUBIC_LINEAR 
-                       && overlay->w_scale > 1 && 
-                       overlay->h_scale > 1))
-       {
-       
-               switch(overlay->scale_input->get_color_model())
-               {
-                       case BC_RGB888:
-                       case BC_YUV888:
-                               BICUBIC(0xff, unsigned char, 3);
-                               break;
-
-                       case BC_RGBA8888:
-                       case BC_YUVA8888:
-                               BICUBIC(0xff, unsigned char, 4);
-                               break;
-
-                       case BC_RGB161616:
-                       case BC_YUV161616:
-                               BICUBIC(0xffff, uint16_t, 3);
-                               break;
-
-                       case BC_RGBA16161616:
-                       case BC_YUVA16161616:
-                               BICUBIC(0xffff, uint16_t, 4);
-                               break;
-               }
-       }
-       else
-// Perform bilinear scaling input -> scale_output
-       {
-               switch(overlay->scale_input->get_color_model())
-               {
-                       case BC_RGB888:
-                       case BC_YUV888:
-                               BILINEAR(0xff, unsigned char, 3);
-                               break;
-
-                       case BC_RGBA8888:
-                       case BC_YUVA8888:
-                               BILINEAR(0xff, unsigned char, 4);
-                               break;
-
-                       case BC_RGB161616:
-                       case BC_YUV161616:
-                               BILINEAR(0xffff, uint16_t, 3);
-                               break;
-
-                       case BC_RGBA16161616:
-                       case BC_YUVA16161616:
-                               BILINEAR(0xffff, uint16_t, 4);
-                               break;
-               }
-       }
-
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-ScaleEngine::ScaleEngine(OverlayFrame *overlay, int cpus)
- : LoadServer(cpus, cpus)
-{
-       this->overlay = overlay;
-}
-
-ScaleEngine::~ScaleEngine()
-{
-}
-
-void ScaleEngine::init_packages()
-{
-       for(int i = 0; i < total_packages; i++)
-       {
-               ScalePackage *package = (ScalePackage*)packages[i];
-               package->out_row1 = overlay->out_h_int / total_packages * i;
-               package->out_row2 = package->out_row1 + overlay->out_h_int / total_packages;
-
-               if(i >= total_packages - 1)
-                       package->out_row2 = overlay->out_h_int;
-       }
-}
-
-LoadClient* ScaleEngine::new_client()
-{
-       return new ScaleUnit(this, overlay);
-}
-
-LoadPackage* ScaleEngine::new_package()
-{
-       return new ScalePackage;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-TranslatePackage::TranslatePackage()
-{
-}
-
-
-
-TranslateUnit::TranslateUnit(TranslateEngine *server, OverlayFrame *overlay)
- : LoadClient(server)
-{
-       this->overlay = overlay;
-}
-
-TranslateUnit::~TranslateUnit()
-{
-}
-
-
-
-void TranslateUnit::translation_array(transfer_table* &table, 
-       float out_x1, 
-       float out_x2,
-       float in_x1,
-       float in_x2,
-       int in_total, 
-       int out_total, 
-       int &out_x1_int,
-       int &out_x2_int)
-{
-       int out_w_int;
-       float offset = out_x1 - in_x1;
-
-       out_x1_int = (int)out_x1;
-       out_x2_int = MIN((int)ceil(out_x2), out_total);
-       out_w_int = out_x2_int - out_x1_int;
-
-       table = new transfer_table[out_w_int];
-       bzero(table, sizeof(transfer_table) * out_w_int);
-
-
-//printf("OverlayFrame::translation_array 1 %f %f -> %f %f\n", in_x1, in_x2, out_x1, out_x2);
-
-       float in_x = in_x1;
-       for(int out_x = out_x1_int; out_x < out_x2_int; out_x++)
-       {
-               transfer_table *entry = &table[out_x - out_x1_int];
-
-               entry->in_x1 = (int)in_x;
-               entry->in_x2 = (int)in_x + 1;
-
-// Get fraction of output pixel to fill
-               entry->output_fraction = 1;
-
-               if(out_x1 > out_x)
-               {
-                       entry->output_fraction -= out_x1 - out_x;
-               }
-
-               if(out_x2 < out_x + 1)
-               {
-                       entry->output_fraction = (out_x2 - out_x);
-               }
-
-// Advance in_x until out_x_fraction is filled
-               float out_x_fraction = entry->output_fraction;
-               float in_x_fraction = floor(in_x + 1) - in_x;
-
-               if(out_x_fraction <= in_x_fraction)
-               {
-                       entry->in_fraction1 = out_x_fraction;
-                       entry->in_fraction2 = 0.0;
-                       in_x += out_x_fraction;
-               }
-               else
-               {
-                       entry->in_fraction1 = in_x_fraction;
-                       in_x += out_x_fraction;
-                       entry->in_fraction2 = in_x - floor(in_x);
-               }
-
-// Clip in_x
-               if(entry->in_x2 >= in_total)
-               {
-                       entry->in_x2 = in_total - 1;
-                       entry->in_fraction2 = 0.0;
-               }
-               
-               if(entry->in_x1 >= in_total)
-               {
-                       entry->in_x1 = in_total - 1;
-                       entry->in_fraction1 = 0.0;
-               }
-// printf("OverlayFrame::translation_array 2 %d %d %d %f %f %f\n", 
-//     out_x, 
-//     entry->in_x1, 
-//     entry->in_x2, 
-//     entry->in_fraction1, 
-//     entry->in_fraction2, 
-//     entry->output_fraction);
-       }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#define TRANSLATE(max, type, components) \
-{ \
- \
-       type **in_rows = (type**)input->get_rows(); \
-       type **out_rows = (type**)output->get_rows(); \
- \
-/* printf("OverlayFrame::translate 1  %.2f %.2f %.2f %.2f -> %.2f %.2f %.2f %.2f\n",  */ \
-/*     (in_x1),  in_y1,  in_x2,  in_y2,  out_x1,  out_y1, out_x2,  out_y2); */ \
- \
-       unsigned int master_opacity = (int)(alpha * max + 0.5); \
-       unsigned int master_transparency = max - master_opacity; \
- \
-/* printf("TRANSLATE %d\n", mode); */ \
- \
-       for(int i = row1; i < row2; i++) \
-       { \
-               int in_y1 = y_table[i - out_y1_int].in_x1; \
-               int in_y2 = y_table[i - out_y1_int].in_x2; \
-               float y_fraction1 = y_table[i - out_y1_int].in_fraction1; \
-               float y_fraction2 = y_table[i - out_y1_int].in_fraction2; \
-               float y_output_fraction = y_table[i - out_y1_int].output_fraction; \
-               type *in_row1 = in_rows[(in_y1)]; \
-               type *in_row2 = in_rows[(in_y2)]; \
-               type *out_row = out_rows[i]; \
- \
-               for(int j = out_x1_int; j < out_x2_int; j++) \
-               { \
-                       int in_x1 = x_table[j - out_x1_int].in_x1; \
-                       int in_x2 = x_table[j - out_x1_int].in_x2; \
-                       float x_fraction1 = x_table[j - out_x1_int].in_fraction1; \
-                       float x_fraction2 = x_table[j - out_x1_int].in_fraction2; \
-                       float x_output_fraction = x_table[j - out_x1_int].output_fraction; \
-                       type *output = &out_row[j * components]; \
-                       int input1, input2, input3, input4; \
- \
-                       input1 = (int)(in_row1[in_x1 * components] * x_fraction1 * y_fraction1 +  \
-                               in_row1[in_x2 * components] * x_fraction2 * y_fraction1 +  \
-                               in_row2[in_x1 * components] * x_fraction1 * y_fraction2 +  \
-                               in_row2[in_x2 * components] * x_fraction2 * y_fraction2 + 0.5); \
-                       input2 = (int)(in_row1[in_x1 * components + 1] * x_fraction1 * y_fraction1 +  \
-                               in_row1[in_x2 * components + 1] * x_fraction2 * y_fraction1 +  \
-                               in_row2[in_x1 * components + 1] * x_fraction1 * y_fraction2 +  \
-                               in_row2[in_x2 * components + 1] * x_fraction2 * y_fraction2 + 0.5); \
-                       input3 = (int)(in_row1[in_x1 * components + 2] * x_fraction1 * y_fraction1 +  \
-                               in_row1[in_x2 * components + 2] * x_fraction2 * y_fraction1 +  \
-                               in_row2[in_x1 * components + 2] * x_fraction1 * y_fraction2 +  \
-                               in_row2[in_x2 * components + 2] * x_fraction2 * y_fraction2 + 0.5); \
-                       if(components == 4) \
-                               input4 = (int)(in_row1[in_x1 * components + 3] * x_fraction1 * y_fraction1 +  \
-                                       in_row1[in_x2 * components + 3] * x_fraction2 * y_fraction1 +  \
-                                       in_row2[in_x1 * components + 3] * x_fraction1 * y_fraction2 +  \
-                                       in_row2[in_x2 * components + 3] * x_fraction2 * y_fraction2 + 0.5); \
- \
-                       unsigned int opacity = (int)(master_opacity *  \
-                               y_output_fraction *  \
-                               x_output_fraction + 0.5); \
-                       unsigned int transparency = max - opacity; \
- \
-/* if(opacity != max) printf("TRANSLATE %x %d %d\n", opacity, j, i); */ \
- \
-                       if(components == 3) \
-                       { \
-                               BLEND_3(max, type); \
-                       } \
-                       else \
-                       { \
-                               BLEND_4(max, type); \
-                       } \
-               } \
-       } \
-}
-
-void TranslateUnit::process_package(LoadPackage *package)
-{
-       TranslatePackage *pkg = (TranslatePackage*)package;
-       int out_y1_int; 
-       int out_y2_int; 
-       int out_x1_int; 
-       int out_x2_int; 
-
-
-// Variables for TRANSLATE
-       VFrame *input = overlay->translate_input;
-       VFrame *output = overlay->translate_output;
-       float in_x1 = overlay->translate_in_x1;
-       float in_y1 = overlay->translate_in_y1;
-       float in_x2 = overlay->translate_in_x2;
-       float in_y2 = overlay->translate_in_y2;
-       float out_x1 = overlay->translate_out_x1;
-       float out_y1 = overlay->translate_out_y1;
-       float out_x2 = overlay->translate_out_x2;
-       float out_y2 = overlay->translate_out_y2;
-       float alpha = overlay->translate_alpha;
-       int row1 = pkg->out_row1;
-       int row2 = pkg->out_row2;
-       int mode = overlay->translate_mode;
-
-       transfer_table *x_table; 
-       transfer_table *y_table; 
-       translation_array(x_table,  
-               out_x1,  
-               out_x2, 
-               in_x1, 
-               in_x2, 
-               input->get_w(),  
-               output->get_w(),  
-               out_x1_int, 
-               out_x2_int); 
-       translation_array(y_table,  
-               out_y1,  
-               out_y2, 
-               in_y1, 
-               in_y2, 
-               input->get_h(),  
-               output->get_h(),  
-               out_y1_int, 
-               out_y2_int); 
-       switch(overlay->translate_input->get_color_model())
-       {
-               case BC_RGB888:
-               case BC_YUV888:
-                       TRANSLATE(0xff, unsigned char, 3);
-                       break;
-
-               case BC_RGBA8888:
-               case BC_YUVA8888:
-                       TRANSLATE(0xff, unsigned char, 4);
-                       break;
-
-               case BC_RGB161616:
-               case BC_YUV161616:
-                       TRANSLATE(0xffff, uint16_t, 3);
-                       break;
-
-               case BC_RGBA16161616:
-               case BC_YUVA16161616:
-                       TRANSLATE(0xffff, uint16_t, 4);
-                       break;
-       }
-       delete [] x_table; 
-       delete [] y_table; 
-}
-
-
-
-
-
-
-
-
-
-
-TranslateEngine::TranslateEngine(OverlayFrame *overlay, int cpus)
- : LoadServer(cpus, cpus)
-{
-       this->overlay = overlay;
-}
-
-TranslateEngine::~TranslateEngine()
-{
-}
-
-void TranslateEngine::init_packages()
-{
-       int out_y1_int = (int)overlay->translate_out_y1;
-       int out_y2_int = MIN((int)ceil(overlay->translate_out_y2), overlay->translate_output->get_h());
-       int out_h = out_y2_int - out_y1_int;
-
-       for(int i = 0; i < total_packages; i++)
-       {
-               TranslatePackage *package = (TranslatePackage*)packages[i];
-               package->out_row1 = (int)(out_y1_int + out_h / 
-                       total_packages * 
-                       i);
-               package->out_row2 = (int)((float)package->out_row1 + 
-                       out_h / 
-                       total_packages);
-               if(i >= total_packages - 1)
-                       package->out_row2 = out_y2_int;
-       }
-}
-
-LoadClient* TranslateEngine::new_client()
-{
-       return new TranslateUnit(this, overlay);
-}
-
-LoadPackage* TranslateEngine::new_package()
-{
-       return new TranslatePackage;
-}
-
-
-
-
-
-
-
-
-#define SCALE_TRANSLATE(max, type, components) \
-{ \
-       int64_t opacity = (int)(alpha * max + 0.5); \
-       int64_t transparency = max - opacity; \
-       int out_w = out_x2 - out_x1; \
- \
-       for(int i = pkg->out_row1; i < pkg->out_row2; i++) \
-       { \
-               int in_y = y_table[i - out_y1]; \
-               type *in_row = (type*)in_rows[in_y] + in_x1 * components; \
-               type *out_row = (type*)out_rows[i] + out_x1 * components; \
- \
-/* X direction is scaled and requires a table lookup */ \
-               if(out_w != in_x2 - in_x1) \
-               { \
-                       for(int j = 0; j < out_w; j++) \
-                       { \
-                               int in_x = x_table[j]; \
-                               int input1, input2, input3, input4; \
-                               type *output = out_row + j * components; \
-        \
-                               input1 = in_row[in_x * components]; \
-                               input2 = in_row[in_x * components + 1]; \
-                               input3 = in_row[in_x * components + 2]; \
-                               if(components == 4) \
-                                       input4 = in_row[in_x * components + 3]; \
-        \
-                               if(components == 3) \
-                               { \
-                                       BLEND_3(max, type); \
-                               } \
-                               else \
-                               { \
-                                       BLEND_4(max, type); \
-                               } \
-                       } \
-               } \
-               else \
-/* X direction is not scaled */ \
-               { \
-                       for(int j = 0; j < out_w; j++) \
-                       { \
-                               int input1, input2, input3, input4; \
-                               type *output = out_row + j * components; \
-        \
-                               input1 = in_row[j * components]; \
-                               input2 = in_row[j * components + 1]; \
-                               input3 = in_row[j * components + 2]; \
-                               if(components == 4) \
-                                       input4 = in_row[j * components + 3]; \
-        \
-                               if(components == 3) \
-                               { \
-                                       BLEND_3(max, type); \
-                               } \
-                               else \
-                               { \
-                                       BLEND_4(max, type); \
-                               } \
-                       } \
-               } \
-       } \
-}
-
-
-
-ScaleTranslateUnit::ScaleTranslateUnit(ScaleTranslateEngine *server, OverlayFrame *overlay)
- : LoadClient(server)
-{
-       this->overlay = overlay;
-       this->scale_translate = server;
-}
-
-ScaleTranslateUnit::~ScaleTranslateUnit()
-{
-}
-
-void ScaleTranslateUnit::scale_array(int* &table, 
-       int out_x1, 
-       int out_x2,
-       int in_x1,
-       int in_x2,
-       int is_x)
-{
-       float scale = (float)(out_x2 - out_x1) / (in_x2 - in_x1);
-
-       table = new int[out_x2 - out_x1];
-       
-       if(!is_x)
-       {
-               for(int i = 0; i < out_x2 - out_x1; i++)
-               {
-                       table[i] = (int)((float)i / scale + in_x1);
-               }
-       }
-       else
-       {       
-               for(int i = 0; i < out_x2 - out_x1; i++)
-               {
-                       table[i] = (int)((float)i / scale);
-               }
-       }
-}
-
-
-void ScaleTranslateUnit::process_package(LoadPackage *package)
-{
-       ScaleTranslatePackage *pkg = (ScaleTranslatePackage*)package;
-
-// Args for NEAREST_NEIGHBOR_MACRO
-       VFrame *output = scale_translate->output;
-       VFrame *input = scale_translate->input;
-       int in_x1 = scale_translate->in_x1;
-       int in_y1 = scale_translate->in_y1;
-       int in_x2 = scale_translate->in_x2;
-       int in_y2 = scale_translate->in_y2;
-       int out_x1 = scale_translate->out_x1;
-       int out_y1 = scale_translate->out_y1;
-       int out_x2 = scale_translate->out_x2;
-       int out_y2 = scale_translate->out_y2;
-       float alpha = scale_translate->alpha;
-       int mode = scale_translate->mode;
-
-       int *x_table;
-       int *y_table;
-       unsigned char **in_rows = input->get_rows();
-       unsigned char **out_rows = output->get_rows();
-
-       scale_array(x_table, 
-               out_x1, 
-               out_x2,
-               in_x1,
-               in_x2,
-               1);
-       scale_array(y_table, 
-               out_y1, 
-               out_y2,
-               in_y1,
-               in_y2,
-               0);
-
-
-       switch(input->get_color_model())
-       {
-               case BC_RGB888:
-               case BC_YUV888:
-                       SCALE_TRANSLATE(0xff, uint8_t, 3);
-                       break;
-
-               case BC_RGBA8888:
-               case BC_YUVA8888:
-                       SCALE_TRANSLATE(0xff, uint8_t, 4);
-                       break;
-
-
-               case BC_RGB161616:
-               case BC_YUV161616:
-                       SCALE_TRANSLATE(0xffff, uint16_t, 3);
-                       break;
-
-               case BC_RGBA16161616:
-               case BC_YUVA16161616:
-                       SCALE_TRANSLATE(0xffff, uint16_t, 4);
-                       break;
-       }
-       
-       delete [] x_table;
-       delete [] y_table;
-
-};
-
-
-
-
-
-
-
-
-
-ScaleTranslateEngine::ScaleTranslateEngine(OverlayFrame *overlay, int cpus)
- : LoadServer(cpus, cpus)
-{
-       this->overlay = overlay;
-}
-
-ScaleTranslateEngine::~ScaleTranslateEngine()
-{
-}
-
-void ScaleTranslateEngine::init_packages()
-{
-       int out_h = out_y2 - out_y1;
-
-       for(int i = 0; i < total_packages; i++)
-       {
-               ScaleTranslatePackage *package = (ScaleTranslatePackage*)packages[i];
-               package->out_row1 = (int)(out_y1 + out_h / 
-                       total_packages * 
-                       i);
-               package->out_row2 = (int)((float)package->out_row1 + 
-                       out_h / 
-                       total_packages);
-               if(i >= total_packages - 1)
-                       package->out_row2 = out_y2;
-       }
-}
-
-LoadClient* ScaleTranslateEngine::new_client()
-{
-       return new ScaleTranslateUnit(this, overlay);
-}
-
-LoadPackage* ScaleTranslateEngine::new_package()
-{
-       return new ScaleTranslatePackage;
-}
-
-
-ScaleTranslatePackage::ScaleTranslatePackage()
-{
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#define BLEND_ONLY(type, max, components) \
-{ \
-       int64_t opacity = (int)(alpha * max + 0.5); \
-       int64_t transparency = max - opacity; \
- \
-       type** output_rows = (type**)output->get_rows(); \
-       type** input_rows = (type**)input->get_rows(); \
-       int w = input->get_w(); \
-       int h = input->get_h(); \
- \
-       for(int i = pkg->out_row1; i < pkg->out_row2; i++) \
-       { \
-               type* in_row = input_rows[i]; \
-               type* output = output_rows[i]; \
- \
-               for(int j = 0; j < w; j++) \
-               { \
-                       int input1, input2, input3, input4; \
-                       input1 = in_row[j * components]; \
-                       input2 = in_row[j * components + 1]; \
-                       input3 = in_row[j * components + 2]; \
-                       if(components == 4) input4 = in_row[j * components + 3]; \
- \
- \
-                       if(components == 3) \
-                       { \
-                               BLEND_3(max, type); \
-                       } \
-                       else \
-                       { \
-                               BLEND_4(max, type); \
-                       } \
- \
-                       input += components; \
-                       output += components; \
-               } \
-       } \
-}
-
-
-
-
-BlendUnit::BlendUnit(BlendEngine *server, OverlayFrame *overlay)
- : LoadClient(server)
-{
-       this->overlay = overlay;
-       this->blend_engine = server;
-}
-
-BlendUnit::~BlendUnit()
-{
-}
-
-void BlendUnit::process_package(LoadPackage *package)
-{
-       BlendPackage *pkg = (BlendPackage*)package;
-
-
-       VFrame *output = blend_engine->output;
-       VFrame *input = blend_engine->input;
-       float alpha = blend_engine->alpha;
-       int mode = blend_engine->mode;
-
-       switch(input->get_color_model())
-       {
-               case BC_RGB888:
-               case BC_YUV888:
-                       BLEND_ONLY(unsigned char, 0xff, 3);
-                       break;
-               case BC_RGBA8888:
-               case BC_YUVA8888:
-                       BLEND_ONLY(unsigned char, 0xff, 4);
-                       break;
-               case BC_RGB161616:
-               case BC_YUV161616:
-                       BLEND_ONLY(uint16_t, 0xffff, 3);
-                       break;
-               case BC_RGBA16161616:
-               case BC_YUVA16161616:
-                       BLEND_ONLY(uint16_t, 0xffff, 4);
-                       break;
-       }
-}
-
-
-
-BlendEngine::BlendEngine(OverlayFrame *overlay, int cpus)
- : LoadServer(cpus, cpus)
-{
-       this->overlay = overlay;
-}
-
-BlendEngine::~BlendEngine()
-{
-}
-
-void BlendEngine::init_packages()
-{
-       for(int i = 0; i < total_packages; i++)
-       {
-               BlendPackage *package = (BlendPackage*)packages[i];
-               package->out_row1 = (int)(input->get_h() / 
-                       total_packages * 
-                       i);
-               package->out_row2 = (int)((float)package->out_row1 +
-                       input->get_h() / 
-                       total_packages);
-
-               if(i >= total_packages - 1)
-                       package->out_row2 = input->get_h();
-       }
-}
-
-LoadClient* BlendEngine::new_client()
-{
-       return new BlendUnit(this, overlay);
-}
-
-LoadPackage* BlendEngine::new_package()
-{
-       return new BlendPackage;
-}
-
-
-BlendPackage::BlendPackage()
-{
-}
-
-
diff --git a/cinelerra-5.1/cinelerra/overlayframe.C.floattable b/cinelerra-5.1/cinelerra/overlayframe.C.floattable
deleted file mode 100644 (file)
index 6b01219..0000000
+++ /dev/null
@@ -1,1769 +0,0 @@
-#include <math.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-
-#include "clip.h"
-#include "edl.inc"
-#include "mutex.h"
-#include "overlayframe.h"
-#include "vframe.h"
-
-OverlayFrame::OverlayFrame(int cpus)
-{
-       temp_frame = 0;
-       blend_engine = 0;
-       scale_engine = 0;
-       scaletranslate_engine = 0;
-       translate_engine = 0;
-       this->cpus = cpus;
-}
-
-OverlayFrame::~OverlayFrame()
-{
-//printf("OverlayFrame::~OverlayFrame 1\n");
-       if(temp_frame) delete temp_frame;
-       if(scale_engine) delete scale_engine;
-       if(translate_engine) delete translate_engine;
-       if(blend_engine) delete blend_engine;
-       if(scaletranslate_engine) delete scaletranslate_engine;
-//printf("OverlayFrame::~OverlayFrame 2\n");
-}
-
-
-
-
-
-
-
-
-// Verification: 
-
-// (255 * 255 + 0 * 0) / 255 = 255
-// (255 * 127 + 255 * (255 - 127)) / 255 = 255
-
-// (65535 * 65535 + 0 * 0) / 65535 = 65535
-// (65535 * 32767 + 65535 * (65535 - 32767)) / 65535 = 65535
-
-
-// Branch prediction 4 U
-
-#define BLEND_3(max, type) \
-{ \
-       int64_t r, g, b; \
- \
-/* if(mode != TRANSFER_NORMAL) printf("BLEND mode = %d\n", mode); */ \
-       switch(mode) \
-       { \
-               case TRANSFER_DIVIDE: \
-                       r = output[0] ? (((int64_t)input1 * max) / output[0]) : max; \
-                       g = output[1] ? (((int64_t)input2 * max) / output[1]) : max; \
-                       b = output[2] ? (((int64_t)input3 * max) / output[2]) : max; \
-                       r = (r * opacity + output[0] * transparency) / max; \
-                       g = (g * opacity + output[1] * transparency) / max; \
-                       b = (b * opacity + output[2] * transparency) / max; \
-                       break; \
-               case TRANSFER_MULTIPLY: \
-                       r = ((int64_t)input1 * output[0]) / max; \
-                       g = ((int64_t)input2 * output[1]) / max; \
-                       b = ((int64_t)input3 * output[2]) / max; \
-                       r = (r * opacity + output[0] * transparency) / max; \
-                       g = (g * opacity + output[1] * transparency) / max; \
-                       b = (b * opacity + output[2] * transparency) / max; \
-                       break; \
-               case TRANSFER_SUBTRACT: \
-                       r = (((int64_t)input1 - output[0]) * opacity + output[0] * transparency) / max; \
-                       g = (((int64_t)input2 - output[1]) * opacity + output[1] * transparency) / max; \
-                       b = (((int64_t)input3 - output[2]) * opacity + output[2] * transparency) / max; \
-                       break; \
-               case TRANSFER_ADDITION: \
-                       r = (((int64_t)input1 + output[0]) * opacity + output[0] * transparency) / max; \
-                       g = (((int64_t)input2 + output[1]) * opacity + output[1] * transparency) / max; \
-                       b = (((int64_t)input3 + output[2]) * opacity + output[2] * transparency) / max; \
-                       break; \
-               case TRANSFER_REPLACE: \
-                       r = input1; \
-                       g = input2; \
-                       b = input3; \
-                       break; \
-               case TRANSFER_NORMAL: \
-                       r = ((int64_t)input1 * opacity + output[0] * transparency) / max; \
-                       g = ((int64_t)input2 * opacity + output[1] * transparency) / max; \
-                       b = ((int64_t)input3 * opacity + output[2] * transparency) / max; \
-                       break; \
-       } \
- \
-       output[0] = (type)CLIP(r, 0, max); \
-       output[1] = (type)CLIP(g, 0, max); \
-       output[2] = (type)CLIP(b, 0, max); \
-}
-
-
-
-
-
-// Blending equations are drastically different for 3 and 4 components
-#define BLEND_4(max, type) \
-{ \
-       int64_t r, g, b, a; \
-       int64_t pixel_opacity, pixel_transparency; \
- \
-       pixel_opacity = opacity * input4 / max; \
-       pixel_transparency = (max - pixel_opacity) * output[3] / max; \
- \
-       switch(mode) \
-       { \
-               case TRANSFER_DIVIDE: \
-                       r = output[0] ? (((int64_t)input1 * max) / output[0]) : max; \
-                       g = output[1] ? (((int64_t)input2 * max) / output[1]) : max; \
-                       b = output[2] ? (((int64_t)input3 * max) / output[2]) : max; \
-                       r = (r * pixel_opacity + output[0] * pixel_transparency) / max; \
-                       g = (g * pixel_opacity + output[1] * pixel_transparency) / max; \
-                       b = (b * pixel_opacity + output[2] * pixel_transparency) / max; \
-                       a = input4 > output[3] ? input4 : output[3]; \
-                       break; \
-               case TRANSFER_MULTIPLY: \
-                       r = ((int64_t)input1 * output[0]) / max; \
-                       g = ((int64_t)input2 * output[1]) / max; \
-                       b = ((int64_t)input3 * output[2]) / max; \
-                       r = (r * pixel_opacity + output[0] * pixel_transparency) / max; \
-                       g = (g * pixel_opacity + output[1] * pixel_transparency) / max; \
-                       b = (b * pixel_opacity + output[2] * pixel_transparency) / max; \
-                       a = input4 > output[3] ? input4 : output[3]; \
-                       break; \
-               case TRANSFER_SUBTRACT: \
-                       r = (((int64_t)input1 - output[0]) * pixel_opacity + output[0] * pixel_transparency) / max; \
-                       g = (((int64_t)input2 - output[1]) * pixel_opacity + output[1] * pixel_transparency) / max; \
-                       b = (((int64_t)input3 - output[2]) * pixel_opacity + output[2] * pixel_transparency) / max; \
-                       a = input4 > output[3] ? input4 : output[3]; \
-                       break; \
-               case TRANSFER_ADDITION: \
-                       r = (((int64_t)input1 + output[0]) * pixel_opacity + output[0] * pixel_transparency) / max; \
-                       g = (((int64_t)input2 + output[1]) * pixel_opacity + output[1] * pixel_transparency) / max; \
-                       b = (((int64_t)input3 + output[2]) * pixel_opacity + output[2] * pixel_transparency) / max; \
-                       a = input4 > output[3] ? input4 : output[3]; \
-                       break; \
-               case TRANSFER_REPLACE: \
-                       r = input1; \
-                       g = input2; \
-                       b = input3; \
-                       a = input4; \
-                       break; \
-               case TRANSFER_NORMAL: \
-                       r = ((int64_t)input1 * pixel_opacity + output[0] * pixel_transparency) / max; \
-                       g = ((int64_t)input2 * pixel_opacity + output[1] * pixel_transparency) / max; \
-                       b = ((int64_t)input3 * pixel_opacity + output[2] * pixel_transparency) / max; \
-                       a = input4 > output[3] ? input4 : output[3]; \
-                       break; \
-       } \
- \
-       output[0] = (type)CLIP(r, 0, max); \
-       output[1] = (type)CLIP(g, 0, max); \
-       output[2] = (type)CLIP(b, 0, max); \
-       output[3] = (type)a; \
-}
-
-
-
-
-
-
-
-
-// Bicubic algorithm using multiprocessors
-// input -> scale nearest integer boundaries -> temp -> translation -> blend -> output
-
-// Nearest neighbor algorithm using multiprocessors for blending
-// input -> scale + translate -> blend -> output
-
-
-int OverlayFrame::overlay(VFrame *output, 
-       VFrame *input, 
-       float in_x1, 
-       float in_y1, 
-       float in_x2, 
-       float in_y2, 
-       float out_x1, 
-       float out_y1, 
-       float out_x2, 
-       float out_y2, 
-       float alpha,       // 0 - 1
-       int mode,
-       int interpolation_type)
-{
-       float w_scale = (out_x2 - out_x1) / (in_x2 - in_x1);
-       float h_scale = (out_y2 - out_y1) / (in_y2 - in_y1);
-
-//printf("OverlayFrame::overlay 1 %d %f\n", mode, alpha);
-// Limit values
-       if(in_x1 < 0)
-       {
-               out_x1 += -in_x1 * w_scale;
-               in_x1 = 0;
-       }
-       else
-       if(in_x1 >= input->get_w())
-       {
-               out_x1 -= (in_x1 - input->get_w()) * w_scale;
-               in_x1 = input->get_w();
-       }
-
-       if(in_y1 < 0)
-       {
-               out_y1 += -in_y1 * h_scale;
-               in_y1 = 0;
-       }
-       else
-       if(in_y1 >= input->get_h())
-       {
-               out_y1 -= (in_y1 - input->get_h()) * h_scale;
-               in_y1 = input->get_h();
-       }
-
-       if(in_x2 < 0)
-       {
-               out_x2 += -in_x2 * w_scale;
-               in_x2 = 0;
-       }
-       else
-       if(in_x2 >= input->get_w())
-       {
-               out_x2 -= (in_x2 - input->get_w()) * w_scale;
-               in_x2 = input->get_w();
-       }
-
-       if(in_y2 < 0)
-       {
-               out_y2 += -in_y2 * h_scale;
-               in_y2 = 0;
-       }
-       else
-       if(in_y2 >= input->get_h())
-       {
-               out_y2 -= (in_y2 - input->get_h()) * h_scale;
-               in_y2 = input->get_h();
-       }
-
-       if(out_x1 < 0)
-       {
-               in_x1 += -out_x1 / w_scale;
-               out_x1 = 0;
-       }
-       else
-       if(out_x1 >= output->get_w())
-       {
-               in_x1 -= (out_x1 - output->get_w()) / w_scale;
-               out_x1 = output->get_w();
-       }
-
-       if(out_y1 < 0)
-       {
-               in_y1 += -out_y1 / h_scale;
-               out_y1 = 0;
-       }
-       else
-       if(out_y1 >= output->get_h())
-       {
-               in_y1 -= (out_y1 - output->get_h()) / h_scale;
-               out_y1 = output->get_h();
-       }
-
-       if(out_x2 < 0)
-       {
-               in_x2 += -out_x2 / w_scale;
-               out_x2 = 0;
-       }
-       else
-       if(out_x2 >= output->get_w())
-       {
-               in_x2 -= (out_x2 - output->get_w()) / w_scale;
-               out_x2 = output->get_w();
-       }
-
-       if(out_y2 < 0)
-       {
-               in_y2 += -out_y2 / h_scale;
-               out_y2 = 0;
-       }
-       else
-       if(out_y2 >= output->get_h())
-       {
-               in_y2 -= (out_y2 - output->get_h()) / h_scale;
-               out_y2 = output->get_h();
-       }
-
-
-
-
-
-       float in_w = in_x2 - in_x1;
-       float in_h = in_y2 - in_y1;
-       float out_w = out_x2 - out_x1;
-       float out_h = out_y2 - out_y1;
-// Input for translation operation
-       VFrame *translation_input = input;
-
-
-
-// printf("OverlayFrame::overlay %f %f %f %f -> %f %f %f %f\n", in_x1,
-//                     in_y1,
-//                     in_x2,
-//                     in_y2,
-//                     out_x1,
-//                     out_y1,
-//                     out_x2,
-//                     out_y2);
-
-
-
-
-
-// ****************************************************************************
-// Transfer to temp buffer by scaling nearest integer boundaries
-// ****************************************************************************
-       if(interpolation_type != NEAREST_NEIGHBOR &&
-               interpolation_type != LINEAR_LINEAR &&
-               (!EQUIV(w_scale, 1) || !EQUIV(h_scale, 1)))
-       {
-// Create integer boundaries for interpolation
-               int in_x1_int = (int)in_x1;
-               int in_y1_int = (int)in_y1;
-               int in_x2_int = MIN((int)ceil(in_x2), input->get_w());
-               int in_y2_int = MIN((int)ceil(in_y2), input->get_h());
-
-// Dimensions of temp frame.  Integer boundaries scaled.
-               int temp_w = (int)ceil(w_scale * (in_x2_int - in_x1_int));
-               int temp_h = (int)ceil(h_scale * (in_y2_int - in_y1_int));
-               VFrame *scale_output;
-
-
-
-#define NO_TRANSLATION1 \
-       (EQUIV(in_x1, 0) && \
-       EQUIV(in_y1, 0) && \
-       EQUIV(out_x1, 0) && \
-       EQUIV(out_y1, 0) && \
-       EQUIV(in_x2, in_x2_int) && \
-       EQUIV(in_y2, in_y2_int) && \
-       EQUIV(out_x2, temp_w) && \
-       EQUIV(out_y2, temp_h))
-
-
-#define NO_BLEND \
-       (EQUIV(alpha, 1) && \
-       (mode == TRANSFER_REPLACE || \
-       (mode == TRANSFER_NORMAL && cmodel_components(input->get_color_model()) == 3)))
-
-
-
-
-
-// Prepare destination for operation
-
-// No translation and no blending.  The blending operation is built into the
-// translation unit but not the scaling unit.
-// input -> output
-               if(NO_TRANSLATION1 &&
-                       NO_BLEND)
-               {
-// printf("OverlayFrame::overlay input -> output\n");
-
-                       scale_output = output;
-                       translation_input = 0;
-               }
-               else
-// If translation or blending
-// input -> nearest integer boundary temp
-               {
-                       if(temp_frame && 
-                               (temp_frame->get_w() != temp_w ||
-                                       temp_frame->get_h() != temp_h))
-                       {
-                               delete temp_frame;
-                               temp_frame = 0;
-                       }
-
-                       if(!temp_frame)
-                       {
-                               temp_frame = new VFrame(0,
-                                       temp_w,
-                                       temp_h,
-                                       input->get_color_model(),
-                                       -1);
-                       }
-//printf("OverlayFrame::overlay input -> temp\n");
-
-
-                       temp_frame->clear_frame();
-
-// printf("OverlayFrame::overlay 4 temp_w=%d temp_h=%d\n",
-//     temp_w, temp_h);
-                       scale_output = temp_frame;
-                       translation_input = scale_output;
-
-// Adjust input coordinates to reflect new scaled coordinates.
-                       in_x1 = (in_x1 - in_x1_int) * w_scale;
-                       in_y1 = (in_y1 - in_y1_int) * h_scale;
-                       in_x2 = (in_x2 - in_x1_int) * w_scale;
-                       in_y2 = (in_y2 - in_y1_int) * h_scale;
-               }
-
-
-
-//printf("Overlay 1\n");
-
-// Scale input -> scale_output
-               if(!scale_engine) scale_engine = new ScaleEngine(this, cpus);
-               scale_engine->scale_output = scale_output;
-               scale_engine->scale_input = input;
-               scale_engine->w_scale = w_scale;
-               scale_engine->h_scale = h_scale;
-               scale_engine->in_x1_int = in_x1_int;
-               scale_engine->in_y1_int = in_y1_int;
-               scale_engine->out_w_int = temp_w;
-               scale_engine->out_h_int = temp_h;
-               scale_engine->interpolation_type = interpolation_type;
-//printf("Overlay 2\n");
-
-//printf("OverlayFrame::overlay ScaleEngine 1 %d\n", out_h_int);
-               scale_engine->process_packages();
-//printf("OverlayFrame::overlay ScaleEngine 2\n");
-
-
-
-       }
-
-// printf("OverlayFrame::overlay 1  %.2f %.2f %.2f %.2f -> %.2f %.2f %.2f %.2f\n", 
-//     in_x1, 
-//     in_y1, 
-//     in_x2, 
-//     in_y2, 
-//     out_x1, 
-//     out_y1, 
-//     out_x2, 
-//     out_y2);
-
-
-
-
-
-#define NO_TRANSLATION2 \
-       (EQUIV(in_x1, 0) && \
-       EQUIV(in_y1, 0) && \
-       EQUIV(in_x2, translation_input->get_w()) && \
-       EQUIV(in_y2, translation_input->get_h()) && \
-       EQUIV(out_x1, 0) && \
-       EQUIV(out_y1, 0) && \
-       EQUIV(out_x2, output->get_w()) && \
-       EQUIV(out_y2, output->get_h())) \
-
-#define NO_SCALE \
-       (EQUIV(out_x2 - out_x1, in_x2 - in_x1) && \
-       EQUIV(out_y2 - out_y1, in_y2 - in_y1))
-
-       
-
-
-//printf("OverlayFrame::overlay 4 %d\n", mode);
-
-
-
-
-       if(translation_input)
-       {
-// Direct copy
-               if( NO_TRANSLATION2 &&
-                       NO_SCALE &&
-                       NO_BLEND)
-               {
-//printf("OverlayFrame::overlay direct copy\n");
-                       output->copy_from(translation_input);
-               }
-               else
-// Blend only
-               if( NO_TRANSLATION2 &&
-                       NO_SCALE)
-               {
-                       if(!blend_engine) blend_engine = new BlendEngine(this, cpus);
-
-
-                       blend_engine->output = output;
-                       blend_engine->input = translation_input;
-                       blend_engine->alpha = alpha;
-                       blend_engine->mode = mode;
-
-                       blend_engine->process_packages();
-               }
-               else
-// Scale and translate using nearest neighbor
-// Translation is exactly on integer boundaries
-               if(interpolation_type == NEAREST_NEIGHBOR ||
-                       EQUIV(in_x1, (int)in_x1) &&
-                       EQUIV(in_y1, (int)in_y1) &&
-                       EQUIV(in_x2, (int)in_x2) &&
-                       EQUIV(in_y2, (int)in_y2) &&
-
-                       EQUIV(out_x1, (int)out_x1) &&
-                       EQUIV(out_y1, (int)out_y1) &&
-                       EQUIV(out_x2, (int)out_x2) &&
-                       EQUIV(out_y2, (int)out_y2))
-               {
-//printf("OverlayFrame::overlay NEAREST_NEIGHBOR 1\n");
-                       if(!scaletranslate_engine) scaletranslate_engine = new ScaleTranslateEngine(this, cpus);
-
-
-                       scaletranslate_engine->output = output;
-                       scaletranslate_engine->input = translation_input;
-                       scaletranslate_engine->in_x1 = (int)in_x1;
-                       scaletranslate_engine->in_y1 = (int)in_y1;
-                       scaletranslate_engine->in_x2 = (int)in_x2;
-                       scaletranslate_engine->in_y2 = (int)in_y2;
-                       scaletranslate_engine->out_x1 = (int)out_x1;
-                       scaletranslate_engine->out_y1 = (int)out_y1;
-                       scaletranslate_engine->out_x2 = (int)out_x2;
-                       scaletranslate_engine->out_y2 = (int)out_y2;
-                       scaletranslate_engine->alpha = alpha;
-                       scaletranslate_engine->mode = mode;
-
-                       scaletranslate_engine->process_packages();
-               }
-               else
-// Fractional translation
-               {
-// Use fractional translation
-// printf("OverlayFrame::overlay temp -> output  %.2f %.2f %.2f %.2f -> %.2f %.2f %.2f %.2f\n", 
-//     in_x1, 
-//     in_y1, 
-//     in_x2, 
-//     in_y2, 
-//     out_x1, 
-//     out_y1, 
-//     out_x2, 
-//     out_y2);
-
-//printf("Overlay 3\n");
-                       if(!translate_engine) translate_engine = new TranslateEngine(this, cpus);
-                       translate_engine->translate_output = output;
-                       translate_engine->translate_input = translation_input;
-                       translate_engine->translate_in_x1 = in_x1;
-                       translate_engine->translate_in_y1 = in_y1;
-                       translate_engine->translate_in_x2 = in_x2;
-                       translate_engine->translate_in_y2 = in_y2;
-                       translate_engine->translate_out_x1 = out_x1;
-                       translate_engine->translate_out_y1 = out_y1;
-                       translate_engine->translate_out_x2 = out_x2;
-                       translate_engine->translate_out_y2 = out_y2;
-                       translate_engine->translate_alpha = alpha;
-                       translate_engine->translate_mode = mode;
-//printf("Overlay 4\n");
-
-//printf("OverlayFrame::overlay 5 %d\n", mode);
-                       translate_engine->process_packages();
-
-               }
-       }
-//printf("OverlayFrame::overlay 2\n");
-
-       return 0;
-}
-
-
-
-
-
-
-
-ScalePackage::ScalePackage()
-{
-}
-
-
-
-
-ScaleUnit::ScaleUnit(ScaleEngine *server, OverlayFrame *overlay)
- : LoadClient(server)
-{
-       this->overlay = overlay;
-       this->engine = server;
-}
-
-ScaleUnit::~ScaleUnit()
-{
-}
-
-
-
-#define BILINEAR(max, type, components) \
-{ \
-       float k_y = 1.0 / scale_h; \
-       float k_x = 1.0 / scale_w; \
-       type **in_rows = (type**)input->get_rows(); \
-       type **out_rows = (type**)output->get_rows(); \
-       type zero_r, zero_g, zero_b, zero_a; \
-       int in_h_int = input->get_h(); \
-       int in_w_int = input->get_w(); \
-       int *table_int_x, *table_int_y; \
-       float *table_frac_x, *table_antifrac_x, *table_frac_y, *table_antifrac_y; \
- \
-       zero_r = 0; \
-       zero_g = ((max + 1) >> 1) * (do_yuv); \
-       zero_b = ((max + 1) >> 1) * (do_yuv); \
-       if(components == 4) zero_a = 0; \
- \
-       tabulate_blinear(table_int_x, table_frac_x, table_antifrac_x, k_x, 0, out_w_int, in_w_int); \
-       tabulate_blinear(table_int_y, table_frac_y, table_antifrac_y, k_y, pkg->out_row1, pkg->out_row2, in_h_int); \
- \
-       for(int i = pkg->out_row1; i < pkg->out_row2; i++) \
-       { \
-               int i_y = table_int_y[i - pkg->out_row1]; \
-               float a = table_frac_y[i - pkg->out_row1]; \
-        float anti_a = table_antifrac_y[i - pkg->out_row1]; \
-               type *in_row1 = in_rows[i_y + in_y1_int]; \
-               type *in_row2 = (i_y + in_y1_int < in_h_int - 1) ?  \
-                       in_rows[i_y + in_y1_int + 1] : \
-                       0; \
-               type *out_row = out_rows[i]; \
- \
-               for(int j = 0; j < out_w_int; j++) \
-               { \
-                       int i_x = table_int_x[j]; \
-                       float b = table_frac_x[j]; \
-                       float anti_b = table_antifrac_x[j]; \
-                       int x = i_x + in_x1_int; \
-                       float output1r, output1g, output1b, output1a; \
-                       float output2r, output2g, output2b, output2a; \
-                       float output3r, output3g, output3b, output3a; \
-                       float output4r, output4g, output4b, output4a; \
- \
-                       output1r = in_row1[x * components]; \
-                       output1g = in_row1[x * components + 1]; \
-                       output1b = in_row1[x * components + 2]; \
-                       if(components == 4) output1a = in_row1[x * components + 3]; \
- \
-                       if(x < in_w_int - 1) \
-                       { \
-                               output2r = in_row1[x * components + components]; \
-                               output2g = in_row1[x * components + components + 1]; \
-                               output2b = in_row1[x * components + components + 2]; \
-                               if(components == 4) output2a = in_row1[x * components + components + 3]; \
- \
-                               if(in_row2) \
-                               { \
-                                       output4r = in_row2[x * components + components]; \
-                                       output4g = in_row2[x * components + components + 1]; \
-                                       output4b = in_row2[x * components + components + 2]; \
-                                       if(components == 4) output4a = in_row2[x * components + components + 3]; \
-                               } \
-                               else \
-                               { \
-                                       output4r = zero_r; \
-                                       output4g = zero_g; \
-                                       output4b = zero_b; \
-                                       if(components == 4) output4a = zero_a; \
-                               } \
-                       } \
-                       else \
-                       { \
-                               output2r = zero_r; \
-                               output2g = zero_g; \
-                               output2b = zero_b; \
-                               if(components == 4) output2a = zero_a; \
-                               output4r = zero_r; \
-                               output4g = zero_g; \
-                               output4b = zero_b; \
-                               if(components == 4) output4a = zero_a; \
-                       } \
- \
-                       if(in_row2) \
-                       { \
-                               output3r = in_row2[x * components]; \
-                               output3g = in_row2[x * components + 1]; \
-                               output3b = in_row2[x * components + 2]; \
-                               if(components == 4) output3a = in_row2[x * components + 3]; \
-                       } \
-                       else \
-                       { \
-                               output3r = zero_r; \
-                               output3g = zero_g; \
-                               output3b = zero_b; \
-                               if(components == 4) output3a = zero_a; \
-                       } \
- \
-                       out_row[j * components] =  \
-                               (type)((anti_a) * (((anti_b) * output1r) +  \
-                               (b * output2r)) +  \
-                a * (((anti_b) * output3r) +  \
-                               (b * output4r))); \
-                       out_row[j * components + 1] =   \
-                               (type)((anti_a) * (((anti_b) * output1g) +  \
-                               (b * output2g)) +  \
-                a * (((anti_b) * output3g) +  \
-                               (b * output4g))); \
-                       out_row[j * components + 2] =   \
-                               (type)((anti_a) * (((anti_b) * output1b) +  \
-                               (b * output2b)) +  \
-                a * (((anti_b) * output3b) +  \
-                               (b * output4b))); \
-                       if(components == 4) \
-                               out_row[j * components + 3] =   \
-                                       (type)((anti_a) * (((anti_b) * output1a) +  \
-                                       (b * output2a)) +  \
-                       a * (((anti_b) * output3a) +  \
-                                       (b * output4a))); \
-               } \
-       } \
- \
- \
-       delete [] table_int_x; \
-       delete [] table_frac_x; \
-       delete [] table_antifrac_x; \
-       delete [] table_int_y; \
-       delete [] table_frac_y; \
-       delete [] table_antifrac_y; \
- \
-}
-
-
-#define BICUBIC(max, type, components) \
-{ \
-       float k_y = 1.0 / scale_h; \
-       float k_x = 1.0 / scale_w; \
-       type **in_rows = (type**)input->get_rows(); \
-       type **out_rows = (type**)output->get_rows(); \
-       float *bspline_x, *bspline_y; \
-       int in_h_int = input->get_h(); \
-       int in_w_int = input->get_w(); \
-       type zero_r, zero_g, zero_b, zero_a; \
-/* printf("BICUBIC\n"); */ \
- \
-       zero_r = 0; \
-       zero_b = ((max + 1) >> 1) * (do_yuv); \
-       zero_g = ((max + 1) >> 1) * (do_yuv); \
-       if(components == 4) \
-               zero_a = 0; \
- \
-       tabulate_bspline(bspline_x,  \
-               k_x, \
-               out_w_int, \
-               -1); \
- \
-       tabulate_bspline(bspline_y,  \
-               k_y, \
-               out_h_int, \
-               1); \
- \
-       for(int i = pkg->out_row1; i < pkg->out_row2; i++) \
-       { \
-               int i_y = (int)(k_y * i); \
- \
- \
-               for(int j = 0; j < out_w_int; j++) \
-               { \
-                       int i_x = (int)(k_x * j); \
-                       float output1, output2, output3, output4; \
-                       output1 = 0; \
-                       output2 = 0; \
-                       output3 = 0; \
-                       if(components == 4) \
-                               output4 = 0; \
-                       int table_y = i * 4; \
- \
-/* Kernel */ \
-                       for(int m = -1; m < 3; m++) \
-                       { \
-                               float r1 = bspline_y[table_y++]; \
-                               int y = in_y1_int + i_y + m; \
-                               int table_x = j * 4; \
- \
-                               CLAMP(y, 0, in_h_int - 1); \
- \
-                               for(int n = -1; n < 3; n++) \
-                               { \
-                                       float r2 = bspline_x[table_x++]; \
-                                       int x = in_x1_int + i_x + n; \
-                                       float r_square = r1 * r2; \
- \
-                                       CLAMP(x, 0, in_w_int - 1); \
- \
-                                       output1 += r_square * in_rows[y][x * components]; \
-                                       output2 += r_square * in_rows[y][x * components + 1]; \
-                                       output3 += r_square * in_rows[y][x * components + 2]; \
-                                       if(components == 4) \
-                                               output4 += r_square * in_rows[y][x * components + 3]; \
-                               } \
-                       } \
- \
- \
-                       out_rows[i][j * components] = (type)output1; \
-                       out_rows[i][j * components + 1] = (type)output2; \
-                       out_rows[i][j * components + 2] = (type)output3; \
-                       if(components == 4) \
-                               out_rows[i][j * components + 3] = (type)output4; \
- \
-               } \
-       } \
- \
-       delete [] bspline_x; \
-       delete [] bspline_y; \
-}
-
-
-
-
-// Pow function is not thread safe in Compaqt C
-#define CUBE(x) ((x) * (x) * (x))
-
-float ScaleUnit::cubic_bspline(float x)
-{
-       float a, b, c, d;
-
-       if((x + 2.0F) <= 0.0F) 
-       {
-       a = 0.0F;
-       }
-       else 
-       {
-       a = CUBE(x + 2.0F);
-       }
-
-
-       if((x + 1.0F) <= 0.0F) 
-       {
-       b = 0.0F;
-       }
-       else 
-       {
-       b = CUBE(x + 1.0F);
-       }    
-
-       if(x <= 0) 
-       {
-       c = 0.0F;
-       }
-       else 
-       {
-       c = CUBE(x);
-       }  
-
-       if((x - 1.0F) <= 0.0F) 
-       {
-       d = 0.0F;
-       }
-       else 
-       {
-       d = CUBE(x - 1.0F);
-       }
-
-
-       return (a - (4.0F * b) + (6.0F * c) - (4.0F * d)) / 6.0;
-}
-
-
-void ScaleUnit::tabulate_bspline(float* &table, 
-       float scale,
-       int pixels,
-       float coefficient)
-{
-       table = new float[pixels * 4];
-       for(int i = 0, j = 0; i < pixels; i++)
-       {
-               float f_x = (float)i * scale;
-               float a = f_x - floor(f_x);
-               
-               for(float m = -1; m < 3; m++)
-               {
-                       table[j++] = cubic_bspline(coefficient * (m - a));
-               }
-               
-       }
-}
-
-void ScaleUnit::tabulate_blinear(int* &table_int,
-               float* &table_frac,
-               float* &table_antifrac,
-               float scale,
-               int pixel1,
-               int pixel2,
-               total_pixels)
-{
-       table_int = new int[pixel2 - pixel1];
-       table_frac = new float[pixel2 - pixel1];
-       table_antifrac = new float[pixel2 - pixel1];
-
-       for(int i = pixel1, j = 0; i < pixel2; i++, j++)
-       {
-               float f_x = (float)i * scale;
-               int i_x = (int)floor(f_x);
-               float a = (f_x - floor(f_x));
-
-               table_int[j] = CLAMP(i_x, 0, total_pixels - 1);
-               table_frac[j] = a;
-               table_antifrac[j] = 1.0F - a;
-       }
-}
-
-void ScaleUnit::process_package(LoadPackage *package)
-{
-       ScalePackage *pkg = (ScalePackage*)package;
-
-//printf("ScaleUnit::process_package 1\n");
-// Arguments for macros
-       VFrame *output = engine->scale_output;
-       VFrame *input = engine->scale_input;
-       float scale_w = engine->w_scale;
-       float scale_h = engine->h_scale;
-       int in_x1_int = engine->in_x1_int;
-       int in_y1_int = engine->in_y1_int;
-       int out_h_int = engine->out_h_int;
-       int out_w_int = engine->out_w_int;
-       int do_yuv = 
-               (input->get_color_model() == BC_YUV888 ||
-               input->get_color_model() == BC_YUVA8888 ||
-               input->get_color_model() == BC_YUV161616 ||
-               input->get_color_model() == BC_YUVA16161616);
-
-//printf("ScaleUnit::process_package 2\n");
-       if(engine->interpolation_type == CUBIC_CUBIC || 
-               (engine->interpolation_type == CUBIC_LINEAR 
-                       && engine->w_scale > 1 && 
-                       engine->h_scale > 1))
-       {
-       
-               switch(engine->scale_input->get_color_model())
-               {
-                       case BC_RGB888:
-                       case BC_YUV888:
-                               BICUBIC(0xff, unsigned char, 3);
-                               break;
-
-                       case BC_RGBA8888:
-                       case BC_YUVA8888:
-                               BICUBIC(0xff, unsigned char, 4);
-                               break;
-
-                       case BC_RGB161616:
-                       case BC_YUV161616:
-                               BICUBIC(0xffff, uint16_t, 3);
-                               break;
-
-                       case BC_RGBA16161616:
-                       case BC_YUVA16161616:
-                               BICUBIC(0xffff, uint16_t, 4);
-                               break;
-               }
-       }
-       else
-// Perform bilinear scaling input -> scale_output
-       {
-               switch(engine->scale_input->get_color_model())
-               {
-                       case BC_RGB888:
-                       case BC_YUV888:
-                               BILINEAR(0xff, unsigned char, 3);
-                               break;
-
-                       case BC_RGBA8888:
-                       case BC_YUVA8888:
-                               BILINEAR(0xff, unsigned char, 4);
-                               break;
-
-                       case BC_RGB161616:
-                       case BC_YUV161616:
-                               BILINEAR(0xffff, uint16_t, 3);
-                               break;
-
-                       case BC_RGBA16161616:
-                       case BC_YUVA16161616:
-                               BILINEAR(0xffff, uint16_t, 4);
-                               break;
-               }
-       }
-//printf("ScaleUnit::process_package 3\n");
-
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-ScaleEngine::ScaleEngine(OverlayFrame *overlay, int cpus)
- : LoadServer(cpus, cpus)
-{
-       this->overlay = overlay;
-}
-
-ScaleEngine::~ScaleEngine()
-{
-}
-
-void ScaleEngine::init_packages()
-{
-       for(int i = 0; i < total_packages; i++)
-       {
-               ScalePackage *package = (ScalePackage*)packages[i];
-               package->out_row1 = out_h_int / total_packages * i;
-               package->out_row2 = package->out_row1 + out_h_int / total_packages;
-
-               if(i >= total_packages - 1)
-                       package->out_row2 = out_h_int;
-       }
-}
-
-LoadClient* ScaleEngine::new_client()
-{
-       return new ScaleUnit(this, overlay);
-}
-
-LoadPackage* ScaleEngine::new_package()
-{
-       return new ScalePackage;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-TranslatePackage::TranslatePackage()
-{
-}
-
-
-
-TranslateUnit::TranslateUnit(TranslateEngine *server, OverlayFrame *overlay)
- : LoadClient(server)
-{
-       this->overlay = overlay;
-       this->engine = server;
-}
-
-TranslateUnit::~TranslateUnit()
-{
-}
-
-
-
-void TranslateUnit::translation_array(transfer_table* &table, 
-       float out_x1, 
-       float out_x2,
-       float in_x1,
-       float in_x2,
-       int in_total, 
-       int out_total, 
-       int &out_x1_int,
-       int &out_x2_int)
-{
-       int out_w_int;
-       float offset = out_x1 - in_x1;
-
-       out_x1_int = (int)out_x1;
-       out_x2_int = MIN((int)ceil(out_x2), out_total);
-       out_w_int = out_x2_int - out_x1_int;
-
-       table = new transfer_table[out_w_int];
-       bzero(table, sizeof(transfer_table) * out_w_int);
-
-
-//printf("OverlayFrame::translation_array 1 %f %f -> %f %f\n", in_x1, in_x2, out_x1, out_x2);
-
-       float in_x = in_x1;
-       for(int out_x = out_x1_int; out_x < out_x2_int; out_x++)
-       {
-               transfer_table *entry = &table[out_x - out_x1_int];
-
-               entry->in_x1 = (int)in_x;
-               entry->in_x2 = (int)in_x + 1;
-
-// Get fraction of output pixel to fill
-               entry->output_fraction = 1;
-
-               if(out_x1 > out_x)
-               {
-                       entry->output_fraction -= out_x1 - out_x;
-               }
-
-               if(out_x2 < out_x + 1)
-               {
-                       entry->output_fraction = (out_x2 - out_x);
-               }
-
-// Advance in_x until out_x_fraction is filled
-               float out_x_fraction = entry->output_fraction;
-               float in_x_fraction = floor(in_x + 1) - in_x;
-
-               if(out_x_fraction <= in_x_fraction)
-               {
-                       entry->in_fraction1 = out_x_fraction;
-                       entry->in_fraction2 = 0.0;
-                       in_x += out_x_fraction;
-               }
-               else
-               {
-                       entry->in_fraction1 = in_x_fraction;
-                       in_x += out_x_fraction;
-                       entry->in_fraction2 = in_x - floor(in_x);
-               }
-
-// Clip in_x and zero out fraction.  This doesn't work for YUV.
-               if(entry->in_x2 >= in_total)
-               {
-                       entry->in_x2 = in_total - 1;
-                       entry->in_fraction2 = 0.0;
-               }
-               
-               if(entry->in_x1 >= in_total)
-               {
-                       entry->in_x1 = in_total - 1;
-                       entry->in_fraction1 = 0.0;
-               }
-// printf("OverlayFrame::translation_array 2 %d %d %d %f %f %f\n", 
-//     out_x, 
-//     entry->in_x1, 
-//     entry->in_x2, 
-//     entry->in_fraction1, 
-//     entry->in_fraction2, 
-//     entry->output_fraction);
-       }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#define TRANSLATE(max, type, components) \
-{ \
- \
-       type **in_rows = (type**)input->get_rows(); \
-       type **out_rows = (type**)output->get_rows(); \
- \
-/* printf("OverlayFrame::translate 1  %.2f %.2f %.2f %.2f -> %.2f %.2f %.2f %.2f\n",  */ \
-/*     (in_x1),  in_y1,  in_x2,  in_y2,  out_x1,  out_y1, out_x2,  out_y2); */ \
- \
-       unsigned int master_opacity = (int)(alpha * max + 0.5); \
-       unsigned int master_transparency = max - master_opacity; \
-       type zero_r, zero_g, zero_b, zero_a; \
-       zero_r = 0; \
-       zero_b = ((max + 1) >> 1) * (do_yuv); \
-       zero_g = ((max + 1) >> 1) * (do_yuv); \
-       if(components == 4) \
-               zero_a = 0; \
- \
-/* printf("TRANSLATE %d\n", mode); */ \
- \
-       for(int i = row1; i < row2; i++) \
-       { \
-               int in_y1 = y_table[i - out_y1_int].in_x1; \
-               int in_y2 = y_table[i - out_y1_int].in_x2; \
-               float y_fraction1 = y_table[i - out_y1_int].in_fraction1; \
-               float y_fraction2 = y_table[i - out_y1_int].in_fraction2; \
-               float y_output_fraction = y_table[i - out_y1_int].output_fraction; \
-               type *in_row1 = in_rows[(in_y1)]; \
-               type *in_row2 = in_rows[(in_y2)]; \
-               type *out_row = out_rows[i]; \
- \
-               for(int j = out_x1_int; j < out_x2_int; j++) \
-               { \
-                       int in_x1 = x_table[j - out_x1_int].in_x1; \
-                       int in_x2 = x_table[j - out_x1_int].in_x2; \
-                       float x_fraction1 = x_table[j - out_x1_int].in_fraction1; \
-                       float x_fraction2 = x_table[j - out_x1_int].in_fraction2; \
-                       float x_output_fraction = x_table[j - out_x1_int].output_fraction; \
-                       type *output = &out_row[j * components]; \
-                       int input1, input2, input3, input4; \
- \
-                       input1 = (int)(in_row1[in_x1 * components] * x_fraction1 * y_fraction1 +  \
-                               in_row1[in_x2 * components] * x_fraction2 * y_fraction1 +  \
-                               in_row2[in_x1 * components] * x_fraction1 * y_fraction2 +  \
-                               in_row2[in_x2 * components] * x_fraction2 * y_fraction2 + 0.5); \
-                       input2 = (int)(in_row1[in_x1 * components + 1] * x_fraction1 * y_fraction1 +  \
-                               in_row1[in_x2 * components + 1] * x_fraction2 * y_fraction1 +  \
-                               in_row2[in_x1 * components + 1] * x_fraction1 * y_fraction2 +  \
-                               in_row2[in_x2 * components + 1] * x_fraction2 * y_fraction2 + 0.5); \
-                       input3 = (int)(in_row1[in_x1 * components + 2] * x_fraction1 * y_fraction1 +  \
-                               in_row1[in_x2 * components + 2] * x_fraction2 * y_fraction1 +  \
-                               in_row2[in_x1 * components + 2] * x_fraction1 * y_fraction2 +  \
-                               in_row2[in_x2 * components + 2] * x_fraction2 * y_fraction2 + 0.5); \
-                       if(components == 4) \
-                               input4 = (int)(in_row1[in_x1 * components + 3] * x_fraction1 * y_fraction1 +  \
-                                       in_row1[in_x2 * components + 3] * x_fraction2 * y_fraction1 +  \
-                                       in_row2[in_x1 * components + 3] * x_fraction1 * y_fraction2 +  \
-                                       in_row2[in_x2 * components + 3] * x_fraction2 * y_fraction2 + 0.5); \
- \
-                       unsigned int opacity = (int)(master_opacity *  \
-                               y_output_fraction *  \
-                               x_output_fraction + 0.5); \
-                       unsigned int transparency = max - opacity; \
- \
-/* if(opacity != max) printf("TRANSLATE %x %d %d\n", opacity, j, i); */ \
- \
-                       if(components == 3) \
-                       { \
-                               BLEND_3(max, type); \
-                       } \
-                       else \
-                       { \
-                               BLEND_4(max, type); \
-                       } \
-               } \
-       } \
-}
-
-void TranslateUnit::process_package(LoadPackage *package)
-{
-       TranslatePackage *pkg = (TranslatePackage*)package;
-       int out_y1_int; 
-       int out_y2_int; 
-       int out_x1_int; 
-       int out_x2_int; 
-
-
-// Variables for TRANSLATE
-       VFrame *input = engine->translate_input;
-       VFrame *output = engine->translate_output;
-       float in_x1 = engine->translate_in_x1;
-       float in_y1 = engine->translate_in_y1;
-       float in_x2 = engine->translate_in_x2;
-       float in_y2 = engine->translate_in_y2;
-       float out_x1 = engine->translate_out_x1;
-       float out_y1 = engine->translate_out_y1;
-       float out_x2 = engine->translate_out_x2;
-       float out_y2 = engine->translate_out_y2;
-       float alpha = engine->translate_alpha;
-       int row1 = pkg->out_row1;
-       int row2 = pkg->out_row2;
-       int mode = engine->translate_mode;
-       int in_total_x = input->get_w();
-       int in_total_y = input->get_h();
-       int do_yuv = 
-               (engine->translate_input->get_color_model() == BC_YUV888 ||
-               engine->translate_input->get_color_model() == BC_YUVA8888 ||
-               engine->translate_input->get_color_model() == BC_YUV161616 ||
-               engine->translate_input->get_color_model() == BC_YUVA16161616);
-
-       transfer_table *x_table; 
-       transfer_table *y_table; 
-       translation_array(x_table,  
-               out_x1,  
-               out_x2, 
-               in_x1, 
-               in_x2, 
-               in_total_x,  
-               output->get_w(),  
-               out_x1_int, 
-               out_x2_int); 
-       translation_array(y_table,  
-               out_y1,  
-               out_y2, 
-               in_y1, 
-               in_y2, 
-               in_total_y,  
-               output->get_h(),  
-               out_y1_int, 
-               out_y2_int); 
-       switch(engine->translate_input->get_color_model())
-       {
-               case BC_RGB888:
-               case BC_YUV888:
-                       TRANSLATE(0xff, unsigned char, 3);
-                       break;
-
-               case BC_RGBA8888:
-               case BC_YUVA8888:
-                       TRANSLATE(0xff, unsigned char, 4);
-                       break;
-
-               case BC_RGB161616:
-               case BC_YUV161616:
-                       TRANSLATE(0xffff, uint16_t, 3);
-                       break;
-
-               case BC_RGBA16161616:
-               case BC_YUVA16161616:
-                       TRANSLATE(0xffff, uint16_t, 4);
-                       break;
-       }
-       delete [] x_table; 
-       delete [] y_table; 
-}
-
-
-
-
-
-
-
-
-
-
-TranslateEngine::TranslateEngine(OverlayFrame *overlay, int cpus)
- : LoadServer(cpus, cpus)
-{
-       this->overlay = overlay;
-}
-
-TranslateEngine::~TranslateEngine()
-{
-}
-
-void TranslateEngine::init_packages()
-{
-       int out_y1_int = (int)translate_out_y1;
-       int out_y2_int = MIN((int)ceil(translate_out_y2), translate_output->get_h());
-       int out_h = out_y2_int - out_y1_int;
-
-       for(int i = 0; i < total_packages; i++)
-       {
-               TranslatePackage *package = (TranslatePackage*)packages[i];
-               package->out_row1 = (int)(out_y1_int + out_h / 
-                       total_packages * 
-                       i);
-               package->out_row2 = (int)((float)package->out_row1 + 
-                       out_h / 
-                       total_packages);
-               if(i >= total_packages - 1)
-                       package->out_row2 = out_y2_int;
-       }
-}
-
-LoadClient* TranslateEngine::new_client()
-{
-       return new TranslateUnit(this, overlay);
-}
-
-LoadPackage* TranslateEngine::new_package()
-{
-       return new TranslatePackage;
-}
-
-
-
-
-
-
-
-
-#define SCALE_TRANSLATE(max, type, components) \
-{ \
-       int64_t opacity = (int)(alpha * max + 0.5); \
-       int64_t transparency = max - opacity; \
-       int out_w = out_x2 - out_x1; \
- \
-       for(int i = pkg->out_row1; i < pkg->out_row2; i++) \
-       { \
-               int in_y = y_table[i - out_y1]; \
-               type *in_row = (type*)in_rows[in_y] + in_x1 * components; \
-               type *out_row = (type*)out_rows[i] + out_x1 * components; \
- \
-/* X direction is scaled and requires a table lookup */ \
-               if(out_w != in_x2 - in_x1) \
-               { \
-                       for(int j = 0; j < out_w; j++) \
-                       { \
-                               int in_x = x_table[j]; \
-                               int input1, input2, input3, input4; \
-                               type *output = out_row + j * components; \
-        \
-                               input1 = in_row[in_x * components]; \
-                               input2 = in_row[in_x * components + 1]; \
-                               input3 = in_row[in_x * components + 2]; \
-                               if(components == 4) \
-                                       input4 = in_row[in_x * components + 3]; \
-        \
-                               if(components == 3) \
-                               { \
-                                       BLEND_3(max, type); \
-                               } \
-                               else \
-                               { \
-                                       BLEND_4(max, type); \
-                               } \
-                       } \
-               } \
-               else \
-/* X direction is not scaled */ \
-               { \
-                       for(int j = 0; j < out_w; j++) \
-                       { \
-                               int input1, input2, input3, input4; \
-                               type *output = out_row + j * components; \
-        \
-                               input1 = in_row[j * components]; \
-                               input2 = in_row[j * components + 1]; \
-                               input3 = in_row[j * components + 2]; \
-                               if(components == 4) \
-                                       input4 = in_row[j * components + 3]; \
-        \
-                               if(components == 3) \
-                               { \
-                                       BLEND_3(max, type); \
-                               } \
-                               else \
-                               { \
-                                       BLEND_4(max, type); \
-                               } \
-                       } \
-               } \
-       } \
-}
-
-
-
-ScaleTranslateUnit::ScaleTranslateUnit(ScaleTranslateEngine *server, OverlayFrame *overlay)
- : LoadClient(server)
-{
-       this->overlay = overlay;
-       this->scale_translate = server;
-}
-
-ScaleTranslateUnit::~ScaleTranslateUnit()
-{
-}
-
-void ScaleTranslateUnit::scale_array(int* &table, 
-       int out_x1, 
-       int out_x2,
-       int in_x1,
-       int in_x2,
-       int is_x)
-{
-       float scale = (float)(out_x2 - out_x1) / (in_x2 - in_x1);
-
-       table = new int[out_x2 - out_x1];
-       
-       if(!is_x)
-       {
-               for(int i = 0; i < out_x2 - out_x1; i++)
-               {
-                       table[i] = (int)((float)i / scale + in_x1);
-               }
-       }
-       else
-       {       
-               for(int i = 0; i < out_x2 - out_x1; i++)
-               {
-                       table[i] = (int)((float)i / scale);
-               }
-       }
-}
-
-
-void ScaleTranslateUnit::process_package(LoadPackage *package)
-{
-       ScaleTranslatePackage *pkg = (ScaleTranslatePackage*)package;
-
-// Args for NEAREST_NEIGHBOR_MACRO
-       VFrame *output = scale_translate->output;
-       VFrame *input = scale_translate->input;
-       int in_x1 = scale_translate->in_x1;
-       int in_y1 = scale_translate->in_y1;
-       int in_x2 = scale_translate->in_x2;
-       int in_y2 = scale_translate->in_y2;
-       int out_x1 = scale_translate->out_x1;
-       int out_y1 = scale_translate->out_y1;
-       int out_x2 = scale_translate->out_x2;
-       int out_y2 = scale_translate->out_y2;
-       float alpha = scale_translate->alpha;
-       int mode = scale_translate->mode;
-
-       int *x_table;
-       int *y_table;
-       unsigned char **in_rows = input->get_rows();
-       unsigned char **out_rows = output->get_rows();
-
-       scale_array(x_table, 
-               out_x1, 
-               out_x2,
-               in_x1,
-               in_x2,
-               1);
-       scale_array(y_table, 
-               out_y1, 
-               out_y2,
-               in_y1,
-               in_y2,
-               0);
-
-
-       switch(input->get_color_model())
-       {
-               case BC_RGB888:
-               case BC_YUV888:
-                       SCALE_TRANSLATE(0xff, uint8_t, 3);
-                       break;
-
-               case BC_RGBA8888:
-               case BC_YUVA8888:
-                       SCALE_TRANSLATE(0xff, uint8_t, 4);
-                       break;
-
-
-               case BC_RGB161616:
-               case BC_YUV161616:
-                       SCALE_TRANSLATE(0xffff, uint16_t, 3);
-                       break;
-
-               case BC_RGBA16161616:
-               case BC_YUVA16161616:
-                       SCALE_TRANSLATE(0xffff, uint16_t, 4);
-                       break;
-       }
-       
-       delete [] x_table;
-       delete [] y_table;
-
-};
-
-
-
-
-
-
-
-
-
-ScaleTranslateEngine::ScaleTranslateEngine(OverlayFrame *overlay, int cpus)
- : LoadServer(cpus, cpus)
-{
-       this->overlay = overlay;
-}
-
-ScaleTranslateEngine::~ScaleTranslateEngine()
-{
-}
-
-void ScaleTranslateEngine::init_packages()
-{
-       int out_h = out_y2 - out_y1;
-
-       for(int i = 0; i < total_packages; i++)
-       {
-               ScaleTranslatePackage *package = (ScaleTranslatePackage*)packages[i];
-               package->out_row1 = (int)(out_y1 + out_h / 
-                       total_packages * 
-                       i);
-               package->out_row2 = (int)((float)package->out_row1 + 
-                       out_h / 
-                       total_packages);
-               if(i >= total_packages - 1)
-                       package->out_row2 = out_y2;
-       }
-}
-
-LoadClient* ScaleTranslateEngine::new_client()
-{
-       return new ScaleTranslateUnit(this, overlay);
-}
-
-LoadPackage* ScaleTranslateEngine::new_package()
-{
-       return new ScaleTranslatePackage;
-}
-
-
-ScaleTranslatePackage::ScaleTranslatePackage()
-{
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#define BLEND_ONLY(type, max, components) \
-{ \
-       int64_t opacity = (int)(alpha * max + 0.5); \
-       int64_t transparency = max - opacity; \
- \
-       type** output_rows = (type**)output->get_rows(); \
-       type** input_rows = (type**)input->get_rows(); \
-       int w = input->get_w(); \
-       int h = input->get_h(); \
- \
-       for(int i = pkg->out_row1; i < pkg->out_row2; i++) \
-       { \
-               type* in_row = input_rows[i]; \
-               type* output = output_rows[i]; \
- \
-               for(int j = 0; j < w; j++) \
-               { \
-                       int input1, input2, input3, input4; \
-                       input1 = in_row[j * components]; \
-                       input2 = in_row[j * components + 1]; \
-                       input3 = in_row[j * components + 2]; \
-                       if(components == 4) input4 = in_row[j * components + 3]; \
- \
- \
-                       if(components == 3) \
-                       { \
-                               BLEND_3(max, type); \
-                       } \
-                       else \
-                       { \
-                               BLEND_4(max, type); \
-                       } \
- \
-                       input += components; \
-                       output += components; \
-               } \
-       } \
-}
-
-
-
-
-BlendUnit::BlendUnit(BlendEngine *server, OverlayFrame *overlay)
- : LoadClient(server)
-{
-       this->overlay = overlay;
-       this->blend_engine = server;
-}
-
-BlendUnit::~BlendUnit()
-{
-}
-
-void BlendUnit::process_package(LoadPackage *package)
-{
-       BlendPackage *pkg = (BlendPackage*)package;
-
-
-       VFrame *output = blend_engine->output;
-       VFrame *input = blend_engine->input;
-       float alpha = blend_engine->alpha;
-       int mode = blend_engine->mode;
-
-       switch(input->get_color_model())
-       {
-               case BC_RGB888:
-               case BC_YUV888:
-                       BLEND_ONLY(unsigned char, 0xff, 3);
-                       break;
-               case BC_RGBA8888:
-               case BC_YUVA8888:
-                       BLEND_ONLY(unsigned char, 0xff, 4);
-                       break;
-               case BC_RGB161616:
-               case BC_YUV161616:
-                       BLEND_ONLY(uint16_t, 0xffff, 3);
-                       break;
-               case BC_RGBA16161616:
-               case BC_YUVA16161616:
-                       BLEND_ONLY(uint16_t, 0xffff, 4);
-                       break;
-       }
-}
-
-
-
-BlendEngine::BlendEngine(OverlayFrame *overlay, int cpus)
- : LoadServer(cpus, cpus)
-{
-       this->overlay = overlay;
-}
-
-BlendEngine::~BlendEngine()
-{
-}
-
-void BlendEngine::init_packages()
-{
-       for(int i = 0; i < total_packages; i++)
-       {
-               BlendPackage *package = (BlendPackage*)packages[i];
-               package->out_row1 = (int)(input->get_h() / 
-                       total_packages * 
-                       i);
-               package->out_row2 = (int)((float)package->out_row1 +
-                       input->get_h() / 
-                       total_packages);
-
-               if(i >= total_packages - 1)
-                       package->out_row2 = input->get_h();
-       }
-}
-
-LoadClient* BlendEngine::new_client()
-{
-       return new BlendUnit(this, overlay);
-}
-
-LoadPackage* BlendEngine::new_package()
-{
-       return new BlendPackage;
-}
-
-
-BlendPackage::BlendPackage()
-{
-}
-
-
diff --git a/cinelerra-5.1/cinelerra/overlayframe.C.int b/cinelerra-5.1/cinelerra/overlayframe.C.int
deleted file mode 100644 (file)
index f241c1f..0000000
+++ /dev/null
@@ -1,1749 +0,0 @@
-#include <math.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-
-#include "clip.h"
-#include "edl.inc"
-#include "mutex.h"
-#include "overlayframe.h"
-#include "vframe.h"
-
-OverlayFrame::OverlayFrame(int cpus)
-{
-       temp_frame = 0;
-       blend_engine = 0;
-       scale_engine = 0;
-       scaletranslate_engine = 0;
-       translate_engine = 0;
-       this->cpus = cpus;
-}
-
-OverlayFrame::~OverlayFrame()
-{
-//printf("OverlayFrame::~OverlayFrame 1\n");
-       if(temp_frame) delete temp_frame;
-       if(scale_engine) delete scale_engine;
-       if(translate_engine) delete translate_engine;
-       if(blend_engine) delete blend_engine;
-       if(scaletranslate_engine) delete scaletranslate_engine;
-//printf("OverlayFrame::~OverlayFrame 2\n");
-}
-
-
-
-
-
-
-
-
-// Verification: 
-
-// (255 * 255 + 0 * 0) / 255 = 255
-// (255 * 127 + 255 * (255 - 127)) / 255 = 255
-
-// (65535 * 65535 + 0 * 0) / 65535 = 65535
-// (65535 * 32767 + 65535 * (65535 - 32767)) / 65535 = 65535
-
-
-// Branch prediction 4 U
-
-#define BLEND_3(max, type) \
-{ \
-       int64_t r, g, b; \
- \
-/* if(mode != TRANSFER_NORMAL) printf("BLEND mode = %d\n", mode); */ \
-       switch(mode) \
-       { \
-               case TRANSFER_DIVIDE: \
-                       r = output[0] ? (((int64_t)input1 * max) / output[0]) : max; \
-                       g = output[1] ? (((int64_t)input2 * max) / output[1]) : max; \
-                       b = output[2] ? (((int64_t)input3 * max) / output[2]) : max; \
-                       r = (r * opacity + output[0] * transparency) / max; \
-                       g = (g * opacity + output[1] * transparency) / max; \
-                       b = (b * opacity + output[2] * transparency) / max; \
-                       break; \
-               case TRANSFER_MULTIPLY: \
-                       r = ((int64_t)input1 * output[0]) / max; \
-                       g = ((int64_t)input2 * output[1]) / max; \
-                       b = ((int64_t)input3 * output[2]) / max; \
-                       r = (r * opacity + output[0] * transparency) / max; \
-                       g = (g * opacity + output[1] * transparency) / max; \
-                       b = (b * opacity + output[2] * transparency) / max; \
-                       break; \
-               case TRANSFER_SUBTRACT: \
-                       r = (((int64_t)input1 - output[0]) * opacity + output[0] * transparency) / max; \
-                       g = (((int64_t)input2 - output[1]) * opacity + output[1] * transparency) / max; \
-                       b = (((int64_t)input3 - output[2]) * opacity + output[2] * transparency) / max; \
-                       break; \
-               case TRANSFER_ADDITION: \
-                       r = (((int64_t)input1 + output[0]) * opacity + output[0] * transparency) / max; \
-                       g = (((int64_t)input2 + output[1]) * opacity + output[1] * transparency) / max; \
-                       b = (((int64_t)input3 + output[2]) * opacity + output[2] * transparency) / max; \
-                       break; \
-               case TRANSFER_REPLACE: \
-                       r = input1; \
-                       g = input2; \
-                       b = input3; \
-                       break; \
-               case TRANSFER_NORMAL: \
-                       r = ((int64_t)input1 * opacity + output[0] * transparency) / max; \
-                       g = ((int64_t)input2 * opacity + output[1] * transparency) / max; \
-                       b = ((int64_t)input3 * opacity + output[2] * transparency) / max; \
-                       break; \
-       } \
- \
-       output[0] = (type)CLIP(r, 0, max); \
-       output[1] = (type)CLIP(g, 0, max); \
-       output[2] = (type)CLIP(b, 0, max); \
-}
-
-
-
-
-
-// Blending equations are drastically different for 3 and 4 components
-#define BLEND_4(max, type) \
-{ \
-       int64_t r, g, b, a; \
-       int64_t pixel_opacity, pixel_transparency; \
- \
-       pixel_opacity = opacity * input4 / max; \
-       pixel_transparency = (max - pixel_opacity) * output[3] / max; \
- \
-       switch(mode) \
-       { \
-               case TRANSFER_DIVIDE: \
-                       r = output[0] ? (((int64_t)input1 * max) / output[0]) : max; \
-                       g = output[1] ? (((int64_t)input2 * max) / output[1]) : max; \
-                       b = output[2] ? (((int64_t)input3 * max) / output[2]) : max; \
-                       r = (r * pixel_opacity + output[0] * pixel_transparency) / max; \
-                       g = (g * pixel_opacity + output[1] * pixel_transparency) / max; \
-                       b = (b * pixel_opacity + output[2] * pixel_transparency) / max; \
-                       a = input4 > output[3] ? input4 : output[3]; \
-                       break; \
-               case TRANSFER_MULTIPLY: \
-                       r = ((int64_t)input1 * output[0]) / max; \
-                       g = ((int64_t)input2 * output[1]) / max; \
-                       b = ((int64_t)input3 * output[2]) / max; \
-                       r = (r * pixel_opacity + output[0] * pixel_transparency) / max; \
-                       g = (g * pixel_opacity + output[1] * pixel_transparency) / max; \
-                       b = (b * pixel_opacity + output[2] * pixel_transparency) / max; \
-                       a = input4 > output[3] ? input4 : output[3]; \
-                       break; \
-               case TRANSFER_SUBTRACT: \
-                       r = (((int64_t)input1 - output[0]) * pixel_opacity + output[0] * pixel_transparency) / max; \
-                       g = (((int64_t)input2 - output[1]) * pixel_opacity + output[1] * pixel_transparency) / max; \
-                       b = (((int64_t)input3 - output[2]) * pixel_opacity + output[2] * pixel_transparency) / max; \
-                       a = input4 > output[3] ? input4 : output[3]; \
-                       break; \
-               case TRANSFER_ADDITION: \
-                       r = (((int64_t)input1 + output[0]) * pixel_opacity + output[0] * pixel_transparency) / max; \
-                       g = (((int64_t)input2 + output[1]) * pixel_opacity + output[1] * pixel_transparency) / max; \
-                       b = (((int64_t)input3 + output[2]) * pixel_opacity + output[2] * pixel_transparency) / max; \
-                       a = input4 > output[3] ? input4 : output[3]; \
-                       break; \
-               case TRANSFER_REPLACE: \
-                       r = input1; \
-                       g = input2; \
-                       b = input3; \
-                       a = input4; \
-                       break; \
-               case TRANSFER_NORMAL: \
-                       r = ((int64_t)input1 * pixel_opacity + output[0] * pixel_transparency) / max; \
-                       g = ((int64_t)input2 * pixel_opacity + output[1] * pixel_transparency) / max; \
-                       b = ((int64_t)input3 * pixel_opacity + output[2] * pixel_transparency) / max; \
-                       a = input4 > output[3] ? input4 : output[3]; \
-                       break; \
-       } \
- \
-       output[0] = (type)CLIP(r, 0, max); \
-       output[1] = (type)CLIP(g, 0, max); \
-       output[2] = (type)CLIP(b, 0, max); \
-       output[3] = (type)a; \
-}
-
-
-
-
-
-
-
-
-// Bicubic algorithm using multiprocessors
-// input -> scale nearest integer boundaries -> temp -> translation -> blend -> output
-
-// Nearest neighbor algorithm using multiprocessors for blending
-// input -> scale + translate -> blend -> output
-
-
-int OverlayFrame::overlay(VFrame *output, 
-       VFrame *input, 
-       float in_x1, 
-       float in_y1, 
-       float in_x2, 
-       float in_y2, 
-       float out_x1, 
-       float out_y1, 
-       float out_x2, 
-       float out_y2, 
-       float alpha,       // 0 - 1
-       int mode,
-       int interpolation_type)
-{
-       float w_scale = (out_x2 - out_x1) / (in_x2 - in_x1);
-       float h_scale = (out_y2 - out_y1) / (in_y2 - in_y1);
-
-//printf("OverlayFrame::overlay 1 %d %f\n", mode, alpha);
-// Limit values
-       if(in_x1 < 0)
-       {
-               out_x1 += -in_x1 * w_scale;
-               in_x1 = 0;
-       }
-       else
-       if(in_x1 >= input->get_w())
-       {
-               out_x1 -= (in_x1 - input->get_w()) * w_scale;
-               in_x1 = input->get_w();
-       }
-
-       if(in_y1 < 0)
-       {
-               out_y1 += -in_y1 * h_scale;
-               in_y1 = 0;
-       }
-       else
-       if(in_y1 >= input->get_h())
-       {
-               out_y1 -= (in_y1 - input->get_h()) * h_scale;
-               in_y1 = input->get_h();
-       }
-
-       if(in_x2 < 0)
-       {
-               out_x2 += -in_x2 * w_scale;
-               in_x2 = 0;
-       }
-       else
-       if(in_x2 >= input->get_w())
-       {
-               out_x2 -= (in_x2 - input->get_w()) * w_scale;
-               in_x2 = input->get_w();
-       }
-
-       if(in_y2 < 0)
-       {
-               out_y2 += -in_y2 * h_scale;
-               in_y2 = 0;
-       }
-       else
-       if(in_y2 >= input->get_h())
-       {
-               out_y2 -= (in_y2 - input->get_h()) * h_scale;
-               in_y2 = input->get_h();
-       }
-
-       if(out_x1 < 0)
-       {
-               in_x1 += -out_x1 / w_scale;
-               out_x1 = 0;
-       }
-       else
-       if(out_x1 >= output->get_w())
-       {
-               in_x1 -= (out_x1 - output->get_w()) / w_scale;
-               out_x1 = output->get_w();
-       }
-
-       if(out_y1 < 0)
-       {
-               in_y1 += -out_y1 / h_scale;
-               out_y1 = 0;
-       }
-       else
-       if(out_y1 >= output->get_h())
-       {
-               in_y1 -= (out_y1 - output->get_h()) / h_scale;
-               out_y1 = output->get_h();
-       }
-
-       if(out_x2 < 0)
-       {
-               in_x2 += -out_x2 / w_scale;
-               out_x2 = 0;
-       }
-       else
-       if(out_x2 >= output->get_w())
-       {
-               in_x2 -= (out_x2 - output->get_w()) / w_scale;
-               out_x2 = output->get_w();
-       }
-
-       if(out_y2 < 0)
-       {
-               in_y2 += -out_y2 / h_scale;
-               out_y2 = 0;
-       }
-       else
-       if(out_y2 >= output->get_h())
-       {
-               in_y2 -= (out_y2 - output->get_h()) / h_scale;
-               out_y2 = output->get_h();
-       }
-
-
-
-
-
-       float in_w = in_x2 - in_x1;
-       float in_h = in_y2 - in_y1;
-       float out_w = out_x2 - out_x1;
-       float out_h = out_y2 - out_y1;
-// Input for translation operation
-       VFrame *translation_input = input;
-
-
-
-// printf("OverlayFrame::overlay %f %f %f %f -> %f %f %f %f\n", in_x1,
-//                     in_y1,
-//                     in_x2,
-//                     in_y2,
-//                     out_x1,
-//                     out_y1,
-//                     out_x2,
-//                     out_y2);
-
-
-
-
-
-// ****************************************************************************
-// Transfer to temp buffer by scaling nearest integer boundaries
-// ****************************************************************************
-       if(interpolation_type != NEAREST_NEIGHBOR &&
-               (!EQUIV(w_scale, 1) || !EQUIV(h_scale, 1)))
-       {
-// Create integer boundaries for interpolation
-               int in_x1_int = (int)in_x1;
-               int in_y1_int = (int)in_y1;
-               int in_x2_int = MIN((int)ceil(in_x2), input->get_w());
-               int in_y2_int = MIN((int)ceil(in_y2), input->get_h());
-
-// Dimensions of temp frame.  Integer boundaries scaled.
-               int temp_w = (int)ceil(w_scale * (in_x2_int - in_x1_int));
-               int temp_h = (int)ceil(h_scale * (in_y2_int - in_y1_int));
-               VFrame *scale_output;
-
-
-
-#define NO_TRANSLATION1 \
-       (EQUIV(in_x1, 0) && \
-       EQUIV(in_y1, 0) && \
-       EQUIV(out_x1, 0) && \
-       EQUIV(out_y1, 0) && \
-       EQUIV(in_x2, in_x2_int) && \
-       EQUIV(in_y2, in_y2_int) && \
-       EQUIV(out_x2, temp_w) && \
-       EQUIV(out_y2, temp_h))
-
-
-#define NO_BLEND \
-       (EQUIV(alpha, 1) && \
-       (mode == TRANSFER_REPLACE || \
-       (mode == TRANSFER_NORMAL && cmodel_components(input->get_color_model()) == 3)))
-
-
-
-
-
-// Prepare destination for operation
-
-// No translation and no blending.  The blending operation is built into the
-// translation unit but not the scaling unit.
-// input -> output
-               if(NO_TRANSLATION1 &&
-                       NO_BLEND)
-               {
-// printf("OverlayFrame::overlay input -> output\n");
-
-                       scale_output = output;
-                       translation_input = 0;
-               }
-               else
-// If translation or blending
-// input -> nearest integer boundary temp
-               {
-                       if(temp_frame && 
-                               (temp_frame->get_w() != temp_w ||
-                                       temp_frame->get_h() != temp_h))
-                       {
-                               delete temp_frame;
-                               temp_frame = 0;
-                       }
-
-                       if(!temp_frame)
-                       {
-                               temp_frame = new VFrame(0,
-                                       temp_w,
-                                       temp_h,
-                                       input->get_color_model(),
-                                       -1);
-                       }
-//printf("OverlayFrame::overlay input -> temp\n");
-
-
-                       temp_frame->clear_frame();
-
-// printf("OverlayFrame::overlay 4 temp_w=%d temp_h=%d\n",
-//     temp_w, temp_h);
-                       scale_output = temp_frame;
-                       translation_input = scale_output;
-
-// Adjust input coordinates to reflect new scaled coordinates.
-                       in_x1 = (in_x1 - in_x1_int) * w_scale;
-                       in_y1 = (in_y1 - in_y1_int) * h_scale;
-                       in_x2 = (in_x2 - in_x1_int) * w_scale;
-                       in_y2 = (in_y2 - in_y1_int) * h_scale;
-               }
-
-
-
-
-// Scale input -> scale_output
-               this->scale_output = scale_output;
-               this->scale_input = input;
-               this->w_scale = w_scale;
-               this->h_scale = h_scale;
-               this->in_x1_int = in_x1_int;
-               this->in_y1_int = in_y1_int;
-               this->out_w_int = temp_w;
-               this->out_h_int = temp_h;
-               this->interpolation_type = interpolation_type;
-
-//printf("OverlayFrame::overlay ScaleEngine 1 %d\n", out_h_int);
-               if(!scale_engine) scale_engine = new ScaleEngine(this, cpus);
-               scale_engine->process_packages();
-//printf("OverlayFrame::overlay ScaleEngine 2\n");
-
-
-
-       }
-
-// printf("OverlayFrame::overlay 1  %.2f %.2f %.2f %.2f -> %.2f %.2f %.2f %.2f\n", 
-//     in_x1, 
-//     in_y1, 
-//     in_x2, 
-//     in_y2, 
-//     out_x1, 
-//     out_y1, 
-//     out_x2, 
-//     out_y2);
-
-
-
-
-
-#define NO_TRANSLATION2 \
-       (EQUIV(in_x1, 0) && \
-       EQUIV(in_y1, 0) && \
-       EQUIV(in_x2, translation_input->get_w()) && \
-       EQUIV(in_y2, translation_input->get_h()) && \
-       EQUIV(out_x1, 0) && \
-       EQUIV(out_y1, 0) && \
-       EQUIV(out_x2, output->get_w()) && \
-       EQUIV(out_y2, output->get_h())) \
-
-#define NO_SCALE \
-       (EQUIV(out_x2 - out_x1, in_x2 - in_x1) && \
-       EQUIV(out_y2 - out_y1, in_y2 - in_y1))
-
-       
-
-
-//printf("OverlayFrame::overlay 4 %d\n", mode);
-
-
-
-
-       if(translation_input)
-       {
-// Direct copy
-               if( NO_TRANSLATION2 &&
-                       NO_SCALE &&
-                       NO_BLEND)
-               {
-//printf("OverlayFrame::overlay direct copy\n");
-                       output->copy_from(translation_input);
-               }
-               else
-// Blend only
-               if( NO_TRANSLATION2 &&
-                       NO_SCALE)
-               {
-                       if(!blend_engine) blend_engine = new BlendEngine(this, cpus);
-
-
-                       blend_engine->output = output;
-                       blend_engine->input = translation_input;
-                       blend_engine->alpha = alpha;
-                       blend_engine->mode = mode;
-
-                       blend_engine->process_packages();
-               }
-               else
-// Scale and translate using nearest neighbor
-// Translation is exactly on integer boundaries
-               if(interpolation_type == NEAREST_NEIGHBOR ||
-                       EQUIV(in_x1, (int)in_x1) &&
-                       EQUIV(in_y1, (int)in_y1) &&
-                       EQUIV(in_x2, (int)in_x2) &&
-                       EQUIV(in_y2, (int)in_y2) &&
-
-                       EQUIV(out_x1, (int)out_x1) &&
-                       EQUIV(out_y1, (int)out_y1) &&
-                       EQUIV(out_x2, (int)out_x2) &&
-                       EQUIV(out_y2, (int)out_y2))
-               {
-//printf("OverlayFrame::overlay NEAREST_NEIGHBOR 1\n");
-                       if(!scaletranslate_engine) scaletranslate_engine = new ScaleTranslateEngine(this, cpus);
-
-
-                       scaletranslate_engine->output = output;
-                       scaletranslate_engine->input = translation_input;
-                       scaletranslate_engine->in_x1 = (int)in_x1;
-                       scaletranslate_engine->in_y1 = (int)in_y1;
-                       scaletranslate_engine->in_x2 = (int)in_x2;
-                       scaletranslate_engine->in_y2 = (int)in_y2;
-                       scaletranslate_engine->out_x1 = (int)out_x1;
-                       scaletranslate_engine->out_y1 = (int)out_y1;
-                       scaletranslate_engine->out_x2 = (int)out_x2;
-                       scaletranslate_engine->out_y2 = (int)out_y2;
-                       scaletranslate_engine->alpha = alpha;
-                       scaletranslate_engine->mode = mode;
-
-                       scaletranslate_engine->process_packages();
-               }
-               else
-// Fractional translation
-               {
-// Use fractional translation
-// printf("OverlayFrame::overlay temp -> output  %.2f %.2f %.2f %.2f -> %.2f %.2f %.2f %.2f\n", 
-//     in_x1, 
-//     in_y1, 
-//     in_x2, 
-//     in_y2, 
-//     out_x1, 
-//     out_y1, 
-//     out_x2, 
-//     out_y2);
-                       this->translate_output = output;
-                       this->translate_input = translation_input;
-                       this->translate_in_x1 = in_x1;
-                       this->translate_in_y1 = in_y1;
-                       this->translate_in_x2 = in_x2;
-                       this->translate_in_y2 = in_y2;
-                       this->translate_out_x1 = out_x1;
-                       this->translate_out_y1 = out_y1;
-                       this->translate_out_x2 = out_x2;
-                       this->translate_out_y2 = out_y2;
-                       this->translate_alpha = alpha;
-                       this->translate_mode = mode;
-
-//printf("OverlayFrame::overlay 5 %d\n", mode);
-                       if(!translate_engine) translate_engine = new TranslateEngine(this, cpus);
-                       translate_engine->process_packages();
-
-               }
-       }
-//printf("OverlayFrame::overlay 2\n");
-
-       return 0;
-}
-
-
-
-
-
-
-
-ScalePackage::ScalePackage()
-{
-}
-
-
-
-
-ScaleUnit::ScaleUnit(ScaleEngine *server, OverlayFrame *overlay)
- : LoadClient(server)
-{
-       this->overlay = overlay;
-}
-
-ScaleUnit::~ScaleUnit()
-{
-}
-
-
-
-#define BILINEAR(max, type, components) \
-{ \
-       float k_y = 1.0 / scale_h; \
-       float k_x = 1.0 / scale_w; \
-       type **in_rows = (type**)input->get_rows(); \
-       type **out_rows = (type**)output->get_rows(); \
-       type zero_r, zero_g, zero_b, zero_a; \
-       int in_h_int = input->get_h(); \
-       int in_w_int = input->get_w(); \
-       int *table_int_x, *table_int_y; \
-       int *table_frac_x, *table_frac_y; \
- \
-       zero_r = 0; \
-       zero_g = ((max + 1) >> 1) * (do_yuv); \
-       zero_b = ((max + 1) >> 1) * (do_yuv); \
-       if(components == 4) zero_a = 0; \
- \
-       tabulate_blinear(table_int_x, table_frac_x, k_x, 0, out_w_int); \
-       tabulate_blinear(table_int_y, table_frac_y, k_y, pkg->out_row1, pkg->out_row2); \
- \
-       for(int i = pkg->out_row1; i < pkg->out_row2; i++) \
-       { \
-               int i_y = table_int_y[i - pkg->out_row1]; \
-               uint64_t a = table_frac_y[i - pkg->out_row1]; \
-        uint64_t anti_a = 0xffff - a; \
-               type *in_row1 = in_rows[i_y + in_y1_int]; \
-               type *in_row2 = (i_y + in_y1_int < in_h_int - 1) ?  \
-                       in_rows[i_y + in_y1_int + 1] : \
-                       0; \
-               type *out_row = out_rows[i]; \
- \
-               for(int j = 0; j < out_w_int; j++) \
-               { \
-                       int i_x = table_int_x[j]; \
-                       uint64_t b = table_frac_x[j]; \
-                       uint64_t anti_b = 0xffff - b; \
-                       int x = i_x + in_x1_int; \
-                       uint64_t output1r, output1g, output1b, output1a; \
-                       uint64_t output2r, output2g, output2b, output2a; \
-                       uint64_t output3r, output3g, output3b, output3a; \
-                       uint64_t output4r, output4g, output4b, output4a; \
- \
-                       output1r = in_row1[x * components]; \
-                       output1g = in_row1[x * components + 1]; \
-                       output1b = in_row1[x * components + 2]; \
-                       if(components == 4) output1a = in_row1[x * components + 3]; \
- \
-                       if(x < in_w_int - 1) \
-                       { \
-                               output2r = in_row1[x * components + components]; \
-                               output2g = in_row1[x * components + components + 1]; \
-                               output2b = in_row1[x * components + components + 2]; \
-                               if(components == 4) output2a = in_row1[x * components + components + 3]; \
- \
-                               if(in_row2) \
-                               { \
-                                       output4r = in_row2[x * components + components]; \
-                                       output4g = in_row2[x * components + components + 1]; \
-                                       output4b = in_row2[x * components + components + 2]; \
-                                       if(components == 4) output4a = in_row2[x * components + components + 3]; \
-                               } \
-                               else \
-                               { \
-                                       output4r = zero_r; \
-                                       output4g = zero_g; \
-                                       output4b = zero_b; \
-                                       if(components == 4) output4a = zero_a; \
-                               } \
-                       } \
-                       else \
-                       { \
-                               output2r = zero_r; \
-                               output2g = zero_g; \
-                               output2b = zero_b; \
-                               if(components == 4) output2a = zero_a; \
-                               output4r = zero_r; \
-                               output4g = zero_g; \
-                               output4b = zero_b; \
-                               if(components == 4) output4a = zero_a; \
-                       } \
- \
-                       if(in_row2) \
-                       { \
-                               output3r = in_row2[x * components]; \
-                               output3g = in_row2[x * components + 1]; \
-                               output3b = in_row2[x * components + 2]; \
-                               if(components == 4) output3a = in_row2[x * components + 3]; \
-                       } \
-                       else \
-                       { \
-                               output3r = zero_r; \
-                               output3g = zero_g; \
-                               output3b = zero_b; \
-                               if(components == 4) output3a = zero_a; \
-                       } \
- \
-                       out_row[j * components] =  \
-                               (type)(((anti_a) * (((anti_b) * output1r) +  \
-                               (b * output2r)) +  \
-                a * (((anti_b) * output3r) +  \
-                               (b * output4r))) / 0xffffffff); \
-                       out_row[j * components + 1] =   \
-                               (type)(((anti_a) * (((anti_b) * output1g) +  \
-                               (b * output2g)) +  \
-                a * (((anti_b) * output3g) +  \
-                               (b * output4g))) / 0xffffffff); \
-                       out_row[j * components + 2] =   \
-                               (type)(((anti_a) * (((anti_b) * output1b) +  \
-                               (b * output2b)) +  \
-                a * (((anti_b) * output3b) +  \
-                               (b * output4b))) / 0xffffffff); \
-                       if(components == 4) \
-                               out_row[j * components + 3] =   \
-                                       (type)(((anti_a) * (((anti_b) * output1a) +  \
-                                       (b * output2a)) +  \
-                       a * (((anti_b) * output3a) +  \
-                                       (b * output4a))) / 0xffffffff); \
-               } \
-       } \
- \
- \
-       delete [] table_int_x; \
-       delete [] table_frac_x; \
-       delete [] table_int_y; \
-       delete [] table_frac_y; \
- \
-}
-
-
-#define BICUBIC(max, type, components) \
-{ \
-       float k_y = 1.0 / scale_h; \
-       float k_x = 1.0 / scale_w; \
-       type **in_rows = (type**)input->get_rows(); \
-       type **out_rows = (type**)output->get_rows(); \
-       int *bspline_x, *bspline_y; \
-       int in_h_int = input->get_h(); \
-       int in_w_int = input->get_w(); \
-       type zero_r, zero_g, zero_b, zero_a; \
- \
-       zero_r = 0; \
-       zero_b = ((max + 1) >> 1) * (do_yuv); \
-       zero_g = ((max + 1) >> 1) * (do_yuv); \
-       if(components == 4) \
-               zero_a = 0; \
- \
-       tabulate_bspline(bspline_x,  \
-               k_x, \
-               out_w_int, \
-               -1); \
- \
-       tabulate_bspline(bspline_y,  \
-               k_y, \
-               out_h_int, \
-               1); \
- \
-       for(int i = pkg->out_row1; i < pkg->out_row2; i++) \
-       { \
-               int i_y = (int)(k_y * i); \
- \
- \
-               for(int j = 0; j < out_w_int; j++) \
-               { \
-                       int i_x = (int)(k_x * j); \
-                       uint64_t output1, output2, output3, output4; \
-                       output1 = 0; \
-                       output2 = 0; \
-                       output3 = 0; \
-                       if(components == 4) \
-                               output4 = 0; \
-                       int table_y = i * 4; \
- \
-/* Kernel */ \
-                       for(int m = -1; m < 3; m++) \
-                       { \
-                               uint64_t r1 = bspline_y[table_y++]; \
-                               int y = in_y1_int + i_y + m; \
-                               int table_x = j * 4; \
- \
-                               for(int n = -1; n < 3; n++) \
-                               { \
-                                       uint64_t r2 = bspline_x[table_x++]; \
-                                       int x = in_x1_int + i_x + n; \
-                                       uint64_t r_square = r1 * r2; \
- \
-/* Inside boundary. */ \
-                                       if(x >= 0 && \
-                                               x < in_w_int && \
-                                               y >= 0 && \
-                                               y < in_h_int) \
-                                       { \
-                                               output1 += r_square * in_rows[y][x * components]; \
-                                               output2 += r_square * in_rows[y][x * components + 1]; \
-                                               output3 += r_square * in_rows[y][x * components + 2]; \
-                                               if(components == 4) \
-                                                       output4 += r_square * in_rows[y][x * components + 3]; \
-                                       } \
-                                       else \
-                                       { \
-                                               output1 += r_square * zero_r; \
-                                               output2 += r_square * zero_g; \
-                                               output3 += r_square * zero_b; \
-                                               if(components == 4) \
-                                                       output4 += r_square * zero_a; \
-                                       } \
-                               } \
-                       } \
- \
- \
-                       out_rows[i][j * components] = (type)(output1 / 0xffffffff); \
-                       out_rows[i][j * components + 1] = (type)(output2 / 0xffffffff); \
-                       out_rows[i][j * components + 2] = (type)(output3 / 0xffffffff); \
-                       if(components == 4) \
-                               out_rows[i][j * components + 3] = (type)(output4 / 0xffffffff); \
- \
-               } \
-       } \
- \
-       delete [] bspline_x; \
-       delete [] bspline_y; \
-}
-
-
-
-
-// Pow function is not thread safe in Compaqt C
-#define CUBE(x) ((x) * (x) * (x))
-
-int ScaleUnit::cubic_bspline(float x)
-{
-       float a, b, c, d;
-
-       if((x + 2.0F) <= 0.0F) 
-       {
-       a = 0.0F;
-       }
-       else 
-       {
-       a = CUBE(x + 2.0F);
-       }
-
-
-       if((x + 1.0F) <= 0.0F) 
-       {
-       b = 0.0F;
-       }
-       else 
-       {
-       b = CUBE(x + 1.0F);
-       }    
-
-       if(x <= 0) 
-       {
-       c = 0.0F;
-       }
-       else 
-       {
-       c = CUBE(x);
-       }  
-
-       if((x - 1.0F) <= 0.0F) 
-       {
-       d = 0.0F;
-       }
-       else 
-       {
-       d = CUBE(x - 1.0F);
-       }
-
-
-       return (int)((a - (4.0F * b) + (6.0F * c) - (4.0F * d)) / 6.0 * 0x10000);
-}
-
-
-void ScaleUnit::tabulate_bspline(int* &table, 
-       float scale,
-       int pixels,
-       float coefficient)
-{
-       table = new int[pixels * 4];
-       for(int i = 0, j = 0; i < pixels; i++)
-       {
-               float f_x = (float)i * scale;
-               float a = f_x - floor(f_x);
-               
-               for(float m = -1; m < 3; m++)
-               {
-                       table[j++] = cubic_bspline(coefficient * (m - a));
-               }
-               
-       }
-}
-
-void ScaleUnit::tabulate_blinear(int* &table_int,
-               int* &table_frac,
-               float scale,
-               int pixel1,
-               int pixel2)
-{
-       table_int = new int[pixel2 - pixel1];
-       table_frac = new int[pixel2 - pixel1];
-
-       for(int i = pixel1, j = 0; i < pixel2; i++, j++)
-       {
-               float f_x = (float)i * scale;
-               int i_x = (int)floor(f_x);
-               int a = (int)((f_x - floor(f_x)) * 0xffff);
-
-               table_int[j] = i_x;
-               table_frac[j] = a;
-       }
-}
-
-void ScaleUnit::process_package(LoadPackage *package)
-{
-       ScalePackage *pkg = (ScalePackage*)package;
-
-// Arguments for macros
-       VFrame *output = overlay->scale_output;
-       VFrame *input = overlay->scale_input;
-       float scale_w = overlay->w_scale;
-       float scale_h = overlay->h_scale;
-       int in_x1_int = overlay->in_x1_int;
-       int in_y1_int = overlay->in_y1_int;
-       int out_h_int = overlay->out_h_int;
-       int out_w_int = overlay->out_w_int;
-       int do_yuv = 
-               (overlay->scale_input->get_color_model() == BC_YUV888 ||
-               overlay->scale_input->get_color_model() == BC_YUVA8888 ||
-               overlay->scale_input->get_color_model() == BC_YUV161616 ||
-               overlay->scale_input->get_color_model() == BC_YUVA16161616);
-
-       if(overlay->interpolation_type == CUBIC_CUBIC || 
-               (overlay->interpolation_type == CUBIC_LINEAR 
-                       && overlay->w_scale > 1 && 
-                       overlay->h_scale > 1))
-       {
-       
-               switch(overlay->scale_input->get_color_model())
-               {
-                       case BC_RGB888:
-                       case BC_YUV888:
-                               BICUBIC(0xff, unsigned char, 3);
-                               break;
-
-                       case BC_RGBA8888:
-                       case BC_YUVA8888:
-                               BICUBIC(0xff, unsigned char, 4);
-                               break;
-
-                       case BC_RGB161616:
-                       case BC_YUV161616:
-                               BICUBIC(0xffff, uint16_t, 3);
-                               break;
-
-                       case BC_RGBA16161616:
-                       case BC_YUVA16161616:
-                               BICUBIC(0xffff, uint16_t, 4);
-                               break;
-               }
-       }
-       else
-// Perform bilinear scaling input -> scale_output
-       {
-               switch(overlay->scale_input->get_color_model())
-               {
-                       case BC_RGB888:
-                       case BC_YUV888:
-                               BILINEAR(0xff, unsigned char, 3);
-                               break;
-
-                       case BC_RGBA8888:
-                       case BC_YUVA8888:
-                               BILINEAR(0xff, unsigned char, 4);
-                               break;
-
-                       case BC_RGB161616:
-                       case BC_YUV161616:
-                               BILINEAR(0xffff, uint16_t, 3);
-                               break;
-
-                       case BC_RGBA16161616:
-                       case BC_YUVA16161616:
-                               BILINEAR(0xffff, uint16_t, 4);
-                               break;
-               }
-       }
-
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-ScaleEngine::ScaleEngine(OverlayFrame *overlay, int cpus)
- : LoadServer(cpus, cpus)
-{
-       this->overlay = overlay;
-}
-
-ScaleEngine::~ScaleEngine()
-{
-}
-
-void ScaleEngine::init_packages()
-{
-       for(int i = 0; i < total_packages; i++)
-       {
-               ScalePackage *package = (ScalePackage*)packages[i];
-               package->out_row1 = overlay->out_h_int / total_packages * i;
-               package->out_row2 = package->out_row1 + overlay->out_h_int / total_packages;
-
-               if(i >= total_packages - 1)
-                       package->out_row2 = overlay->out_h_int;
-       }
-}
-
-LoadClient* ScaleEngine::new_client()
-{
-       return new ScaleUnit(this, overlay);
-}
-
-LoadPackage* ScaleEngine::new_package()
-{
-       return new ScalePackage;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-TranslatePackage::TranslatePackage()
-{
-}
-
-
-
-TranslateUnit::TranslateUnit(TranslateEngine *server, OverlayFrame *overlay)
- : LoadClient(server)
-{
-       this->overlay = overlay;
-}
-
-TranslateUnit::~TranslateUnit()
-{
-}
-
-
-
-void TranslateUnit::translation_array(transfer_table* &table, 
-       float out_x1, 
-       float out_x2,
-       float in_x1,
-       float in_x2,
-       int in_total, 
-       int out_total, 
-       int &out_x1_int,
-       int &out_x2_int)
-{
-       int out_w_int;
-       float offset = out_x1 - in_x1;
-
-       out_x1_int = (int)out_x1;
-       out_x2_int = MIN((int)ceil(out_x2), out_total);
-       out_w_int = out_x2_int - out_x1_int;
-
-       table = new transfer_table[out_w_int];
-       bzero(table, sizeof(transfer_table) * out_w_int);
-
-
-//printf("OverlayFrame::translation_array 1 %f %f -> %f %f\n", in_x1, in_x2, out_x1, out_x2);
-
-       float in_x = in_x1;
-       for(int out_x = out_x1_int; out_x < out_x2_int; out_x++)
-       {
-               transfer_table *entry = &table[out_x - out_x1_int];
-
-               entry->in_x1 = (int)in_x;
-               entry->in_x2 = (int)in_x + 1;
-
-// Get fraction of output pixel to fill
-               entry->output_fraction = 1;
-
-               if(out_x1 > out_x)
-               {
-                       entry->output_fraction -= out_x1 - out_x;
-               }
-
-               if(out_x2 < out_x + 1)
-               {
-                       entry->output_fraction = (out_x2 - out_x);
-               }
-
-// Advance in_x until out_x_fraction is filled
-               float out_x_fraction = entry->output_fraction;
-               float in_x_fraction = floor(in_x + 1) - in_x;
-
-               if(out_x_fraction <= in_x_fraction)
-               {
-                       entry->in_fraction1 = out_x_fraction;
-                       entry->in_fraction2 = 0.0;
-                       in_x += out_x_fraction;
-               }
-               else
-               {
-                       entry->in_fraction1 = in_x_fraction;
-                       in_x += out_x_fraction;
-                       entry->in_fraction2 = in_x - floor(in_x);
-               }
-
-// Clip in_x
-               if(entry->in_x2 >= in_total)
-               {
-                       entry->in_x2 = in_total - 1;
-                       entry->in_fraction2 = 0.0;
-               }
-               
-               if(entry->in_x1 >= in_total)
-               {
-                       entry->in_x1 = in_total - 1;
-                       entry->in_fraction1 = 0.0;
-               }
-// printf("OverlayFrame::translation_array 2 %d %d %d %f %f %f\n", 
-//     out_x, 
-//     entry->in_x1, 
-//     entry->in_x2, 
-//     entry->in_fraction1, 
-//     entry->in_fraction2, 
-//     entry->output_fraction);
-       }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#define TRANSLATE(max, type, components) \
-{ \
- \
-       type **in_rows = (type**)input->get_rows(); \
-       type **out_rows = (type**)output->get_rows(); \
- \
-/* printf("OverlayFrame::translate 1  %.2f %.2f %.2f %.2f -> %.2f %.2f %.2f %.2f\n",  */ \
-/*     (in_x1),  in_y1,  in_x2,  in_y2,  out_x1,  out_y1, out_x2,  out_y2); */ \
- \
-       unsigned int master_opacity = (int)(alpha * max + 0.5); \
-       unsigned int master_transparency = max - master_opacity; \
- \
-/* printf("TRANSLATE %d\n", mode); */ \
- \
-       for(int i = row1; i < row2; i++) \
-       { \
-               int in_y1 = y_table[i - out_y1_int].in_x1; \
-               int in_y2 = y_table[i - out_y1_int].in_x2; \
-               float y_fraction1 = y_table[i - out_y1_int].in_fraction1; \
-               float y_fraction2 = y_table[i - out_y1_int].in_fraction2; \
-               float y_output_fraction = y_table[i - out_y1_int].output_fraction; \
-               type *in_row1 = in_rows[(in_y1)]; \
-               type *in_row2 = in_rows[(in_y2)]; \
-               type *out_row = out_rows[i]; \
- \
-               for(int j = out_x1_int; j < out_x2_int; j++) \
-               { \
-                       int in_x1 = x_table[j - out_x1_int].in_x1; \
-                       int in_x2 = x_table[j - out_x1_int].in_x2; \
-                       float x_fraction1 = x_table[j - out_x1_int].in_fraction1; \
-                       float x_fraction2 = x_table[j - out_x1_int].in_fraction2; \
-                       float x_output_fraction = x_table[j - out_x1_int].output_fraction; \
-                       type *output = &out_row[j * components]; \
-                       int input1, input2, input3, input4; \
- \
-                       input1 = (int)(in_row1[in_x1 * components] * x_fraction1 * y_fraction1 +  \
-                               in_row1[in_x2 * components] * x_fraction2 * y_fraction1 +  \
-                               in_row2[in_x1 * components] * x_fraction1 * y_fraction2 +  \
-                               in_row2[in_x2 * components] * x_fraction2 * y_fraction2 + 0.5); \
-                       input2 = (int)(in_row1[in_x1 * components + 1] * x_fraction1 * y_fraction1 +  \
-                               in_row1[in_x2 * components + 1] * x_fraction2 * y_fraction1 +  \
-                               in_row2[in_x1 * components + 1] * x_fraction1 * y_fraction2 +  \
-                               in_row2[in_x2 * components + 1] * x_fraction2 * y_fraction2 + 0.5); \
-                       input3 = (int)(in_row1[in_x1 * components + 2] * x_fraction1 * y_fraction1 +  \
-                               in_row1[in_x2 * components + 2] * x_fraction2 * y_fraction1 +  \
-                               in_row2[in_x1 * components + 2] * x_fraction1 * y_fraction2 +  \
-                               in_row2[in_x2 * components + 2] * x_fraction2 * y_fraction2 + 0.5); \
-                       if(components == 4) \
-                               input4 = (int)(in_row1[in_x1 * components + 3] * x_fraction1 * y_fraction1 +  \
-                                       in_row1[in_x2 * components + 3] * x_fraction2 * y_fraction1 +  \
-                                       in_row2[in_x1 * components + 3] * x_fraction1 * y_fraction2 +  \
-                                       in_row2[in_x2 * components + 3] * x_fraction2 * y_fraction2 + 0.5); \
- \
-                       unsigned int opacity = (int)(master_opacity *  \
-                               y_output_fraction *  \
-                               x_output_fraction + 0.5); \
-                       unsigned int transparency = max - opacity; \
- \
-/* if(opacity != max) printf("TRANSLATE %x %d %d\n", opacity, j, i); */ \
- \
-                       if(components == 3) \
-                       { \
-                               BLEND_3(max, type); \
-                       } \
-                       else \
-                       { \
-                               BLEND_4(max, type); \
-                       } \
-               } \
-       } \
-}
-
-void TranslateUnit::process_package(LoadPackage *package)
-{
-       TranslatePackage *pkg = (TranslatePackage*)package;
-       int out_y1_int; 
-       int out_y2_int; 
-       int out_x1_int; 
-       int out_x2_int; 
-
-
-// Variables for TRANSLATE
-       VFrame *input = overlay->translate_input;
-       VFrame *output = overlay->translate_output;
-       float in_x1 = overlay->translate_in_x1;
-       float in_y1 = overlay->translate_in_y1;
-       float in_x2 = overlay->translate_in_x2;
-       float in_y2 = overlay->translate_in_y2;
-       float out_x1 = overlay->translate_out_x1;
-       float out_y1 = overlay->translate_out_y1;
-       float out_x2 = overlay->translate_out_x2;
-       float out_y2 = overlay->translate_out_y2;
-       float alpha = overlay->translate_alpha;
-       int row1 = pkg->out_row1;
-       int row2 = pkg->out_row2;
-       int mode = overlay->translate_mode;
-
-       transfer_table *x_table; 
-       transfer_table *y_table; 
-       translation_array(x_table,  
-               out_x1,  
-               out_x2, 
-               in_x1, 
-               in_x2, 
-               input->get_w(),  
-               output->get_w(),  
-               out_x1_int, 
-               out_x2_int); 
-       translation_array(y_table,  
-               out_y1,  
-               out_y2, 
-               in_y1, 
-               in_y2, 
-               input->get_h(),  
-               output->get_h(),  
-               out_y1_int, 
-               out_y2_int); 
-       switch(overlay->translate_input->get_color_model())
-       {
-               case BC_RGB888:
-               case BC_YUV888:
-                       TRANSLATE(0xff, unsigned char, 3);
-                       break;
-
-               case BC_RGBA8888:
-               case BC_YUVA8888:
-                       TRANSLATE(0xff, unsigned char, 4);
-                       break;
-
-               case BC_RGB161616:
-               case BC_YUV161616:
-                       TRANSLATE(0xffff, uint16_t, 3);
-                       break;
-
-               case BC_RGBA16161616:
-               case BC_YUVA16161616:
-                       TRANSLATE(0xffff, uint16_t, 4);
-                       break;
-       }
-       delete [] x_table; 
-       delete [] y_table; 
-}
-
-
-
-
-
-
-
-
-
-
-TranslateEngine::TranslateEngine(OverlayFrame *overlay, int cpus)
- : LoadServer(cpus, cpus)
-{
-       this->overlay = overlay;
-}
-
-TranslateEngine::~TranslateEngine()
-{
-}
-
-void TranslateEngine::init_packages()
-{
-       int out_y1_int = (int)overlay->translate_out_y1;
-       int out_y2_int = MIN((int)ceil(overlay->translate_out_y2), overlay->translate_output->get_h());
-       int out_h = out_y2_int - out_y1_int;
-
-       for(int i = 0; i < total_packages; i++)
-       {
-               TranslatePackage *package = (TranslatePackage*)packages[i];
-               package->out_row1 = (int)(out_y1_int + out_h / 
-                       total_packages * 
-                       i);
-               package->out_row2 = (int)((float)package->out_row1 + 
-                       out_h / 
-                       total_packages);
-               if(i >= total_packages - 1)
-                       package->out_row2 = out_y2_int;
-       }
-}
-
-LoadClient* TranslateEngine::new_client()
-{
-       return new TranslateUnit(this, overlay);
-}
-
-LoadPackage* TranslateEngine::new_package()
-{
-       return new TranslatePackage;
-}
-
-
-
-
-
-
-
-
-#define SCALE_TRANSLATE(max, type, components) \
-{ \
-       int64_t opacity = (int)(alpha * max + 0.5); \
-       int64_t transparency = max - opacity; \
-       int out_w = out_x2 - out_x1; \
- \
-       for(int i = pkg->out_row1; i < pkg->out_row2; i++) \
-       { \
-               int in_y = y_table[i - out_y1]; \
-               type *in_row = (type*)in_rows[in_y] + in_x1 * components; \
-               type *out_row = (type*)out_rows[i] + out_x1 * components; \
- \
-/* X direction is scaled and requires a table lookup */ \
-               if(out_w != in_x2 - in_x1) \
-               { \
-                       for(int j = 0; j < out_w; j++) \
-                       { \
-                               int in_x = x_table[j]; \
-                               int input1, input2, input3, input4; \
-                               type *output = out_row + j * components; \
-        \
-                               input1 = in_row[in_x * components]; \
-                               input2 = in_row[in_x * components + 1]; \
-                               input3 = in_row[in_x * components + 2]; \
-                               if(components == 4) \
-                                       input4 = in_row[in_x * components + 3]; \
-        \
-                               if(components == 3) \
-                               { \
-                                       BLEND_3(max, type); \
-                               } \
-                               else \
-                               { \
-                                       BLEND_4(max, type); \
-                               } \
-                       } \
-               } \
-               else \
-/* X direction is not scaled */ \
-               { \
-                       for(int j = 0; j < out_w; j++) \
-                       { \
-                               int input1, input2, input3, input4; \
-                               type *output = out_row + j * components; \
-        \
-                               input1 = in_row[j * components]; \
-                               input2 = in_row[j * components + 1]; \
-                               input3 = in_row[j * components + 2]; \
-                               if(components == 4) \
-                                       input4 = in_row[j * components + 3]; \
-        \
-                               if(components == 3) \
-                               { \
-                                       BLEND_3(max, type); \
-                               } \
-                               else \
-                               { \
-                                       BLEND_4(max, type); \
-                               } \
-                       } \
-               } \
-       } \
-}
-
-
-
-ScaleTranslateUnit::ScaleTranslateUnit(ScaleTranslateEngine *server, OverlayFrame *overlay)
- : LoadClient(server)
-{
-       this->overlay = overlay;
-       this->scale_translate = server;
-}
-
-ScaleTranslateUnit::~ScaleTranslateUnit()
-{
-}
-
-void ScaleTranslateUnit::scale_array(int* &table, 
-       int out_x1, 
-       int out_x2,
-       int in_x1,
-       int in_x2,
-       int is_x)
-{
-       float scale = (float)(out_x2 - out_x1) / (in_x2 - in_x1);
-
-       table = new int[out_x2 - out_x1];
-       
-       if(!is_x)
-       {
-               for(int i = 0; i < out_x2 - out_x1; i++)
-               {
-                       table[i] = (int)((float)i / scale + in_x1);
-               }
-       }
-       else
-       {       
-               for(int i = 0; i < out_x2 - out_x1; i++)
-               {
-                       table[i] = (int)((float)i / scale);
-               }
-       }
-}
-
-
-void ScaleTranslateUnit::process_package(LoadPackage *package)
-{
-       ScaleTranslatePackage *pkg = (ScaleTranslatePackage*)package;
-
-// Args for NEAREST_NEIGHBOR_MACRO
-       VFrame *output = scale_translate->output;
-       VFrame *input = scale_translate->input;
-       int in_x1 = scale_translate->in_x1;
-       int in_y1 = scale_translate->in_y1;
-       int in_x2 = scale_translate->in_x2;
-       int in_y2 = scale_translate->in_y2;
-       int out_x1 = scale_translate->out_x1;
-       int out_y1 = scale_translate->out_y1;
-       int out_x2 = scale_translate->out_x2;
-       int out_y2 = scale_translate->out_y2;
-       float alpha = scale_translate->alpha;
-       int mode = scale_translate->mode;
-
-       int *x_table;
-       int *y_table;
-       unsigned char **in_rows = input->get_rows();
-       unsigned char **out_rows = output->get_rows();
-
-       scale_array(x_table, 
-               out_x1, 
-               out_x2,
-               in_x1,
-               in_x2,
-               1);
-       scale_array(y_table, 
-               out_y1, 
-               out_y2,
-               in_y1,
-               in_y2,
-               0);
-
-
-       switch(input->get_color_model())
-       {
-               case BC_RGB888:
-               case BC_YUV888:
-                       SCALE_TRANSLATE(0xff, uint8_t, 3);
-                       break;
-
-               case BC_RGBA8888:
-               case BC_YUVA8888:
-                       SCALE_TRANSLATE(0xff, uint8_t, 4);
-                       break;
-
-
-               case BC_RGB161616:
-               case BC_YUV161616:
-                       SCALE_TRANSLATE(0xffff, uint16_t, 3);
-                       break;
-
-               case BC_RGBA16161616:
-               case BC_YUVA16161616:
-                       SCALE_TRANSLATE(0xffff, uint16_t, 4);
-                       break;
-       }
-       
-       delete [] x_table;
-       delete [] y_table;
-
-};
-
-
-
-
-
-
-
-
-
-ScaleTranslateEngine::ScaleTranslateEngine(OverlayFrame *overlay, int cpus)
- : LoadServer(cpus, cpus)
-{
-       this->overlay = overlay;
-}
-
-ScaleTranslateEngine::~ScaleTranslateEngine()
-{
-}
-
-void ScaleTranslateEngine::init_packages()
-{
-       int out_h = out_y2 - out_y1;
-
-       for(int i = 0; i < total_packages; i++)
-       {
-               ScaleTranslatePackage *package = (ScaleTranslatePackage*)packages[i];
-               package->out_row1 = (int)(out_y1 + out_h / 
-                       total_packages * 
-                       i);
-               package->out_row2 = (int)((float)package->out_row1 + 
-                       out_h / 
-                       total_packages);
-               if(i >= total_packages - 1)
-                       package->out_row2 = out_y2;
-       }
-}
-
-LoadClient* ScaleTranslateEngine::new_client()
-{
-       return new ScaleTranslateUnit(this, overlay);
-}
-
-LoadPackage* ScaleTranslateEngine::new_package()
-{
-       return new ScaleTranslatePackage;
-}
-
-
-ScaleTranslatePackage::ScaleTranslatePackage()
-{
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#define BLEND_ONLY(type, max, components) \
-{ \
-       int64_t opacity = (int)(alpha * max + 0.5); \
-       int64_t transparency = max - opacity; \
- \
-       type** output_rows = (type**)output->get_rows(); \
-       type** input_rows = (type**)input->get_rows(); \
-       int w = input->get_w(); \
-       int h = input->get_h(); \
- \
-       for(int i = pkg->out_row1; i < pkg->out_row2; i++) \
-       { \
-               type* in_row = input_rows[i]; \
-               type* output = output_rows[i]; \
- \
-               for(int j = 0; j < w; j++) \
-               { \
-                       int input1, input2, input3, input4; \
-                       input1 = in_row[j * components]; \
-                       input2 = in_row[j * components + 1]; \
-                       input3 = in_row[j * components + 2]; \
-                       if(components == 4) input4 = in_row[j * components + 3]; \
- \
- \
-                       if(components == 3) \
-                       { \
-                               BLEND_3(max, type); \
-                       } \
-                       else \
-                       { \
-                               BLEND_4(max, type); \
-                       } \
- \
-                       input += components; \
-                       output += components; \
-               } \
-       } \
-}
-
-
-
-
-BlendUnit::BlendUnit(BlendEngine *server, OverlayFrame *overlay)
- : LoadClient(server)
-{
-       this->overlay = overlay;
-       this->blend_engine = server;
-}
-
-BlendUnit::~BlendUnit()
-{
-}
-
-void BlendUnit::process_package(LoadPackage *package)
-{
-       BlendPackage *pkg = (BlendPackage*)package;
-
-
-       VFrame *output = blend_engine->output;
-       VFrame *input = blend_engine->input;
-       float alpha = blend_engine->alpha;
-       int mode = blend_engine->mode;
-
-       switch(input->get_color_model())
-       {
-               case BC_RGB888:
-               case BC_YUV888:
-                       BLEND_ONLY(unsigned char, 0xff, 3);
-                       break;
-               case BC_RGBA8888:
-               case BC_YUVA8888:
-                       BLEND_ONLY(unsigned char, 0xff, 4);
-                       break;
-               case BC_RGB161616:
-               case BC_YUV161616:
-                       BLEND_ONLY(uint16_t, 0xffff, 3);
-                       break;
-               case BC_RGBA16161616:
-               case BC_YUVA16161616:
-                       BLEND_ONLY(uint16_t, 0xffff, 4);
-                       break;
-       }
-}
-
-
-
-BlendEngine::BlendEngine(OverlayFrame *overlay, int cpus)
- : LoadServer(cpus, cpus)
-{
-       this->overlay = overlay;
-}
-
-BlendEngine::~BlendEngine()
-{
-}
-
-void BlendEngine::init_packages()
-{
-       for(int i = 0; i < total_packages; i++)
-       {
-               BlendPackage *package = (BlendPackage*)packages[i];
-               package->out_row1 = (int)(input->get_h() / 
-                       total_packages * 
-                       i);
-               package->out_row2 = (int)((float)package->out_row1 +
-                       input->get_h() / 
-                       total_packages);
-
-               if(i >= total_packages - 1)
-                       package->out_row2 = input->get_h();
-       }
-}
-
-LoadClient* BlendEngine::new_client()
-{
-       return new BlendUnit(this, overlay);
-}
-
-LoadPackage* BlendEngine::new_package()
-{
-       return new BlendPackage;
-}
-
-
-BlendPackage::BlendPackage()
-{
-}
-
-
index 7ca03621e6b6df0b91b165e9566fbc263a2074b0..730be3741ed638b54703c530809aeaada999e20e 100644 (file)
 
 #include "loadbalance.h"
 #include "overlayframe.inc"
-#include "vframe.inc"
+#include "vframe.h"
+
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
 
 #define DIRECT_COPY 0
 #define BILINEAR 1
 #define BICUBIC 2
 #define LANCZOS 3
 
+#define STD_ALPHA(mx, Sa, Da) (Sa + Da - (Sa * Da) / mx)
+#define STD_BLEND(mx, Sc, Sa, Dc, Da) ((Sc * (mx - Da) + Dc * (mx - Sa)) / mx)
+
+#define ZERO 0
+#define ONE 1
+#define TWO 2
+
+// NORMAL      [Sa + Da * (1 - Sa), Sc * Sa + Dc * (1 - Sa)])
+#define ALPHA_NORMAL(mx, Sa, Da) (Sa + (Da * (mx - Sa)) / mx)
+#define COLOR_NORMAL(mx, Sc, Sa, Dc, Da) ((Sc * Sa + Dc * (mx - Sa)) / mx)
+#define CHROMA_NORMAL COLOR_NORMAL
+
+// ADDITION    [(Sa + Da), (Sc + Dc)]
+#define ALPHA_ADDITION(mx, Sa, Da) (Sa + Da)
+#define COLOR_ADDITION(mx, Sc, Sa, Dc, Da) (Sc + Dc)
+#define CHROMA_ADDITION COLOR_ADDITION
+
+// SUBTRACT    [(Sa - Da), (Sc - Dc)]
+#define ALPHA_SUBTRACT(mx, Sa, Da) (Sa - Da)
+#define COLOR_SUBTRACT(mx, Sc, Sa, Dc, Da) (Sc - Dc)
+#define CHROMA_SUBTRACT COLOR_SUBTRACT
+
+// MULTIPLY    [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) +  Sc * Dc]
+#define ALPHA_MULTIPLY STD_ALPHA
+#define COLOR_MULTIPLY(mx, Sc, Sa, Dc, Da) (STD_BLEND(mx,Sc,Sa,Dc,Da) + \
+  (Sc * Dc) / mx)
+#define CHROMA_MULTIPLY COLOR_MULTIPLY
+
+// DIVIDE      [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) +  Sc / Dc]
+#define ALPHA_DIVIDE STD_ALPHA
+#define COLOR_DIVIDE(mx, Sc, Sa, Dc, Da) (STD_BLEND(mx,Sc,Sa,Dc,Da) + \
+  (Dc > ZERO ? (Sc * mx) / Dc : ZERO))
+#define CHROMA_DIVIDE COLOR_DIVIDE
+
+// REPLACE     [Sa, Sc] (fade = 1)
+#define ALPHA_REPLACE(mx, Sa, Da) Sa
+#define COLOR_REPLACE(mx, Sc, Sa, Dc, Da) Sc
+#define CHROMA_REPLACE COLOR_REPLACE
+
+// MAX         [max(Sa, Da), MAX(Sc, Dc)]
+#define ALPHA_MAX(mx, Sa, Da) (Sa > Da ? Sa : Da)
+#define COLOR_MAX(mx, Sc, Sa, Dc, Da) (Sc > Dc ? Sc : Dc)
+#define CHROMA_MAX(mx, Sc, Sa, Dc, Da) (mabs(Sc) > mabs(Dc) ? Sc : Dc)
+
+// MIN         [min(Sa, Da), MIN(Sc, Dc)]
+#define ALPHA_MIN(mx, Sa, Da) (Sa < Da ? Sa : Da)
+#define COLOR_MIN(mx, Sc, Sa, Dc, Da) (Sc < Dc ? Sc : Dc)
+#define CHROMA_MIN(mx, Sc, Sa, Dc, Da) (mabs(Sc) < mabs(Dc) ? Sc : Dc)
+
+// DARKEN      [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) +  min(Sc*Da, Dc*Sa)]
+#define ALPHA_DARKEN STD_ALPHA
+#define COLOR_DARKEN(mx, Sc, Sa, Dc, Da) (STD_BLEND(mx,Sc,Sa,Dc,Da) + \
+  mmin(Sc * Da, Dc * Sa) / mx)
+#define CHROMA_DARKEN(mx, Sc, Sa, Dc, Da) (CHROMA_XOR(mx,Sc,Sa,Dc,Da) + \
+  (mabs(Sc * Da) < mabs(Dc * Sa) ? Sc * Da : Dc * Sa) / mx)
+
+// LIGHTEN     [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) +  max(Sc*Da, Dc*Sa)]
+#define ALPHA_LIGHTEN STD_ALPHA
+#define COLOR_LIGHTEN(mx, Sc, Sa, Dc, Da) (STD_BLEND(mx,Sc,Sa,Dc,Da) + \
+  mmax(Sc * Da, Dc * Sa) / mx)
+#define CHROMA_LIGHTEN(mx, Sc, Sa, Dc, Da) (CHROMA_XOR(mx,Sc,Sa,Dc,Da) + \
+  (mabs(Sc * Da) > mabs(Dc * Sa) ? Sc * Da : Dc * Sa) / mx)
+
+// DST         [Da, Dc]
+#define ALPHA_DST(mx, Sa, Da) Da
+#define COLOR_DST(mx, Sc, Sa, Dc, Da) Dc
+#define CHROMA_DST COLOR_DST
+
+// DST_ATOP    [Sa, Sc * (1 - Da) + Dc * Sa]
+#define ALPHA_DST_ATOP(mx, Sa, Da) Sa
+#define COLOR_DST_ATOP(mx, Sc, Sa, Dc, Da) ((Sc * (mx - Da) + Dc * Sa) / mx)
+#define CHROMA_DST_ATOP COLOR_DST_ATOP
+
+// DST_IN      [Da * Sa, Dc * Sa]
+#define ALPHA_DST_IN(mx, Sa, Da) ((Da * Sa) / mx)
+#define COLOR_DST_IN(mx, Sc, Sa, Dc, Da) ((Dc * Sa) / mx)
+#define CHROMA_DST_IN COLOR_DST_IN
+
+// DST_OUT     [Da * (1 - Sa), Dc * (1 - Sa)]
+#define ALPHA_DST_OUT(mx, Sa, Da) (Da * (mx - Sa) / mx)
+#define COLOR_DST_OUT(mx, Sc, Sa, Dc, Da) (Dc * (mx - Sa) / mx)
+#define CHROMA_DST_OUT COLOR_DST_OUT
+
+// DST_OVER    [Sa + Da - Sa*Da, Sc * (1 - Da) + Dc]
+#define ALPHA_DST_OVER STD_ALPHA
+#define COLOR_DST_OVER(mx, Sc, Sa, Dc, Da) (Sc * (mx - Da)/ mx + Dc)
+#define CHROMA_DST_OVER COLOR_DST_OVER
+
+// SRC                 [Sa, Sc]
+#define ALPHA_SRC(mx, Sa, Da) Sa
+#define COLOR_SRC(mx, Sc, Sa, Dc, Da) Sc
+#define CHROMA_SRC COLOR_SRC
+
+// SRC_ATOP    [Da, Sc * Da + Dc * (1 - Sa)]
+#define ALPHA_SRC_ATOP(mx, Sa, Da) Da
+#define COLOR_SRC_ATOP(mx, Sc, Sa, Dc, Da) ((Sc * Da + Dc * (mx - Sa)) / mx)
+#define CHROMA_SRC_ATOP COLOR_SRC_ATOP
+
+// SRC_IN      [Sa * Da, Sc * Da]
+#define ALPHA_SRC_IN(mx, Sa, Da) ((Sa * Da) / mx)
+#define COLOR_SRC_IN(mx, Sc, Sa, Dc, Da) (Sc * Da / mx)
+#define CHROMA_SRC_IN COLOR_SRC_IN
+
+// SRC_OUT     [Sa * (1 - Da), Sc * (1 - Da)]
+#define ALPHA_SRC_OUT(mx, Sa, Da) (Sa * (mx - Da) / mx)
+#define COLOR_SRC_OUT(mx, Sc, Sa, Dc, Da) (Sc * (mx - Da) / mx)
+#define CHROMA_SRC_OUT COLOR_SRC_OUT
+
+// SRC_OVER    [Sa + Da - Sa*Da, Sc + (1 - Sa) * Dc]
+#define ALPHA_SRC_OVER STD_ALPHA
+#define COLOR_SRC_OVER(mx, Sc, Sa, Dc, Da) (Sc + Dc * (mx - Sa) / mx)
+#define CHROMA_SRC_OVER COLOR_SRC_OVER
+
+// AND         [Sa + Da - Sa * Da, Sc * Dc]
+#define ALPHA_AND(mx, Sa, Da) ((Sa * Da) / mx)
+#define COLOR_AND(mx, Sc, Sa, Dc, Da) ((Sc * Dc) / mx)
+#define CHROMA_AND COLOR_AND
+
+// OR          [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc]
+#define ALPHA_OR(mx, Sa, Da) (Sa + Da - (Sa * Da) / mx)
+#define COLOR_OR(mx, Sc, Sa, Dc, Da) (Sc + Dc - (Sc * Dc) / mx)
+#define CHROMA_OR COLOR_OR
+
+// XOR         [Sa * (1 - Da) + Da * (1 - Sa), Sa + Da - 2 * Sa * Da]
+#define ALPHA_XOR(mx, Sa, Da) (Sa + Da - (TWO * Sa * Da / mx))
+#define COLOR_XOR(mx, Sc, Sa, Dc, Da) ((Sc * (mx - Da) + Dc * (mx - Sa)) / mx)
+#define CHROMA_XOR COLOR_XOR
+
+//SVG 1.2
+//https://www.w3.org/TR/2004/WD-SVG12-20041027/rendering.html
+// OVERLAY [Sa + Da - Sa * Da,  Sc*(1 - Da) + Dc*(1 - Sa) +
+//   2*Dc < Da ? 2*Sc*Dc : Sa*Da - 2*(Da-Dc)*(Sa-Sc) ]
+#define ALPHA_OVERLAY STD_ALPHA
+#define COLOR_OVERLAY(mx, Sc, Sa, Dc, Da) (STD_BLEND(mx,Sc,Sa,Dc,Da) + \
+  ((TWO * Dc < Da) ? \
+    (TWO * Sc * Dc) : (Sa * Da - TWO * (Da - Dc) * (Sa - Sc))) / mx)
+#define CHROMA_OVERLAY COLOR_OVERLAY
+
+// SCREEN [Sa + Da - Sa * Da, Sc + Dc - (Sc * Dc)] (same as OR)
+#define ALPHA_SCREEN STD_ALPHA
+#define COLOR_SCREEN(mx, Sc, Sa, Dc, Da) (Sc + Dc - (Sc * Dc) / mx)
+#define CHROMA_SCREEN COLOR_SCREEN
+
+// BURN        [Sa + Da - Sa * Da,  Sc*(1 - Da) + Dc*(1 - Sa) +
+//  Sc <= 0 || Sc*Da + Dc*Sa <= Sa*Da ? 0 : (Sc*Da + Dc*Sa - Sa*Da)*Sa/Sc]
+#define ALPHA_BURN STD_ALPHA
+#define COLOR_BURN(mx, Sc, Sa, Dc, Da) (STD_BLEND(mx,Sc,Sa,Dc,Da) + \
+  ((Sc <= ZERO || Sc * Da + Dc * Sa <= Sa * Da) ? ZERO : \
+    (Sa * ((Sc * Da + Dc * Sa - Sa * Da) / Sc) / mx)))
+#define CHROMA_BURN COLOR_BURN
+
+// DODGE [Sa + Da - Sa * Da,  Sc*(1 - Da) + Dc*(1 - Sa) +
+//  Sa <= Sc || Sc*Da + Dc*Sa >= Sa*Da) ? Sa*Da : Dc*Sa / (1 - Sc/Sa)]
+#define ALPHA_DODGE STD_ALPHA
+#define COLOR_DODGE(mx, Sc, Sa, Dc, Da) (STD_BLEND(mx,Sc,Sa,Dc,Da) + \
+  ((Sa <= Sc || Sc * Da + Dc * Sa >= Sa * Da) ? (Sa * Da) : \
+    (Sa * ((Dc * Sa) / (Sa - Sc))) / mx))
+#define CHROMA_DODGE COLOR_DODGE
+
+// HARDLIGHT [Sa + Da - Sa * Da, Sc*(1 - Da) + Dc*(1 - Sa) +
+//  2*Sc < Sa ? 2*Sc*Dc : Sa*Da - 2*(Da - Dc)*(Sa - Sc)]
+#define ALPHA_HARDLIGHT STD_ALPHA
+#define COLOR_HARDLIGHT(mx, Sc, Sa, Dc, Da) (STD_BLEND(mx,Sc,Sa,Dc,Da) + \
+  ((TWO * Sc < Sa) ? \
+    (TWO * Sc * Dc) : (Sa * Da - TWO * (Da - Dc) * (Sa - Sc))) / mx)
+#define CHROMA_HARDLIGHT COLOR_HARDLIGHT
+
+// SOFTLIGHT [Sa + Da - Sa * Da,  Sc*(1 - Da) + Dc*(1 - Sa) +
+//  Da > 0 ? (Dc*Sa + 2*Sc*(Da - Dc))/Da : 0]
+#define ALPHA_SOFTLIGHT STD_ALPHA
+#define COLOR_SOFTLIGHT(mx, Sc, Sa, Dc, Da) (STD_BLEND(mx,Sc,Sa,Dc,Da) + \
+  ((Da > ZERO) ? \
+    (Dc * ((Dc*Sa + TWO * Sc * (Da - Dc)) / Da) / mx) : ZERO))
+#define CHROMA_SOFTLIGHT COLOR_SOFTLIGHT
+
+// DIFFERENCE [Sa + Da - Sa * Da,  Sc*(1 - Da) + Dc*(1 - Sa) +
+//  abs(Sc * Da - Sc * Sa)]
+#define ALPHA_DIFFERENCE STD_ALPHA
+#define COLOR_DIFFERENCE(mx, Sc, Sa, Dc, Da) (STD_BLEND(mx,Sc,Sa,Dc,Da) + \
+  (mabs(Sc * Da - Dc * Sa) / mx))
+#define CHROMA_DIFFERENCE COLOR_DIFFERENCE
+
+static inline int   mabs(int32_t v) { return abs(v); }
+static inline int   mabs(int64_t v) { return llabs(v); }
+static inline float mabs(float v)   { return fabsf(v); }
+static inline int   mmin(int32_t a, int32_t b) { return a < b ? a : b; }
+static inline int   mmin(int64_t a, int64_t b) { return a < b ? a : b; }
+static inline float mmin(float a, float b)   { return a < b ? a : b; }
+static inline int   mmax(int32_t a, int32_t b) { return a > b ? a : b; }
+static inline int   mmax(int64_t a, int64_t b) { return a > b ? a : b; }
+static inline float mmax(float a, float b)   { return a > b ? a : b; }
+
+static inline int32_t aclip(int32_t v, int mx) {
+       return v < 0 ? 0 : v > mx ? mx : v;
+}
+static inline int64_t aclip(int64_t v, int mx) {
+       return v < 0 ? 0 : v > mx ? mx : v;
+}
+static inline float   aclip(float v, float mx) {
+       return v < 0 ? 0 : v > mx ? mx : v;
+}
+static inline float   aclip(float v, int mx) {
+       return v < 0 ? 0 : v > mx ? mx : v;
+}
+static inline int   aclip(int v, float mx) {
+       return v < 0 ? 0 : v > mx ? mx : v;
+}
+static inline int32_t cclip(int32_t v, int mx) {
+       return v > (mx/=2) ? mx : v < (mx=(-mx-1)) ? mx : v;
+}
+static inline int64_t cclip(int64_t v, int mx) {
+       return v > (mx/=2) ? mx : v < (mx=(-mx-1)) ? mx : v;
+}
+static inline float   cclip(float v, float mx) {
+       return v > (mx/=2) ? mx : v < (mx=(-mx)) ? mx : v;
+}
+static inline float   cclip(float v, int mx) {
+       return v > (mx/=2) ? mx : v < (mx=(-mx-1)) ? mx : v;
+}
+static inline int   cclip(int v, float mx) {
+       return v > (mx/=2) ? mx : v < (mx=(-mx-1)) ? mx : v;
+}
+
+/* number of data pts per unit x in lookup table */
+#define TRANSFORM_SPP    (4096)
+/* bits of fraction past TRANSFORM_SPP on kernel index accumulation */
+#define INDEX_FRACTION   (8)
+#define TRANSFORM_MIN    (.5 / TRANSFORM_SPP)
+
+#define ZTYP(ty) typedef ty z_##ty __attribute__ ((__unused__))
+ZTYP(int8_t);  ZTYP(uint8_t);
+ZTYP(int16_t); ZTYP(uint16_t);
+ZTYP(int32_t); ZTYP(uint32_t);
+ZTYP(int64_t); ZTYP(uint64_t);
+ZTYP(float);   ZTYP(double);
+
+#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( oofs ) { \
+    g = CHROMA_##FN(mx, inp1, inp3, out1, out3); \
+    b = CHROMA_##FN(mx, inp2, inp3, out2, out3); \
+  } \
+  else { \
+    g = COLOR_##FN(mx, inp1, inp3, out1, out3); \
+    b = COLOR_##FN(mx, inp2, inp3, out2, out3); \
+  }
+
+#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( oofs ) { \
+    g = CHROMA_##FN(mx, inp1, inp3, out1, out3); \
+    b = CHROMA_##FN(mx, inp2, inp3, out2, out3); \
+  } \
+  else { \
+    g = COLOR_##FN(mx, inp1, inp3, out1, out3); \
+    b = COLOR_##FN(mx, inp2, inp3, out2, out3); \
+  } \
+  a = ALPHA_##FN(mx, inp3, out3)
+
+#define ALPHA_STORE(out, ofs, mx) \
+  out[0] = r; \
+  out[1] = g + ofs; \
+  out[2] = b + ofs
+
+#define ALPHA3_STORE(out, ofs, mx) \
+  r = aclip(r, mx); \
+  g = ofs ? cclip(g, mx) : aclip(g, mx); \
+  b = ofs ? cclip(b, mx) : aclip(b, mx); \
+  if( trnsp ) { \
+    r = (r * opcty + out0 * trnsp) / mx; \
+    g = (g * opcty + out1 * trnsp) / mx; \
+    b = (b * opcty + out2 * trnsp) / mx; \
+  } \
+  ALPHA_STORE(out, ofs, mx)
+
+#define ALPHA4_STORE(out, ofs, mx) \
+  r = aclip(r, mx); \
+  g = ofs ? cclip(g, mx) : aclip(g, mx); \
+  b = ofs ? cclip(b, mx) : aclip(b, mx); \
+  if( trnsp ) { \
+    r = (r * opcty + out0 * trnsp) / mx; \
+    g = (g * opcty + out1 * trnsp) / mx; \
+    b = (b * opcty + out2 * trnsp) / mx; \
+    a = (a * opcty + out3 * trnsp) / mx; \
+  } \
+  ALPHA_STORE(out, ofs, mx); \
+  out[3] = aclip(a, mx)
+
+
+#define BLEND_SWITCH(FN) \
+       switch( mode ) { \
+        case TRANSFER_NORMAL:          FN(NORMAL); \
+        case TRANSFER_ADDITION:                FN(ADDITION); \
+        case TRANSFER_SUBTRACT:                FN(SUBTRACT); \
+        case TRANSFER_MULTIPLY:                FN(MULTIPLY); \
+        case TRANSFER_DIVIDE:          FN(DIVIDE); \
+        case TRANSFER_REPLACE:                 FN(REPLACE); \
+        case TRANSFER_MAX:             FN(MAX); \
+        case TRANSFER_MIN:             FN(MIN); \
+       case TRANSFER_DARKEN:           FN(DARKEN); \
+       case TRANSFER_LIGHTEN:          FN(LIGHTEN); \
+       case TRANSFER_DST:              FN(DST); \
+       case TRANSFER_DST_ATOP:         FN(DST_ATOP); \
+       case TRANSFER_DST_IN:           FN(DST_IN); \
+       case TRANSFER_DST_OUT:          FN(DST_OUT); \
+       case TRANSFER_DST_OVER:         FN(DST_OVER); \
+       case TRANSFER_SRC:              FN(SRC); \
+       case TRANSFER_SRC_ATOP:         FN(SRC_ATOP); \
+       case TRANSFER_SRC_IN:           FN(SRC_IN); \
+       case TRANSFER_SRC_OUT:          FN(SRC_OUT); \
+       case TRANSFER_SRC_OVER:         FN(SRC_OVER); \
+       case TRANSFER_AND:              FN(AND); \
+       case TRANSFER_OR:               FN(OR); \
+       case TRANSFER_XOR:              FN(XOR); \
+       case TRANSFER_OVERLAY:          FN(OVERLAY); \
+       case TRANSFER_SCREEN:           FN(SCREEN); \
+       case TRANSFER_BURN:             FN(BURN); \
+       case TRANSFER_DODGE:            FN(DODGE); \
+       case TRANSFER_HARDLIGHT:        FN(HARDLIGHT); \
+       case TRANSFER_SOFTLIGHT:        FN(SOFTLIGHT); \
+       case TRANSFER_DIFFERENCE:       FN(DIFFERENCE); \
+       }
+
 class OverlayKernel
 {
 public:
diff --git a/cinelerra-5.1/cinelerra/overlayframe.h.clamp b/cinelerra-5.1/cinelerra/overlayframe.h.clamp
deleted file mode 100644 (file)
index 4df7207..0000000
+++ /dev/null
@@ -1,381 +0,0 @@
-#ifndef OVERLAYFRAME_H
-#define OVERLAYFRAME_H
-
-#include "loadbalance.h"
-#include "overlayframe.inc"
-#include "vframe.inc"
-
-
-// Issues encoutered with overlay
-
-// Floating point vs. int.  On alpha the floating point interpolation is about
-// 2x faster than integer interpolation.  Integer interpolation uses 32 
-// siginificant bits while floating point uses 24, however.
-
-// Single step vs. two step process.
-
-// A single step process would require performing blend with the output
-// of BILINEAR or BICUBIC and trimming the output to fractional pixels.
-// This is easy.  
-
-// However reading the input for
-// BILINEAR and BICUBIC would require trimming the input to fractional
-// pixels often repeatedly since the interpolation reads the same pixels more
-// than once.  This is hard.
-
-// In the two step process one step worries purely about scaling, ignoring 
-// trimming at the input and output so redundant trimming is not done here.
-
-// The translation engine focuses purely on trimming input pixels and
-// blending with the output.
-
-// Translation
-
-typedef struct
-{
-       int in_x1;
-       float in_fraction1;
-       int in_x2;       // Might be same as in_x1 for boundary
-       float in_fraction2;
-       float output_fraction;
-} transfer_table;
-
-
-class ScaleEngine;
-
-class ScalePackage : public LoadPackage
-{
-public:
-       ScalePackage();
-
-       int out_row1, out_row2;
-};
-
-class ScaleUnit : public LoadClient
-{
-public:
-       ScaleUnit(ScaleEngine *server, OverlayFrame *overlay);
-       ~ScaleUnit();
-       
-       float cubic_bspline(float x);
-       void tabulate_bicubic(float* &coef_table, 
-               int* &coord_table,
-               float scale,
-               int start, 
-               int pixels,
-               int total_pixels,
-               float coefficient);
-       void tabulate_blinear(int* &table_int1,
-               int* &table_int2,
-               float* &table_frac,
-               float* &table_antifrac,
-               float scale,
-               int pixel1,
-               int pixel2,
-               int start,
-               int total_pixels);
-
-       void process_package(LoadPackage *package);
-       
-       OverlayFrame *overlay;
-       ScaleEngine *engine;
-};
-
-class ScaleEngine : public LoadServer
-{
-public:
-       ScaleEngine(OverlayFrame *overlay, int cpus);
-       ~ScaleEngine();
-       
-       void init_packages();
-       LoadClient* new_client();
-       LoadPackage* new_package();
-       
-       OverlayFrame *overlay;
-// Global parameters for scaling units
-       VFrame *scale_output;
-       VFrame *scale_input;
-       float w_scale;
-       float h_scale;
-       int in_x1_int;
-       int in_y1_int;
-       int out_w_int;
-       int out_h_int;
-       int interpolation_type;
-};
-
-
-
-
-
-
-
-class TranslateEngine;
-
-class TranslatePackage : public LoadPackage
-{
-public:
-       TranslatePackage();
-
-       int out_row1, out_row2;
-};
-
-
-class TranslateUnit : public LoadClient
-{
-public:
-       TranslateUnit(TranslateEngine *server, OverlayFrame *overlay);
-       ~TranslateUnit();
-
-       void process_package(LoadPackage *package);
-       void translation_array(transfer_table* &table, 
-               float out_x1, 
-               float out_x2,
-               float in_x1,
-               float in_x2,
-               int in_total, 
-               int out_total, 
-               int &out_x1_int,
-               int &out_x2_int);
-       void translate(VFrame *output, 
-                       VFrame *input, 
-                       float in_x1,
-                       float in_y1,
-                       float in_x2,
-                       float in_y2,
-                       float out_x1,
-                       float out_y1,
-                       float out_x2,
-                       float out_y2,
-                       float alpha,
-                       int mode,
-                       int row1,
-                       int row2);
-
-       OverlayFrame *overlay;
-       TranslateEngine *engine;
-};
-
-class TranslateEngine : public LoadServer
-{
-public:
-       TranslateEngine(OverlayFrame *overlay, int cpus);
-       ~TranslateEngine();
-       
-       void init_packages();
-       LoadClient* new_client();
-       LoadPackage* new_package();
-       
-       OverlayFrame *overlay;
-// Global parameters for translate units
-       VFrame *translate_output;
-       VFrame *translate_input;
-       float translate_in_x1;
-       float translate_in_y1;
-       float translate_in_x2;
-       float translate_in_y2;
-       float translate_out_x1;
-       float translate_out_y1;
-       float translate_out_x2;
-       float translate_out_y2;
-       float translate_alpha;
-       int translate_mode;
-};
-
-
-
-
-
-
-
-
-
-class ScaleTranslateEngine;
-
-class ScaleTranslatePackage : public LoadPackage
-{
-public:
-       ScaleTranslatePackage();
-
-       int out_row1, out_row2;
-};
-
-
-class ScaleTranslateUnit : public LoadClient
-{
-public:
-       ScaleTranslateUnit(ScaleTranslateEngine *server, OverlayFrame *overlay);
-       ~ScaleTranslateUnit();
-
-       void process_package(LoadPackage *package);
-       void scale_array(int* &table, 
-               int out_x1, 
-               int out_x2,
-               int in_x1,
-               int in_x2,
-               int is_x);
-       
-       OverlayFrame *overlay;
-       ScaleTranslateEngine *scale_translate;
-};
-
-class ScaleTranslateEngine : public LoadServer
-{
-public:
-       ScaleTranslateEngine(OverlayFrame *overlay, int cpus);
-       ~ScaleTranslateEngine();
-       
-       void init_packages();
-       LoadClient* new_client();
-       LoadPackage* new_package();
-       
-       OverlayFrame *overlay;
-       
-       
-// Arguments
-       VFrame *output;
-       VFrame *input;
-       int in_x1;
-       int in_y1;
-       int in_x2;
-       int in_y2;
-       int out_x1;
-       int out_y1;
-       int out_x2;
-       int out_y2;
-       float alpha;
-       int mode;
-};
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-class BlendEngine;
-
-class BlendPackage : public LoadPackage
-{
-public:
-       BlendPackage();
-
-       int out_row1, out_row2;
-};
-
-
-class BlendUnit : public LoadClient
-{
-public:
-       BlendUnit(BlendEngine *server, OverlayFrame *overlay);
-       ~BlendUnit();
-
-       void process_package(LoadPackage *package);
-       void translation_array(transfer_table* &table, 
-               float out_x1, 
-               float out_x2,
-               float in_x1,
-               float in_x2,
-               int in_total, 
-               int out_total, 
-               int &out_x1_int,
-               int &out_x2_int);
-       void translate(VFrame *output, 
-                       VFrame *input, 
-                       float in_x1,
-                       float in_y1,
-                       float in_x2,
-                       float in_y2,
-                       float out_x1,
-                       float out_y1,
-                       float out_x2,
-                       float out_y2,
-                       float alpha,
-                       int mode,
-                       int row1,
-                       int row2);
-
-       OverlayFrame *overlay;
-       BlendEngine *blend_engine;
-};
-
-class BlendEngine : public LoadServer
-{
-public:
-       BlendEngine(OverlayFrame *overlay, int cpus);
-       ~BlendEngine();
-       
-       void init_packages();
-       LoadClient* new_client();
-       LoadPackage* new_package();
-       
-       OverlayFrame *overlay;
-       
-       
-// Arguments
-       VFrame *output;
-       VFrame *input;
-       float alpha;
-       int mode;
-};
-
-
-
-
-
-
-
-
-
-
-
-
-
-class OverlayFrame
-{
-public:
-       OverlayFrame(int cpus = 1);
-       virtual ~OverlayFrame();
-
-// Alpha is from 0 - 1
-       int overlay(VFrame *output, 
-               VFrame *input, 
-               float in_x1, 
-               float in_y1, 
-               float in_x2, 
-               float in_y2, 
-               float out_x1, 
-               float out_y1, 
-               float out_x2, 
-               float out_y2, 
-               float alpha, 
-               int mode,
-               int interpolation_type);
-
-       int overlay(VFrame *output, unsigned char *input,
-               float in_x1, float in_y1, float in_x2, float in_y2,
-               float out_x1, float out_y1, float out_x2, float out_y2, 
-               int alpha, int in_w, int in_h);
-       int use_alpha, use_float, mode, interpolate;
-       int color_model;
-
-       BlendEngine *blend_engine;
-       ScaleEngine *scale_engine;
-       TranslateEngine *translate_engine;
-       ScaleTranslateEngine *scaletranslate_engine;
-
-
-       VFrame *temp_frame;
-       int cpus;
-
-};
-
-#endif
diff --git a/cinelerra-5.1/cinelerra/overlayframe.h.float b/cinelerra-5.1/cinelerra/overlayframe.h.float
deleted file mode 100644 (file)
index cf1f30e..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-#ifndef OVERLAYFRAME_H
-#define OVERLAYFRAME_H
-
-#include "loadbalance.h"
-#include "overlayframe.inc"
-#include "vframe.inc"
-
-
-
-// Translation
-
-typedef struct
-{
-       int in_x1;
-       float in_fraction1;
-       int in_x2;       // Might be same as in_x1 for boundary
-       float in_fraction2;
-       float output_fraction;
-} transfer_table;
-
-
-class ScaleEngine;
-
-class ScalePackage : public LoadPackage
-{
-public:
-       ScalePackage();
-
-       int out_row1, out_row2;
-};
-
-
-class ScaleUnit : public LoadClient
-{
-public:
-       ScaleUnit(ScaleEngine *server, OverlayFrame *overlay);
-       ~ScaleUnit();
-       
-       float cubic_bspline(float x);
-       void tabulate_bspline(float* &table, 
-               float scale,
-               int pixels,
-               float coefficient);
-
-       void process_package(LoadPackage *package);
-       
-       OverlayFrame *overlay;
-};
-
-class ScaleEngine : public LoadServer
-{
-public:
-       ScaleEngine(OverlayFrame *overlay, int cpus);
-       ~ScaleEngine();
-       
-       void init_packages();
-       LoadClient* new_client();
-       LoadPackage* new_package();
-       
-       OverlayFrame *overlay;
-};
-
-
-
-
-
-
-
-class TranslateEngine;
-
-class TranslatePackage : public LoadPackage
-{
-public:
-       TranslatePackage();
-
-       int out_row1, out_row2;
-};
-
-
-class TranslateUnit : public LoadClient
-{
-public:
-       TranslateUnit(TranslateEngine *server, OverlayFrame *overlay);
-       ~TranslateUnit();
-
-       void process_package(LoadPackage *package);
-       void translation_array(transfer_table* &table, 
-               float out_x1, 
-               float out_x2,
-               float in_x1,
-               float in_x2,
-               int in_total, 
-               int out_total, 
-               int &out_x1_int,
-               int &out_x2_int);
-       void translate(VFrame *output, 
-                       VFrame *input, 
-                       float in_x1,
-                       float in_y1,
-                       float in_x2,
-                       float in_y2,
-                       float out_x1,
-                       float out_y1,
-                       float out_x2,
-                       float out_y2,
-                       float alpha,
-                       int mode,
-                       int row1,
-                       int row2);
-
-       OverlayFrame *overlay;
-};
-
-class TranslateEngine : public LoadServer
-{
-public:
-       TranslateEngine(OverlayFrame *overlay, int cpus);
-       ~TranslateEngine();
-       
-       void init_packages();
-       LoadClient* new_client();
-       LoadPackage* new_package();
-       
-       OverlayFrame *overlay;
-};
-
-
-
-
-
-
-
-
-
-class ScaleTranslateEngine;
-
-class ScaleTranslatePackage : public LoadPackage
-{
-public:
-       ScaleTranslatePackage();
-
-       int out_row1, out_row2;
-};
-
-
-class ScaleTranslateUnit : public LoadClient
-{
-public:
-       ScaleTranslateUnit(ScaleTranslateEngine *server, OverlayFrame *overlay);
-       ~ScaleTranslateUnit();
-
-       void process_package(LoadPackage *package);
-       void scale_array(int* &table, 
-               int out_x1, 
-               int out_x2,
-               int in_x1,
-               int in_x2,
-               int is_x);
-       
-       OverlayFrame *overlay;
-       ScaleTranslateEngine *scale_translate;
-};
-
-class ScaleTranslateEngine : public LoadServer
-{
-public:
-       ScaleTranslateEngine(OverlayFrame *overlay, int cpus);
-       ~ScaleTranslateEngine();
-       
-       void init_packages();
-       LoadClient* new_client();
-       LoadPackage* new_package();
-       
-       OverlayFrame *overlay;
-       
-       
-// Arguments
-       VFrame *output;
-       VFrame *input;
-       int in_x1;
-       int in_y1;
-       int in_x2;
-       int in_y2;
-       int out_x1;
-       int out_y1;
-       int out_x2;
-       int out_y2;
-       float alpha;
-       int mode;
-};
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-class BlendEngine;
-
-class BlendPackage : public LoadPackage
-{
-public:
-       BlendPackage();
-
-       int out_row1, out_row2;
-};
-
-
-class BlendUnit : public LoadClient
-{
-public:
-       BlendUnit(BlendEngine *server, OverlayFrame *overlay);
-       ~BlendUnit();
-
-       void process_package(LoadPackage *package);
-       void translation_array(transfer_table* &table, 
-               float out_x1, 
-               float out_x2,
-               float in_x1,
-               float in_x2,
-               int in_total, 
-               int out_total, 
-               int &out_x1_int,
-               int &out_x2_int);
-       void translate(VFrame *output, 
-                       VFrame *input, 
-                       float in_x1,
-                       float in_y1,
-                       float in_x2,
-                       float in_y2,
-                       float out_x1,
-                       float out_y1,
-                       float out_x2,
-                       float out_y2,
-                       float alpha,
-                       int mode,
-                       int row1,
-                       int row2);
-
-       OverlayFrame *overlay;
-       BlendEngine *blend_engine;
-};
-
-class BlendEngine : public LoadServer
-{
-public:
-       BlendEngine(OverlayFrame *overlay, int cpus);
-       ~BlendEngine();
-       
-       void init_packages();
-       LoadClient* new_client();
-       LoadPackage* new_package();
-       
-       OverlayFrame *overlay;
-       
-       
-// Arguments
-       VFrame *output;
-       VFrame *input;
-       float alpha;
-       int mode;
-};
-
-
-
-
-
-
-
-
-
-
-
-
-
-class OverlayFrame
-{
-public:
-       OverlayFrame(int cpus = 1);
-       virtual ~OverlayFrame();
-
-// Alpha is from 0 - 1
-       int overlay(VFrame *output, 
-               VFrame *input, 
-               float in_x1, 
-               float in_y1, 
-               float in_x2, 
-               float in_y2, 
-               float out_x1, 
-               float out_y1, 
-               float out_x2, 
-               float out_y2, 
-               float alpha, 
-               int mode,
-               int interpolation_type);
-
-       int overlay(VFrame *output, unsigned char *input,
-               float in_x1, float in_y1, float in_x2, float in_y2,
-               float out_x1, float out_y1, float out_x2, float out_y2, 
-               int alpha, int in_w, int in_h);
-       int use_alpha, use_float, mode, interpolate;
-       int color_model;
-
-       BlendEngine *blend_engine;
-       ScaleEngine *scale_engine;
-       TranslateEngine *translate_engine;
-       ScaleTranslateEngine *scaletranslate_engine;
-
-
-       VFrame *temp_frame;
-       int cpus;
-
-// TODO: These should all be in their respective Engine
-// Global parameters for scaling units
-       VFrame *scale_output;
-       VFrame *scale_input;
-       float w_scale;
-       float h_scale;
-       int in_x1_int;
-       int in_y1_int;
-       int out_w_int;
-       int out_h_int;
-       int interpolation_type;
-// Global parameters for translate units
-       VFrame *translate_output;
-       VFrame *translate_input;
-       float translate_in_x1;
-       float translate_in_y1;
-       float translate_in_x2;
-       float translate_in_y2;
-       float translate_out_x1;
-       float translate_out_y1;
-       float translate_out_x2;
-       float translate_out_y2;
-       float translate_alpha;
-       int translate_mode;
-};
-
-#endif
diff --git a/cinelerra-5.1/cinelerra/overlayframe.h.floattable b/cinelerra-5.1/cinelerra/overlayframe.h.floattable
deleted file mode 100644 (file)
index cf5b075..0000000
+++ /dev/null
@@ -1,376 +0,0 @@
-#ifndef OVERLAYFRAME_H
-#define OVERLAYFRAME_H
-
-#include "loadbalance.h"
-#include "overlayframe.inc"
-#include "vframe.inc"
-
-
-// Issues encoutered with overlay
-
-// Floating point vs. int.  On alpha the floating point interpolation is about
-// 2x faster than integer interpolation.  Integer interpolation uses 32 
-// siginificant bits while floating point uses 24, however.
-
-// Single step vs. two step process.
-
-// A single step process would require performing blend with the output
-// of BILINEAR or BICUBIC and trimming the output to fractional pixels.
-// This is easy.  
-
-// However reading the input for
-// BILINEAR and BICUBIC would require trimming the input to fractional
-// pixels often repeatedly since the interpolation reads the same pixels more
-// than once.  This is hard.
-
-// In the two step process one step worries purely about scaling, ignoring 
-// trimming at the input and output so redundant trimming is not done here.
-
-// The translation engine focuses purely on trimming input pixels and
-// blending with the output
-
-// Translation
-
-typedef struct
-{
-       int in_x1;
-       float in_fraction1;
-       int in_x2;       // Might be same as in_x1 for boundary
-       float in_fraction2;
-       float output_fraction;
-} transfer_table;
-
-
-class ScaleEngine;
-
-class ScalePackage : public LoadPackage
-{
-public:
-       ScalePackage();
-
-       int out_row1, out_row2;
-};
-
-class ScaleUnit : public LoadClient
-{
-public:
-       ScaleUnit(ScaleEngine *server, OverlayFrame *overlay);
-       ~ScaleUnit();
-       
-       float cubic_bspline(float x);
-       void tabulate_bspline(float* &table, 
-               float scale,
-               int pixels,
-               float coefficient);
-       void tabulate_blinear(int* &table_int,
-               float* &table_frac,
-               float* &table_antifrac,
-               float scale,
-               int pixel1,
-               int pixel2,
-               int total_pixels);
-
-       void process_package(LoadPackage *package);
-       
-       OverlayFrame *overlay;
-       ScaleEngine *engine;
-};
-
-class ScaleEngine : public LoadServer
-{
-public:
-       ScaleEngine(OverlayFrame *overlay, int cpus);
-       ~ScaleEngine();
-       
-       void init_packages();
-       LoadClient* new_client();
-       LoadPackage* new_package();
-       
-       OverlayFrame *overlay;
-// Global parameters for scaling units
-       VFrame *scale_output;
-       VFrame *scale_input;
-       float w_scale;
-       float h_scale;
-       int in_x1_int;
-       int in_y1_int;
-       int out_w_int;
-       int out_h_int;
-       int interpolation_type;
-};
-
-
-
-
-
-
-
-class TranslateEngine;
-
-class TranslatePackage : public LoadPackage
-{
-public:
-       TranslatePackage();
-
-       int out_row1, out_row2;
-};
-
-
-class TranslateUnit : public LoadClient
-{
-public:
-       TranslateUnit(TranslateEngine *server, OverlayFrame *overlay);
-       ~TranslateUnit();
-
-       void process_package(LoadPackage *package);
-       void translation_array(transfer_table* &table, 
-               float out_x1, 
-               float out_x2,
-               float in_x1,
-               float in_x2,
-               int in_total, 
-               int out_total, 
-               int &out_x1_int,
-               int &out_x2_int);
-       void translate(VFrame *output, 
-                       VFrame *input, 
-                       float in_x1,
-                       float in_y1,
-                       float in_x2,
-                       float in_y2,
-                       float out_x1,
-                       float out_y1,
-                       float out_x2,
-                       float out_y2,
-                       float alpha,
-                       int mode,
-                       int row1,
-                       int row2);
-
-       OverlayFrame *overlay;
-       TranslateEngine *engine;
-};
-
-class TranslateEngine : public LoadServer
-{
-public:
-       TranslateEngine(OverlayFrame *overlay, int cpus);
-       ~TranslateEngine();
-       
-       void init_packages();
-       LoadClient* new_client();
-       LoadPackage* new_package();
-       
-       OverlayFrame *overlay;
-// Global parameters for translate units
-       VFrame *translate_output;
-       VFrame *translate_input;
-       float translate_in_x1;
-       float translate_in_y1;
-       float translate_in_x2;
-       float translate_in_y2;
-       float translate_out_x1;
-       float translate_out_y1;
-       float translate_out_x2;
-       float translate_out_y2;
-       float translate_alpha;
-       int translate_mode;
-};
-
-
-
-
-
-
-
-
-
-class ScaleTranslateEngine;
-
-class ScaleTranslatePackage : public LoadPackage
-{
-public:
-       ScaleTranslatePackage();
-
-       int out_row1, out_row2;
-};
-
-
-class ScaleTranslateUnit : public LoadClient
-{
-public:
-       ScaleTranslateUnit(ScaleTranslateEngine *server, OverlayFrame *overlay);
-       ~ScaleTranslateUnit();
-
-       void process_package(LoadPackage *package);
-       void scale_array(int* &table, 
-               int out_x1, 
-               int out_x2,
-               int in_x1,
-               int in_x2,
-               int is_x);
-       
-       OverlayFrame *overlay;
-       ScaleTranslateEngine *scale_translate;
-};
-
-class ScaleTranslateEngine : public LoadServer
-{
-public:
-       ScaleTranslateEngine(OverlayFrame *overlay, int cpus);
-       ~ScaleTranslateEngine();
-       
-       void init_packages();
-       LoadClient* new_client();
-       LoadPackage* new_package();
-       
-       OverlayFrame *overlay;
-       
-       
-// Arguments
-       VFrame *output;
-       VFrame *input;
-       int in_x1;
-       int in_y1;
-       int in_x2;
-       int in_y2;
-       int out_x1;
-       int out_y1;
-       int out_x2;
-       int out_y2;
-       float alpha;
-       int mode;
-};
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-class BlendEngine;
-
-class BlendPackage : public LoadPackage
-{
-public:
-       BlendPackage();
-
-       int out_row1, out_row2;
-};
-
-
-class BlendUnit : public LoadClient
-{
-public:
-       BlendUnit(BlendEngine *server, OverlayFrame *overlay);
-       ~BlendUnit();
-
-       void process_package(LoadPackage *package);
-       void translation_array(transfer_table* &table, 
-               float out_x1, 
-               float out_x2,
-               float in_x1,
-               float in_x2,
-               int in_total, 
-               int out_total, 
-               int &out_x1_int,
-               int &out_x2_int);
-       void translate(VFrame *output, 
-                       VFrame *input, 
-                       float in_x1,
-                       float in_y1,
-                       float in_x2,
-                       float in_y2,
-                       float out_x1,
-                       float out_y1,
-                       float out_x2,
-                       float out_y2,
-                       float alpha,
-                       int mode,
-                       int row1,
-                       int row2);
-
-       OverlayFrame *overlay;
-       BlendEngine *blend_engine;
-};
-
-class BlendEngine : public LoadServer
-{
-public:
-       BlendEngine(OverlayFrame *overlay, int cpus);
-       ~BlendEngine();
-       
-       void init_packages();
-       LoadClient* new_client();
-       LoadPackage* new_package();
-       
-       OverlayFrame *overlay;
-       
-       
-// Arguments
-       VFrame *output;
-       VFrame *input;
-       float alpha;
-       int mode;
-};
-
-
-
-
-
-
-
-
-
-
-
-
-
-class OverlayFrame
-{
-public:
-       OverlayFrame(int cpus = 1);
-       virtual ~OverlayFrame();
-
-// Alpha is from 0 - 1
-       int overlay(VFrame *output, 
-               VFrame *input, 
-               float in_x1, 
-               float in_y1, 
-               float in_x2, 
-               float in_y2, 
-               float out_x1, 
-               float out_y1, 
-               float out_x2, 
-               float out_y2, 
-               float alpha, 
-               int mode,
-               int interpolation_type);
-
-       int overlay(VFrame *output, unsigned char *input,
-               float in_x1, float in_y1, float in_x2, float in_y2,
-               float out_x1, float out_y1, float out_x2, float out_y2, 
-               int alpha, int in_w, int in_h);
-       int use_alpha, use_float, mode, interpolate;
-       int color_model;
-
-       BlendEngine *blend_engine;
-       ScaleEngine *scale_engine;
-       TranslateEngine *translate_engine;
-       ScaleTranslateEngine *scaletranslate_engine;
-
-
-       VFrame *temp_frame;
-       int cpus;
-
-};
-
-#endif
diff --git a/cinelerra-5.1/cinelerra/overlayframe.h.int b/cinelerra-5.1/cinelerra/overlayframe.h.int
deleted file mode 100644 (file)
index a851140..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-#ifndef OVERLAYFRAME_H
-#define OVERLAYFRAME_H
-
-#include "loadbalance.h"
-#include "overlayframe.inc"
-#include "vframe.inc"
-
-
-
-// Translation
-
-typedef struct
-{
-       int in_x1;
-       float in_fraction1;
-       int in_x2;       // Might be same as in_x1 for boundary
-       float in_fraction2;
-       float output_fraction;
-} transfer_table;
-
-
-class ScaleEngine;
-
-class ScalePackage : public LoadPackage
-{
-public:
-       ScalePackage();
-
-       int out_row1, out_row2;
-};
-
-
-class ScaleUnit : public LoadClient
-{
-public:
-       ScaleUnit(ScaleEngine *server, OverlayFrame *overlay);
-       ~ScaleUnit();
-       
-       int cubic_bspline(float x);
-       void tabulate_bspline(int* &table, 
-               float scale,
-               int pixels,
-               float coefficient);
-       void tabulate_blinear(int* &table_int,
-               int* &table_frac,
-               float scale,
-               int pixel1,
-               int pixel2);
-
-       void process_package(LoadPackage *package);
-       
-       OverlayFrame *overlay;
-};
-
-class ScaleEngine : public LoadServer
-{
-public:
-       ScaleEngine(OverlayFrame *overlay, int cpus);
-       ~ScaleEngine();
-       
-       void init_packages();
-       LoadClient* new_client();
-       LoadPackage* new_package();
-       
-       OverlayFrame *overlay;
-};
-
-
-
-
-
-
-
-class TranslateEngine;
-
-class TranslatePackage : public LoadPackage
-{
-public:
-       TranslatePackage();
-
-       int out_row1, out_row2;
-};
-
-
-class TranslateUnit : public LoadClient
-{
-public:
-       TranslateUnit(TranslateEngine *server, OverlayFrame *overlay);
-       ~TranslateUnit();
-
-       void process_package(LoadPackage *package);
-       void translation_array(transfer_table* &table, 
-               float out_x1, 
-               float out_x2,
-               float in_x1,
-               float in_x2,
-               int in_total, 
-               int out_total, 
-               int &out_x1_int,
-               int &out_x2_int);
-       void translate(VFrame *output, 
-                       VFrame *input, 
-                       float in_x1,
-                       float in_y1,
-                       float in_x2,
-                       float in_y2,
-                       float out_x1,
-                       float out_y1,
-                       float out_x2,
-                       float out_y2,
-                       float alpha,
-                       int mode,
-                       int row1,
-                       int row2);
-
-       OverlayFrame *overlay;
-};
-
-class TranslateEngine : public LoadServer
-{
-public:
-       TranslateEngine(OverlayFrame *overlay, int cpus);
-       ~TranslateEngine();
-       
-       void init_packages();
-       LoadClient* new_client();
-       LoadPackage* new_package();
-       
-       OverlayFrame *overlay;
-};
-
-
-
-
-
-
-
-
-
-class ScaleTranslateEngine;
-
-class ScaleTranslatePackage : public LoadPackage
-{
-public:
-       ScaleTranslatePackage();
-
-       int out_row1, out_row2;
-};
-
-
-class ScaleTranslateUnit : public LoadClient
-{
-public:
-       ScaleTranslateUnit(ScaleTranslateEngine *server, OverlayFrame *overlay);
-       ~ScaleTranslateUnit();
-
-       void process_package(LoadPackage *package);
-       void scale_array(int* &table, 
-               int out_x1, 
-               int out_x2,
-               int in_x1,
-               int in_x2,
-               int is_x);
-       
-       OverlayFrame *overlay;
-       ScaleTranslateEngine *scale_translate;
-};
-
-class ScaleTranslateEngine : public LoadServer
-{
-public:
-       ScaleTranslateEngine(OverlayFrame *overlay, int cpus);
-       ~ScaleTranslateEngine();
-       
-       void init_packages();
-       LoadClient* new_client();
-       LoadPackage* new_package();
-       
-       OverlayFrame *overlay;
-       
-       
-// Arguments
-       VFrame *output;
-       VFrame *input;
-       int in_x1;
-       int in_y1;
-       int in_x2;
-       int in_y2;
-       int out_x1;
-       int out_y1;
-       int out_x2;
-       int out_y2;
-       float alpha;
-       int mode;
-};
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-class BlendEngine;
-
-class BlendPackage : public LoadPackage
-{
-public:
-       BlendPackage();
-
-       int out_row1, out_row2;
-};
-
-
-class BlendUnit : public LoadClient
-{
-public:
-       BlendUnit(BlendEngine *server, OverlayFrame *overlay);
-       ~BlendUnit();
-
-       void process_package(LoadPackage *package);
-       void translation_array(transfer_table* &table, 
-               float out_x1, 
-               float out_x2,
-               float in_x1,
-               float in_x2,
-               int in_total, 
-               int out_total, 
-               int &out_x1_int,
-               int &out_x2_int);
-       void translate(VFrame *output, 
-                       VFrame *input, 
-                       float in_x1,
-                       float in_y1,
-                       float in_x2,
-                       float in_y2,
-                       float out_x1,
-                       float out_y1,
-                       float out_x2,
-                       float out_y2,
-                       float alpha,
-                       int mode,
-                       int row1,
-                       int row2);
-
-       OverlayFrame *overlay;
-       BlendEngine *blend_engine;
-};
-
-class BlendEngine : public LoadServer
-{
-public:
-       BlendEngine(OverlayFrame *overlay, int cpus);
-       ~BlendEngine();
-       
-       void init_packages();
-       LoadClient* new_client();
-       LoadPackage* new_package();
-       
-       OverlayFrame *overlay;
-       
-       
-// Arguments
-       VFrame *output;
-       VFrame *input;
-       float alpha;
-       int mode;
-};
-
-
-
-
-
-
-
-
-
-
-
-
-
-class OverlayFrame
-{
-public:
-       OverlayFrame(int cpus = 1);
-       virtual ~OverlayFrame();
-
-// Alpha is from 0 - 1
-       int overlay(VFrame *output, 
-               VFrame *input, 
-               float in_x1, 
-               float in_y1, 
-               float in_x2, 
-               float in_y2, 
-               float out_x1, 
-               float out_y1, 
-               float out_x2, 
-               float out_y2, 
-               float alpha, 
-               int mode,
-               int interpolation_type);
-
-       int overlay(VFrame *output, unsigned char *input,
-               float in_x1, float in_y1, float in_x2, float in_y2,
-               float out_x1, float out_y1, float out_x2, float out_y2, 
-               int alpha, int in_w, int in_h);
-       int use_alpha, use_float, mode, interpolate;
-       int color_model;
-
-       BlendEngine *blend_engine;
-       ScaleEngine *scale_engine;
-       TranslateEngine *translate_engine;
-       ScaleTranslateEngine *scaletranslate_engine;
-
-
-       VFrame *temp_frame;
-       int cpus;
-
-// TODO: These should all be in their respective Engine
-// Global parameters for scaling units
-       VFrame *scale_output;
-       VFrame *scale_input;
-       float w_scale;
-       float h_scale;
-       int in_x1_int;
-       int in_y1_int;
-       int out_w_int;
-       int out_h_int;
-       int interpolation_type;
-// Global parameters for translate units
-       VFrame *translate_output;
-       VFrame *translate_input;
-       float translate_in_x1;
-       float translate_in_y1;
-       float translate_in_x2;
-       float translate_in_y2;
-       float translate_out_x1;
-       float translate_out_y1;
-       float translate_out_x2;
-       float translate_out_y2;
-       float translate_alpha;
-       int translate_mode;
-};
-
-#endif
index f29bc5724be062b7c8c51033a66600895e3723b1..18a926c9f2bf97aadda24e7b44309f0a51c4af59 100644 (file)
 
 // Modes
 
-/*
-source
-x = porter duff operator
-g = good guy
-a = android
-* = hv 4.6.1
-
-cin 5.1 overlayframe TRANSFER_MODEs
-x      DST [Da, Dc]
-x      DST_ATOP [Sa, Sc * (1 - Da) + Dc * Sa]
-x      DST_IN  [Da * Sa, Dc * Sa]
-x      DST_OUT [Da * (1 - Sa), Dc * (1 - Sa)]
-x      DST_OVER [Sa * (1 - Da) + Da, Sc * (1 - Da) + Dc]
-x      SRC [Sa, Sc]
-x      SRC_ATOP [Da, Sc * Da + Dc * (1 - Sa)]
-x      SRC_IN  [Sa * Da, Sc * Da]
-x      SRC_OUT [Sa * (1 - Da), Sc * (1 - Da)]
-x      SRC_OVER [Sa + Da * (1 - Sa), Sc + (1 - Sa) * Dc]
-g      OR [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc]
-a      XOR     [Sa * (1 - Da) + Da * (1 - Sa), Sc * (1 - Da) + Dc * (1 Â­ Sa)]
-*      NORMAL [Sa + Da * (1 - Sa), Sc * Sa + Dc * (1 Â­ Sa)])
-*      ADDITION [(Sa + Da), (Sc + Dc)]
-*      SUBTRACT [(Sa - Da), (Sc Â­ Dc)]
-*      MULTIPLY [(Sa * Da), Sc * Dc]
-*      DIVIDE  [(Sa / Da), (Sc / Dc)]
-*      REPLACE [Sa, Sc] (fade = 1)
-*      MAX     [max(Sa, Da), MAX(Sc, Dc)]
-*      MIN [min(Sa, Da), MIN(Sc, Dc)]
-g      AVERAGE [(Sa + Da) * 0.5, (Sc + Dc) * 0.5]
-a      DARKEN [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)]
-a      LIGHTEN [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)]
-
-https://developer.android.com/reference/android/graphics/PorterDuff.Mode.html
-       ADD Saturate(S + D)
-       CLEAR [0, 0]  
-       DARKEN [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)]  
-       DST [Da, Dc]  
-       DST_ATOP [Sa, Sa * Dc + Sc * (1 - Da)]  
-       DST_IN [Sa * Da, Sa * Dc]  
-       DST_OUT [Da * (1 - Sa), Dc * (1 - Sa)]  
-       DST_OVER [Sa + (1 - Sa)*Da, Rc = Dc + (1 - Da)*Sc]  
-       LIGHTEN [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)]  
-       MULTIPLY [Sa * Da, Sc * Dc]  
-       OVERLAY (defined, but unspecified in android)
-       SCREEN [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc]  
-       SRC [Sa, Sc]  
-       SRC_ATOP [Da, Sc * Da + (1 - Sa) * Dc]  
-       SRC_IN [Sa * Da, Sc * Da]  
-       SRC_OUT [Sa * (1 - Da), Sc * (1 - Da)]  
-       SRC_OVER [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc]  
-       XOR [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc]  
-
-https://docs.gimp.org/2.6/en/gimp-concepts-layer-modes.html
-       Normal          [M]
-       Dissolve        [I + dots]
-       Multiply        [M * I]
-       Divide          [I / M]
-       Screen          [1 - (1-M)*(1-I)]
-       Overlay         [I * (I + 2*M*(1-I))]
-       Dodge           [I / (1-M)]
-       Burn            [1 - (1-I) / M]
-       Hard light      [M>0.5 ? (1 - (1-2*(M-0.5))*(1 - I) : 2*M*I]
-       Soft light      [((1-I)*M + Screen()) * I]
-       Grain extract   [I - M + 0.5]
-       Grain merge     [I + M - 0.5]
-       Difference      [abs(I-M)]
-       Addition        [min((I+M),1.0)]
-       Subtract        [max((I-M),0.0)]
-       Darken only     [min(M,I)]
-       Lighten only    [max(M,I)]
-       Hue             [hue(M) + sat(I)+val(I)]
-       Saturation      [sat(M) + hue(I)+val(I)]
-       Color           [hue(M)+sat(M) + val(I)]
-       Value           [val(M) + sat(I)+hue(I)]
-
-*/
-
-#define TRANSFER_TYPES 23
+#define TRANSFER_TYPES 30
 
 #define TRANSFER_NORMAL                0
 #define TRANSFER_ADDITION      1
@@ -111,21 +34,29 @@ https://docs.gimp.org/2.6/en/gimp-concepts-layer-modes.html
 #define TRANSFER_REPLACE       5
 #define TRANSFER_MAX           6
 #define TRANSFER_MIN           7
-#define TRANSFER_AVERAGE       8
-#define TRANSFER_DARKEN                9
-#define TRANSFER_LIGHTEN       10
-#define TRANSFER_DST           11
-#define TRANSFER_DST_ATOP      12
-#define TRANSFER_DST_IN                13
-#define TRANSFER_DST_OUT       14
-#define TRANSFER_DST_OVER      15
-#define TRANSFER_SRC           16
-#define TRANSFER_SRC_ATOP      17
-#define TRANSFER_SRC_IN                18
-#define TRANSFER_SRC_OUT       19
-#define TRANSFER_SRC_OVER      20
+#define TRANSFER_DARKEN                8
+#define TRANSFER_LIGHTEN       9
+#define TRANSFER_DST           10
+#define TRANSFER_DST_ATOP      11
+#define TRANSFER_DST_IN                12
+#define TRANSFER_DST_OUT       13
+#define TRANSFER_DST_OVER      14
+#define TRANSFER_SRC           15
+#define TRANSFER_SRC_ATOP      16
+#define TRANSFER_SRC_IN                17
+#define TRANSFER_SRC_OUT       18
+#define TRANSFER_SRC_OVER      19
+#define TRANSFER_AND           20
 #define TRANSFER_OR            21
 #define TRANSFER_XOR           22
+#define TRANSFER_OVERLAY       23
+#define TRANSFER_SCREEN                24
+#define TRANSFER_BURN          25
+#define TRANSFER_DODGE         26
+#define TRANSFER_HARDLIGHT     27
+#define TRANSFER_SOFTLIGHT     28
+#define TRANSFER_DIFFERENCE    29
+
 
 // Interpolation types
 
diff --git a/cinelerra-5.1/cinelerra/overlaynearest.C b/cinelerra-5.1/cinelerra/overlaynearest.C
new file mode 100644 (file)
index 0000000..e4a842d
--- /dev/null
@@ -0,0 +1,195 @@
+#include "overlayframe.h"
+
+/* Nearest Neighbor scale / translate / blend ********************/
+
+#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(); \
+       ox *= components; \
+ \
+       for(int i = pkg->out_row1; i < pkg->out_row2; i++) { \
+               int *lx = engine->in_lookup_x; \
+               type* in_row = input_rows[*ly++]; \
+               type* output = output_rows[i] + ox; \
+               for(int j = 0; j < ow; j++) { \
+                       in_row += *lx++; \
+                       if( components == 4 ) { \
+                               temp_type r, g, b, a; \
+                               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, ofs, ofs, round); \
+                               ALPHA3_STORE(output, ofs, max); \
+                       } \
+                       output += components; \
+               } \
+       } \
+       break; \
+}
+
+#define XBLEND_NN(FN) { \
+       switch(input->get_color_model()) { \
+       case BC_RGB_FLOAT:      XBLEND_3NN(FN, z_float,   z_float,    1.f,    3, 0,       0.f); \
+       case BC_RGBA_FLOAT:     XBLEND_3NN(FN, z_float,   z_float,    1.f,    4, 0,       0.f); \
+       case BC_RGB888:         XBLEND_3NN(FN, z_int32_t, z_uint8_t,  0xff,   3, 0,      .5f); \
+       case BC_YUV888:         XBLEND_3NN(FN, z_int32_t, z_uint8_t,  0xff,   3, 0x80,   .5f); \
+       case BC_RGBA8888:       XBLEND_3NN(FN, z_int32_t, z_uint8_t,  0xff,   4, 0,      .5f); \
+       case BC_YUVA8888:       XBLEND_3NN(FN, z_int32_t, z_uint8_t,  0xff,   4, 0x80,   .5f); \
+       case BC_RGB161616:      XBLEND_3NN(FN, z_int64_t, z_uint16_t, 0xffff, 3, 0,      .5f); \
+       case BC_YUV161616:      XBLEND_3NN(FN, z_int64_t, z_uint16_t, 0xffff, 3, 0x8000, .5f); \
+       case BC_RGBA16161616:   XBLEND_3NN(FN, z_int64_t, z_uint16_t, 0xffff, 4, 0,      .5f); \
+       case BC_YUVA16161616:   XBLEND_3NN(FN, z_int64_t, z_uint16_t, 0xffff, 4, 0x8000, .5f); \
+       } \
+       break; \
+}
+
+NNPackage::NNPackage()
+{
+}
+
+NNUnit::NNUnit(NNEngine *server)
+ : LoadClient(server)
+{
+       this->engine = server;
+}
+
+NNUnit::~NNUnit()
+{
+}
+
+void NNUnit::process_package(LoadPackage *package)
+{
+       NNPackage *pkg = (NNPackage*)package;
+       VFrame *output = engine->output;
+       VFrame *input = engine->input;
+       int mode = engine->mode;
+       float fade =
+               BC_CModels::has_alpha(input->get_color_model()) &&
+               mode == TRANSFER_REPLACE ? 1.f : engine->alpha;
+
+       int ox = engine->out_x1i;
+       int ow = engine->out_x2i - ox;
+       int *ly = engine->in_lookup_y + pkg->out_row1;
+
+       BLEND_SWITCH(XBLEND_NN);
+}
+
+NNEngine::NNEngine(int cpus)
+ : LoadServer(cpus, cpus)
+{
+       in_lookup_x = 0;
+       in_lookup_y = 0;
+}
+
+NNEngine::~NNEngine()
+{
+       if(in_lookup_x)
+               delete[] in_lookup_x;
+       if(in_lookup_y)
+               delete[] in_lookup_y;
+}
+
+void NNEngine::init_packages()
+{
+       int in_w = input->get_w();
+       int in_h = input->get_h();
+       int out_w = output->get_w();
+       int out_h = output->get_h();
+
+       float in_subw = in_x2 - in_x1;
+       float in_subh = in_y2 - in_y1;
+       float out_subw = out_x2 - out_x1;
+       float out_subh = out_y2 - out_y1;
+       int first, last, count, i;
+       int components = 3;
+
+       out_x1i = rint(out_x1);
+       out_x2i = rint(out_x2);
+       if(out_x1i < 0) out_x1i = 0;
+       if(out_x1i > out_w) out_x1i = out_w;
+       if(out_x2i < 0) out_x2i = 0;
+       if(out_x2i > out_w) out_x2i = out_w;
+       int out_wi = out_x2i - out_x1i;
+       if( !out_wi ) return;
+
+       delete[] in_lookup_x;
+       in_lookup_x = new int[out_wi];
+       delete[] in_lookup_y;
+       in_lookup_y = new int[out_h];
+
+       switch(input->get_color_model()) {
+       case BC_RGBA_FLOAT:
+       case BC_RGBA8888:
+       case BC_YUVA8888:
+       case BC_RGBA16161616:
+               components = 4;
+               break;
+       }
+
+       first = count = 0;
+
+       for(i = out_x1i; i < out_x2i; i++) {
+               int in = (i - out_x1 + .5) * in_subw / out_subw + in_x1;
+               if(in < in_x1)
+                       in = in_x1;
+               if(in > in_x2)
+                       in = in_x2;
+
+               if(in >= 0 && in < in_w && in >= in_x1 && i >= 0 && i < out_w) {
+                       if(count == 0) {
+                               first = i;
+                               in_lookup_x[0] = in * components;
+                       }
+                       else {
+                               in_lookup_x[count] = (in-last)*components;
+                       }
+                       last = in;
+                       count++;
+               }
+               else if(count)
+                       break;
+       }
+       out_x1i = first;
+       out_x2i = first + count;
+       first = count = 0;
+
+       for(i = out_y1; i < out_y2; i++) {
+               int in = (i - out_y1+.5) * in_subh / out_subh + in_y1;
+               if(in < in_y1) in = in_y1;
+               if(in > in_y2) in = in_y2;
+               if(in >= 0 && in < in_h && i >= 0 && i < out_h) {
+                       if(count == 0) first = i;
+                       in_lookup_y[i] = in;
+                       count++;
+               }
+               else if(count)
+                       break;
+       }
+       out_y1 = first;
+       out_y2 = first + count;
+
+       int rows = count;
+       int pkgs = get_total_packages();
+       int row1 = out_y1, row2 = row1;
+       for(int i = 0; i < pkgs; row1=row2 ) {
+               NNPackage *package = (NNPackage*)get_package(i);
+               row2 = ++i * rows / pkgs + out_y1;
+               package->out_row1 = row1;
+               package->out_row2 = row2;
+       }
+}
+
+LoadClient* NNEngine::new_client()
+{
+       return new NNUnit(this);
+}
+
+LoadPackage* NNEngine::new_package()
+{
+       return new NNPackage;
+}
+
+
diff --git a/cinelerra-5.1/cinelerra/overlaysample.C b/cinelerra-5.1/cinelerra/overlaysample.C
new file mode 100644 (file)
index 0000000..4907159
--- /dev/null
@@ -0,0 +1,288 @@
+#include "overlayframe.h"
+
+/* Fully resampled scale / translate / blend ******************************/
+/* resample into a temporary row vector, then blend */
+
+#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; \
+       type **input_rows = (type**)vinput->get_rows(); \
+ \
+       for(int i = pkg->out_col1; i < pkg->out_col2; i++) { \
+               type *input = input_rows[i - engine->col_out1 + engine->row_in]; \
+               float *tempp = temp; \
+               if( !k ) { /* direct copy case */ \
+                       type *ip = input + i1i * components; \
+                       for(int j = 0; j < oh; j++) { \
+                               *tempp++ = *ip++; \
+                               *tempp++ = *ip++ - ofs; \
+                               *tempp++ = *ip++ - ofs; \
+                               if( components == 4 ) *tempp++ = *ip++; \
+                       } \
+               } \
+               else { /* resample */ \
+                       for(int j = 0; j < oh; j++) { \
+                               float racc=0.f, gacc=0.f, bacc=0.f, aacc=0.f; \
+                               int ki = lookup_sk[j], x = lookup_sx0[j]; \
+                               type *ip = input + x * components; \
+                               float wacc = 0, awacc = 0; \
+                               while(x++ < lookup_sx1[j]) { \
+                                       float kv = k[abs(ki >> INDEX_FRACTION)]; \
+                                       /* handle fractional pixels on edges of input */ \
+                                       if(x == i1i) kv *= i1f; \
+                                       if(x + 1 == i2i) kv *= i2f; \
+                                       if( components == 4 ) { awacc += kv;  kv *= ip[3]; } \
+                                       wacc += kv; \
+                                       racc += kv * *ip++; \
+                                       gacc += kv * (*ip++ - ofs); \
+                                       bacc += kv * (*ip++ - ofs); \
+                                       if( components == 4 ) { aacc += kv;  ++ip; } \
+                                       ki += kd; \
+                               } \
+                               if(wacc > 0.) wacc = 1. / wacc; \
+                               *tempp++ = racc * wacc; \
+                               *tempp++ = gacc * wacc; \
+                               *tempp++ = bacc * wacc; \
+                               if( components == 4 ) { \
+                                       if(awacc > 0.) awacc = 1. / awacc; \
+                                       *tempp++ = aacc * awacc; \
+                               } \
+                       } \
+               } \
+ \
+               /* handle fractional pixels on edges of output */ \
+               temp[0] *= o1f;   temp[1] *= o1f;   temp[2] *= o1f; \
+               if( components == 4 ) temp[3] *= o1f; \
+               tempp = temp + (oh-1)*components; \
+               tempp[0] *= o2f;  tempp[1] *= o2f;  tempp[2] *= o2f; \
+               if( components == 4 ) tempp[3] *= o2f; \
+               tempp = temp; \
+               /* blend output */ \
+               for(int j = 0; j < oh; j++) { \
+                       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, ofs, round); \
+                               ALPHA4_STORE(output, ofs, max); \
+                       } \
+                       else { \
+                               temp_type r, g, b; \
+                               ALPHA3_BLEND(FN, temp_type, tempp, output, max, 0, ofs, round); \
+                               ALPHA3_STORE(output, ofs, max); \
+                       } \
+                       tempp += components; \
+               } \
+       } \
+       break; \
+}
+
+#define XBLEND_SAMPLE(FN) { \
+        switch(vinput->get_color_model()) { \
+        case BC_RGB_FLOAT:      XSAMPLE(FN, z_float,   z_float,    1.f,    3, 0.f,    0.f); \
+        case BC_RGBA_FLOAT:     XSAMPLE(FN, z_float,   z_float,    1.f,    4, 0.f,    0.f); \
+        case BC_RGB888:         XSAMPLE(FN, z_int32_t, z_uint8_t,  0xff,   3, 0,      .5f); \
+        case BC_YUV888:         XSAMPLE(FN, z_int32_t, z_uint8_t,  0xff,   3, 0x80,   .5f); \
+        case BC_RGBA8888:       XSAMPLE(FN, z_int32_t, z_uint8_t,  0xff,   4, 0,      .5f); \
+        case BC_YUVA8888:       XSAMPLE(FN, z_int32_t, z_uint8_t,  0xff,   4, 0x80,   .5f); \
+        case BC_RGB161616:      XSAMPLE(FN, z_int64_t, z_uint16_t, 0xffff, 3, 0,      .5f); \
+        case BC_YUV161616:      XSAMPLE(FN, z_int64_t, z_uint16_t, 0xffff, 3, 0x8000, .5f); \
+        case BC_RGBA16161616:   XSAMPLE(FN, z_int64_t, z_uint16_t, 0xffff, 4, 0,      .5f); \
+        case BC_YUVA16161616:   XSAMPLE(FN, z_int64_t, z_uint16_t, 0xffff, 4, 0x8000, .5f); \
+        } \
+        break; \
+}
+
+
+SamplePackage::SamplePackage()
+{
+}
+
+SampleUnit::SampleUnit(SampleEngine *server)
+ : LoadClient(server)
+{
+       this->engine = server;
+}
+
+SampleUnit::~SampleUnit()
+{
+}
+
+void SampleUnit::process_package(LoadPackage *package)
+{
+       SamplePackage *pkg = (SamplePackage*)package;
+
+       float i1  = engine->in1;
+       float i2  = engine->in2;
+       float o1  = engine->out1;
+       float o2  = engine->out2;
+
+       if(i2 - i1 <= 0 || o2 - o1 <= 0)
+               return;
+
+       VFrame *voutput = engine->output;
+       VFrame *vinput = engine->input;
+       int mode = engine->mode;
+       float fade =
+               BC_CModels::has_alpha(vinput->get_color_model()) &&
+               mode == TRANSFER_REPLACE ? 1.f : engine->alpha;
+
+       //int   iw  = vinput->get_w();
+       int   i1i = floor(i1);
+       int   i2i = ceil(i2);
+       float i1f = 1.f - i1 + i1i;
+       float i2f = 1.f - i2i + i2;
+
+       int   o1i = floor(o1);
+       int   o2i = ceil(o2);
+       float o1f = 1.f - o1 + o1i;
+       float o2f = 1.f - o2i + o2;
+       int   oh  = o2i - o1i;
+
+       float *k  = engine->kernel->lookup;
+       //float kw  = engine->kernel->width;
+       //int   kn  = engine->kernel->n;
+       int   kd = engine->kd;
+
+       int *lookup_sx0 = engine->lookup_sx0;
+       int *lookup_sx1 = engine->lookup_sx1;
+       int *lookup_sk = engine->lookup_sk;
+       //float *lookup_wacc = engine->lookup_wacc;
+
+       BLEND_SWITCH(XBLEND_SAMPLE);
+}
+
+
+SampleEngine::SampleEngine(int cpus)
+ : LoadServer(cpus, cpus)
+{
+       lookup_sx0 = 0;
+       lookup_sx1 = 0;
+       lookup_sk = 0;
+       lookup_wacc = 0;
+       kd = 0;
+}
+
+SampleEngine::~SampleEngine()
+{
+       if(lookup_sx0) delete [] lookup_sx0;
+       if(lookup_sx1) delete [] lookup_sx1;
+       if(lookup_sk) delete [] lookup_sk;
+       if(lookup_wacc) delete [] lookup_wacc;
+}
+
+/*
+ * unlike the Direct and NN engines, the Sample engine works across
+ * output columns (it makes for more economical memory addressing
+ * during convolution)
+ */
+void SampleEngine::init_packages()
+{
+       int   iw  = input->get_w();
+       int   i1i = floor(in1);
+       int   i2i = ceil(in2);
+       float i1f = 1.f - in1 + i1i;
+       float i2f = 1.f - i2i + in2;
+
+       int   oy  = floor(out1);
+       float oyf = out1 - oy;
+       int   oh  = ceil(out2) - oy;
+
+       float *k  = kernel->lookup;
+       float kw  = kernel->width;
+       int   kn  = kernel->n;
+
+       if(in2 - in1 <= 0 || out2 - out1 <= 0)
+               return;
+
+       /* determine kernel spatial coverage */
+       float scale = (out2 - out1) / (in2 - in1);
+       float iscale = (in2 - in1) / (out2 - out1);
+       float coverage = fabs(1.f / scale);
+       float bound = (coverage < 1.f ? kw : kw * coverage) - (.5f / TRANSFORM_SPP);
+       float coeff = (coverage < 1.f ? 1.f : scale) * TRANSFORM_SPP;
+
+       delete [] lookup_sx0;
+       delete [] lookup_sx1;
+       delete [] lookup_sk;
+       delete [] lookup_wacc;
+
+       lookup_sx0 = new int[oh];
+       lookup_sx1 = new int[oh];
+       lookup_sk = new int[oh];
+       lookup_wacc = new float[oh];
+
+       kd = (double)coeff * (1 << INDEX_FRACTION) + .5;
+
+       /* precompute kernel values and weight sums */
+       for(int i = 0; i < oh; i++) {
+               /* map destination back to source */
+               double sx = (i - oyf + .5) * iscale + in1 - .5;
+
+               /*
+                * clip iteration to source area but not source plane. Points
+                * outside the source plane count as transparent. Points outside
+                * the source area don't count at all.  The actual convolution
+                * later will be clipped to both, but we need to compute
+                * weights.
+                */
+               int sx0 = mmax((int)floor(sx - bound) + 1, i1i);
+               int sx1 = mmin((int)ceil(sx + bound), i2i);
+               int ki = (double)(sx0 - sx) * coeff * (1 << INDEX_FRACTION)
+                               + (1 << (INDEX_FRACTION - 1)) + .5;
+               float wacc=0.;
+
+               lookup_sx0[i] = -1;
+               lookup_sx1[i] = -1;
+
+               for(int j= sx0; j < sx1; j++) {
+                       int kv = (ki >> INDEX_FRACTION);
+                       if(kv > kn) break;
+                       if(kv >= -kn) {
+                               /*
+                                * the contribution of the first and last input pixel (if
+                                * fractional) are linearly weighted by the fraction
+                                */
+                               if(j == i1i)
+                                       wacc += k[abs(kv)] * i1f;
+                               else if(j + 1 == i2i)
+                                       wacc += k[abs(kv)] * i2f;
+                               else
+                                       wacc += k[abs(kv)];
+
+                               /* this is where we clip the kernel convolution to the source plane */
+                               if(j >= 0 && j < iw) {
+                                       if(lookup_sx0[i] == -1) {
+                                               lookup_sx0[i] = j;
+                                               lookup_sk[i] = ki;
+                                       }
+                                       lookup_sx1[i] = j + 1;
+                               }
+                       }
+                       ki += kd;
+               }
+               lookup_wacc[i] = wacc > 0. ? 1. / wacc : 0.;
+       }
+
+       int cols = col_out2 - col_out1;
+       int pkgs = get_total_packages();
+       int col1 = col_out1, col2 = col1;
+       for(int i = 0; i < pkgs; col1=col2 ) {
+               SamplePackage *package = (SamplePackage*)get_package(i);
+               col2 = ++i * cols / pkgs + col_out1;
+               package->out_col1 = col1;
+               package->out_col2 = col2;
+       }
+}
+
+LoadClient* SampleEngine::new_client()
+{
+       return new SampleUnit(this);
+}
+
+LoadPackage* SampleEngine::new_package()
+{
+       return new SamplePackage;
+}
+
+
index cb6c0c64214084f556587e9a31a28be6c9782dee..3292eeb5543911fe576d85f51b266b77d4de1e75 100644 (file)
@@ -192,7 +192,6 @@ void PatchBay::create_objects()
                "mode_replace",
                "mode_max",
                "mode_min",
-               "mode_average",
                "mode_darken",
                "mode_lighten",
                "mode_dst",
@@ -205,8 +204,16 @@ void PatchBay::create_objects()
                "mode_srcin",
                "mode_srcout",
                "mode_srcover",
+               "mode_and",
                "mode_or",
                "mode_xor",
+               "mode_overlay",
+               "mode_screen",
+               "mode_burn",
+               "mode_dodge",
+               "mode_hardlight",
+               "mode_softlight",
+               "mode_difference",
        };
        for( int mode=0; mode<TRANSFER_TYPES; ++mode ) {
                mode_icons[mode] = new BC_Pixmap(this,
index 3b9cd6901edb6cf3461a808713693c2a95c66faf..c2e015e24d5fc653d8fb0041682c821efb077589 100644 (file)
@@ -30,6 +30,7 @@
 #include "maskauto.h"
 #include "mutex.h"
 #include "overlayframe.inc"
+#include "overlayframe.h"
 #include "playback3d.h"
 #include "pluginclient.h"
 #include "pluginvclient.h"
@@ -46,6 +47,8 @@
 #include <unistd.h>
 #include <fcntl.h>
 
+#define QQ(q)#q
+#define SS(s)QQ(s)
 
 
 // Shaders
@@ -144,8 +147,51 @@ static const char *rgba_to_rgb_flatten =
        "       gl_FragColor.a = 1.0;\n"
        "}\n";
 
+#define GL_STD_BLEND(FN) \
+static const char *blend_##FN##_frag = \
+       "uniform sampler2D tex2;\n" \
+       "uniform vec2 tex2_dimensions;\n" \
+       "uniform float alpha;\n" \
+       "void main() {\n" \
+       "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" \
+       "       vec4 result;\n" \
+       "       result.rgb = "SS(COLOR_##FN(1.0, gl_FragColor.rgb, gl_FragColor.a, canvas.rgb, canvas.a))";\n" \
+       "       result.a = "SS(ALPHA_##FN(1.0, gl_FragColor.a, canvas.a))";\n" \
+       "       gl_FragColor = mix(canvas, result, alpha);\n" \
+       "}\n"
+
+#define GL_VEC_BLEND(FN) \
+static const char *blend_##FN##_frag = \
+       "uniform sampler2D tex2;\n" \
+       "uniform vec2 tex2_dimensions;\n" \
+       "uniform float alpha;\n" \
+       "void main() {\n" \
+       "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" \
+       "       vec4 result;\n" \
+       "       result.r = "SS(COLOR_##FN(1.0, gl_FragColor.r, gl_FragColor.a, canvas.r, canvas.a))";\n" \
+       "       result.g = "SS(COLOR_##FN(1.0, gl_FragColor.g, gl_FragColor.a, canvas.g, canvas.a))";\n" \
+       "       result.b = "SS(COLOR_##FN(1.0, gl_FragColor.b, gl_FragColor.a, canvas.b, canvas.a))";\n" \
+       "       result.a = "SS(ALPHA_##FN(1.0, gl_FragColor.a, canvas.a))";\n" \
+       "       result = clamp(result, 0.0, 1.0);\n" \
+       "       gl_FragColor = mix(canvas, result, alpha);\n" \
+       "}\n"
+
+#undef mabs
+#define mabs abs
+#undef mmin
+#define mmin min
+#undef mmax
+#define mmax max
+
+#undef ZERO
+#define ZERO 0.0
+#undef ONE
+#define ONE 1.0
+#undef TWO
+#define TWO 2.0
+
 // NORMAL
-static const char *blend_normal_frag =
+static const char *blend_NORMAL_frag =
        "uniform sampler2D tex2;\n"
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
@@ -155,264 +201,60 @@ static const char *blend_normal_frag =
        "       gl_FragColor = mix(canvas, result, alpha);\n"
        "}\n";
 
-// ADDITION
-static const char *blend_add_frag =
-       "uniform sampler2D tex2;\n"
-       "uniform vec2 tex2_dimensions;\n"
-       "uniform float alpha;\n"
-       "void main() {\n"
-       "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "       vec4 result = canvas + gl_FragColor;\n"
-       "       result = clamp(result, 0.0, 1.0);\n"
-       "       gl_FragColor = mix(canvas, result, alpha);\n"
-       "}\n";
-
-// SUBTRACT
-static const char *blend_subtract_frag =
-       "uniform sampler2D tex2;\n"
-       "uniform vec2 tex2_dimensions;\n"
-       "uniform float alpha;\n"
-       "void main() {\n"
-       "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "       vec4 result = gl_FragColor - canvas;\n"
-       "       result = clamp(result, 0.0, 1.0);\n"
-       "       gl_FragColor = mix(canvas, result, alpha);\n"
-       "}\n";
-
-// MULTIPLY
-static const char *blend_multiply_frag =
-       "uniform sampler2D tex2;\n"
-       "uniform vec2 tex2_dimensions;\n"
-       "uniform float alpha;\n"
-       "void main() {\n"
-       "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "       vec4 result = canvas * gl_FragColor;\n"
-       "       gl_FragColor = mix(canvas, result, alpha);\n"
-       "}\n";
-
-// DIVIDE
-static const char *blend_divide_frag =
-       "uniform sampler2D tex2;\n"
-       "uniform vec2 tex2_dimensions;\n"
-       "uniform float alpha;\n"
-       "void main() {\n"
-       "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "       vec4 result = gl_FragColor / canvas;\n"
-       "       if(canvas.r == 0.) result.r = 1.0;\n"
-       "       if(canvas.g == 0.) result.g = 1.0;\n"
-       "       if(canvas.b == 0.) result.b = 1.0;\n"
-       "       if(canvas.a == 0.) result.a = 1.0;\n"
-       "       result = clamp(result, 0.0, 1.0);\n"
-       "       gl_FragColor = mix(canvas, result, alpha);\n"
-       "}\n";
-
 // REPLACE
-static const char *blend_replace_frag =
-       "uniform float alpha;\n"
-       "void main() {\n"
-       "}\n";
-
-// MAX
-static const char *blend_max_frag =
-       "uniform sampler2D tex2;\n"
-       "uniform vec2 tex2_dimensions;\n"
-       "uniform float alpha;\n"
-       "void main() {\n"
-       "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "       vec4 result = max(canvas, gl_FragColor);\n"
-       "       gl_FragColor = mix(canvas, result, alpha);\n"
-       "}\n";
-
-// MIN
-static const char *blend_min_frag =
-       "uniform sampler2D tex2;\n"
-       "uniform vec2 tex2_dimensions;\n"
-       "uniform float alpha;\n"
-       "void main() {\n"
-       "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "       vec4 result = min(canvas, gl_FragColor);\n"
-       "       gl_FragColor = mix(canvas, result, alpha);\n"
-       "}\n";
-
-// AVERAGE
-static const char *blend_average_frag =
-       "uniform sampler2D tex2;\n"
-       "uniform vec2 tex2_dimensions;\n"
-       "uniform float alpha;\n"
-       "void main() {\n"
-       "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "       vec4 result = (canvas + gl_FragColor) * 0.5;\n"
-       "       gl_FragColor = mix(canvas, result, alpha);\n"
-       "}\n";
-
-// DARKEN
-static const char *blend_darken_frag =
-       "uniform sampler2D tex2;\n"
-       "uniform vec2 tex2_dimensions;\n"
-       "uniform float alpha;\n"
-       "void main() {\n"
-       "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "       vec4 result = vec4(canvas.rgb * (1.0 - gl_FragColor.a) +"
-                       " gl_FragColor.rgb * (1.0 - canvas.a) +"
-                       " min(canvas.rgb, gl_FragColor.rgb), "
-                       " canvas.a + gl_FragColor.a - canvas.a * gl_FragColor.a);\n"
-       "       result = clamp(result, 0.0, 1.0);\n"
-       "       gl_FragColor = mix(canvas, result, alpha);\n"
-       "}\n";
-
-// LIGHTEN
-static const char *blend_lighten_frag =
-       "uniform sampler2D tex2;\n"
-       "uniform vec2 tex2_dimensions;\n"
-       "uniform float alpha;\n"
-       "void main() {\n"
-       "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "       vec4 result = vec4(canvas.rgb * (1.0 - gl_FragColor.a) +"
-                       " gl_FragColor.rgb * (1.0 - canvas.a) +"
-                       " max(canvas.rgb, gl_FragColor.rgb), "
-                       " canvas.a + gl_FragColor.a - canvas.a * gl_FragColor.a);\n"
-       "       result = clamp(result, 0.0, 1.0);\n"
-       "       gl_FragColor = mix(canvas, result, alpha);\n"
-       "}\n";
-
-// DST
-static const char *blend_dst_frag =
-       "uniform sampler2D tex2;\n"
-       "uniform vec2 tex2_dimensions;\n"
-       "uniform float alpha;\n"
-       "void main() {\n"
-//     "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-//     "       vec4 result = canvas;\n"
-//     "       gl_FragColor = mix(result, canvas, alpha);\n"
-       "       gl_FragColor = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "}\n";
-
-// DST_ATOP
-static const char *blend_dst_atop_frag =
-       "uniform sampler2D tex2;\n"
-       "uniform vec2 tex2_dimensions;\n"
+static const char *blend_REPLACE_frag =
        "uniform float alpha;\n"
        "void main() {\n"
-       "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "       vec4 result = vec4(canvas.rgb * gl_FragColor.a + "
-                       "(1.0 - canvas.a) * gl_FragColor.rgb, gl_FragColor.a);\n"
-       "       gl_FragColor = mix(canvas, result, alpha);\n"
-       "}\n";
-
-// DST_IN
-static const char *blend_dst_in_frag =
-       "uniform sampler2D tex2;\n"
-       "uniform vec2 tex2_dimensions;\n"
-       "uniform float alpha;\n"
-       "void main() {\n"
-       "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "       vec4 result = canvas * gl_FragColor.a;\n"
-       "       gl_FragColor = mix(canvas, result, alpha);\n"
        "}\n";
 
-// DST_OUT
-static const char *blend_dst_out_frag =
-       "uniform sampler2D tex2;\n"
-       "uniform vec2 tex2_dimensions;\n"
-       "uniform float alpha;\n"
-       "void main() {\n"
-       "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "       vec4 result = canvas * (1.0 - gl_FragColor.a);\n"
-       "       gl_FragColor = mix(canvas, result, alpha);\n"
-       "}\n";
-
-// DST_OVER
-static const char *blend_dst_over_frag =
-       "uniform sampler2D tex2;\n"
-       "uniform vec2 tex2_dimensions;\n"
-       "uniform float alpha;\n"
-       "void main() {\n"
-       "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "       vec4 result = vec4(canvas.rgb + (1.0 - canvas.a) * gl_FragColor.rgb, "
-                       " gl_FragColor.a + canvas.a - gl_FragColor.a * canvas.a);\n"
-       "       gl_FragColor = mix(canvas, result, alpha);\n"
-       "}\n";
-
-// SRC
-static const char *blend_src_frag =
-       "uniform sampler2D tex2;\n"
-       "uniform vec2 tex2_dimensions;\n"
-       "uniform float alpha;\n"
-       "void main() {\n"
-       "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "       vec4 result = gl_FragColor;\n"
-       "       gl_FragColor = mix(canvas, result, alpha);\n"
-       "}\n";
-
-// SRC_ATOP
-static const char *blend_src_atop_frag =
-       "uniform sampler2D tex2;\n"
-       "uniform vec2 tex2_dimensions;\n"
-       "uniform float alpha;\n"
-       "void main() {\n"
-       "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "       vec4 result = vec4(gl_FragColor.rgb * canvas.a + "
-                       "canvas.rgb * (1.0 - gl_FragColor.a), canvas.a);\n"
-       "       gl_FragColor = mix(canvas, result, alpha);\n"
-       "}\n";
-
-// SRC_IN
-static const char *blend_src_in_frag =
-       "uniform sampler2D tex2;\n"
-       "uniform vec2 tex2_dimensions;\n"
-       "uniform float alpha;\n"
-       "void main() {\n"
-       "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "       vec4 result = gl_FragColor * canvas.a;\n"
-       "       gl_FragColor = mix(canvas, result, alpha);\n"
-       "}\n";
-
-// SRC_OUT
-static const char *blend_src_out_frag =
-       "uniform sampler2D tex2;\n"
-       "uniform vec2 tex2_dimensions;\n"
-       "uniform float alpha;\n"
-       "void main() {\n"
-       "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "       vec4 result = gl_FragColor * (1.0 - canvas.a);\n"
-       "       gl_FragColor = mix(canvas, result, alpha);\n"
-       "}\n";
-
-// SRC_OVER
-static const char *blend_src_over_frag =
+// ADDITION
+static const char *blend_ADDITION_frag =
        "uniform sampler2D tex2;\n"
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "       vec4 result = vec4(gl_FragColor.rgb + (1.0 - gl_FragColor.a) * canvas.rgb, "
-                               "gl_FragColor.a + canvas.a - gl_FragColor.a * canvas.a);\n"
+       "       vec4 result = clamp(gl_FragColor + canvas, 0.0, 1.0);\n"
        "       gl_FragColor = mix(canvas, result, alpha);\n"
        "}\n";
 
-// OR
-static const char *blend_or_frag =
+// SUBTRACT
+static const char *blend_SUBTRACT_frag =
        "uniform sampler2D tex2;\n"
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "       vec4 result = canvas + gl_FragColor - canvas * gl_FragColor;\n"
+       "       vec4 result = clamp(gl_FragColor - canvas, 0.0, 1.0);\n"
        "       gl_FragColor = mix(canvas, result, alpha);\n"
        "}\n";
 
-// XOR
-static const char *blend_xor_frag =
-       "uniform sampler2D tex2;\n"
-       "uniform vec2 tex2_dimensions;\n"
-       "uniform float alpha;\n"
-       "void main() {\n"
-       "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "       vec4 result = vec4(gl_FragColor.rgb * (1.0 - canvas.a) + "
-                       "(1.0 - gl_FragColor.a) * canvas.rgb, "
-                       "gl_FragColor.a + canvas.a - 2.0 * gl_FragColor.a * canvas.a);\n"
-       "       gl_FragColor = mix(canvas, result, alpha);\n"
-       "}\n";
+GL_STD_BLEND(MULTIPLY);
+GL_VEC_BLEND(DIVIDE);
+GL_VEC_BLEND(MAX);
+GL_VEC_BLEND(MIN);
+GL_VEC_BLEND(DARKEN);
+GL_VEC_BLEND(LIGHTEN);
+GL_STD_BLEND(DST);
+GL_STD_BLEND(DST_ATOP);
+GL_STD_BLEND(DST_IN);
+GL_STD_BLEND(DST_OUT);
+GL_STD_BLEND(DST_OVER);
+GL_STD_BLEND(SRC);
+GL_STD_BLEND(SRC_ATOP);
+GL_STD_BLEND(SRC_IN);
+GL_STD_BLEND(SRC_OUT);
+GL_STD_BLEND(SRC_OVER);
+GL_STD_BLEND(AND);
+GL_STD_BLEND(OR);
+GL_STD_BLEND(XOR);
+GL_VEC_BLEND(OVERLAY);
+GL_STD_BLEND(SCREEN);
+GL_VEC_BLEND(BURN);
+GL_VEC_BLEND(DODGE);
+GL_VEC_BLEND(HARDLIGHT);
+GL_VEC_BLEND(SOFTLIGHT);
+GL_VEC_BLEND(DIFFERENCE);
 
 static const char *read_texture_frag =
        "uniform sampler2D tex;\n"
@@ -1082,29 +924,36 @@ void Playback3D::overlay_sync(Playback3DCommand *command)
 // To do these operations, we need to copy the input buffer to a texture
 // and blend 2 textures in a shader
        static const char * const overlay_shaders[TRANSFER_TYPES] = {
-               blend_normal_frag,      // TRANSFER_NORMAL
-               blend_add_frag,         // TRANSFER_ADDITION
-               blend_subtract_frag,    // TRANSFER_SUBTRACT
-               blend_multiply_frag,    // TRANSFER_MULTIPLY
-               blend_divide_frag,      // TRANSFER_DIVIDE
-               blend_replace_frag,     // TRANSFER_REPLACE
-               blend_max_frag,         // TRANSFER_MAX
-               blend_min_frag,         // TRANSFER_MIN
-               blend_average_frag,     // TRANSFER_AVERAGE
-               blend_darken_frag,      // TRANSFER_DARKEN
-               blend_lighten_frag,     // TRANSFER_LIGHTEN
-               blend_dst_frag,         // TRANSFER_DST
-               blend_dst_atop_frag,    // TRANSFER_DST_ATOP
-               blend_dst_in_frag,      // TRANSFER_DST_IN
-               blend_dst_out_frag,     // TRANSFER_DST_OUT
-               blend_dst_over_frag,    // TRANSFER_DST_OVER
-               blend_src_frag,         // TRANSFER_SRC
-               blend_src_atop_frag,    // TRANSFER_SRC_ATOP
-               blend_src_in_frag,      // TRANSFER_SRC_IN
-               blend_src_out_frag,     // TRANSFER_SRC_OUT
-               blend_src_over_frag,    // TRANSFER_SRC_OVER
-               blend_or_frag,          // TRANSFER_OR
-               blend_xor_frag          // TRANSFER_XOR
+               blend_NORMAL_frag,      // TRANSFER_NORMAL
+               blend_ADDITION_frag,    // TRANSFER_ADDITION
+               blend_SUBTRACT_frag,    // TRANSFER_SUBTRACT
+               blend_MULTIPLY_frag,    // TRANSFER_MULTIPLY
+               blend_DIVIDE_frag,      // TRANSFER_DIVIDE
+               blend_REPLACE_frag,     // TRANSFER_REPLACE
+               blend_MAX_frag,         // TRANSFER_MAX
+               blend_MIN_frag,         // TRANSFER_MIN
+               blend_DARKEN_frag,      // TRANSFER_DARKEN
+               blend_LIGHTEN_frag,     // TRANSFER_LIGHTEN
+               blend_DST_frag,         // TRANSFER_DST
+               blend_DST_ATOP_frag,    // TRANSFER_DST_ATOP
+               blend_DST_IN_frag,      // TRANSFER_DST_IN
+               blend_DST_OUT_frag,     // TRANSFER_DST_OUT
+               blend_DST_OVER_frag,    // TRANSFER_DST_OVER
+               blend_SRC_frag,         // TRANSFER_SRC
+               blend_SRC_ATOP_frag,    // TRANSFER_SRC_ATOP
+               blend_SRC_IN_frag,      // TRANSFER_SRC_IN
+               blend_SRC_OUT_frag,     // TRANSFER_SRC_OUT
+               blend_SRC_OVER_frag,    // TRANSFER_SRC_OVER
+               blend_AND_frag,         // TRANSFER_AND
+               blend_OR_frag,          // TRANSFER_OR
+               blend_XOR_frag,         // TRANSFER_XOR
+               blend_OVERLAY_frag,     // TRANSFER_OVERLAY
+               blend_SCREEN_frag,      // TRANSFER_SCREEN
+               blend_BURN_frag,        // TRANSFER_BURN
+               blend_DODGE_frag,       // TRANSFER_DODGE
+               blend_HARDLIGHT_frag,   // TRANSFER_HARDLIGHT
+               blend_SOFTLIGHT_frag,   // TRANSFER_SOFTLIGHT
+               blend_DIFFERENCE_frag,  // TRANSFER_DIFFERENCE
        };
 
        command->canvas->lock_canvas("Playback3D::overlay_sync");
index d02f9ad44304704bfd90990a42367a9295ede31c..26c92c56e6bb37a0dc7cfb6df238a1f21554bfb1 100644 (file)
@@ -365,7 +365,7 @@ SET_TRACE
 
 PreferencesWindow::PreferencesWindow(MWindow *mwindow,
        PreferencesThread *thread, int x, int y, int w, int h)
- : BC_Window(_(PROGRAM_NAME ": Preferences"), x,y, w,h, 1,0,1)
+ : BC_Window(_(PROGRAM_NAME ": Preferences"), x,y, w,h,w,h, 1)
 {
        this->mwindow = mwindow;
        this->thread = thread;
index 6562a56c5be01016c1634d0dcc1a910620822c87..827d5b9eeaa049ddcf2b1903652c725c5bc4ae2a 100644 (file)
@@ -212,7 +212,6 @@ void Theme::initialize()
        new_image("mode_replace", "mode_replace.png");
        new_image("mode_max", "mode_max.png");
        new_image("mode_min", "mode_min.png");
-       new_image("mode_average", "mode_average.png");
        new_image("mode_darken", "mode_darken.png");
        new_image("mode_lighten", "mode_lighten.png");
        new_image("mode_dst", "mode_dst.png");
@@ -225,8 +224,16 @@ void Theme::initialize()
        new_image("mode_srcin", "mode_srcin.png");
        new_image("mode_srcout", "mode_srcout.png");
        new_image("mode_srcover", "mode_srcover.png");
+       new_image("mode_and", "mode_and.png");
        new_image("mode_or", "mode_or.png");
        new_image("mode_xor", "mode_xor.png");
+       new_image("mode_overlay", "mode_overlay.png");
+       new_image("mode_screen", "mode_screen.png");
+       new_image("mode_burn", "mode_burn.png");
+       new_image("mode_dodge", "mode_dodge.png");
+       new_image("mode_hardlight", "mode_hardlight.png");
+       new_image("mode_softlight", "mode_softlight.png");
+       new_image("mode_difference", "mode_difference.png");
 
        new_image_set("mode_popup", 3, "mode_up.png", "mode_hi.png", "mode_dn.png");
 
index 94e194d5ecc66818284ef39c97d38e016f48ad81..1d4c46fb26a3663f7badbc4475d6c0b8d9c00e5a 100644 (file)
@@ -332,8 +332,46 @@ int VModePatch::handle_event()
 
 void VModePatch::create_objects()
 {
-       for( int mode=0; mode<TRANSFER_TYPES; ++mode )
-               add_item(new VModePatchItem(this, mode_to_text(mode), mode));
+       VModePatchItem *mode_item;
+       VModePatchSubMenu *submenu;
+       add_item(mode_item = new VModePatchItem(this, mode_to_text(TRANSFER_NORMAL),  TRANSFER_NORMAL));
+       add_item(mode_item = new VModePatchItem(this, _("Arithmetic..."), -1));
+       mode_item->add_submenu(submenu = new VModePatchSubMenu(mode_item));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_ADDITION), TRANSFER_ADDITION));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SUBTRACT), TRANSFER_SUBTRACT));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DIVIDE),   TRANSFER_DIVIDE));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_MULTIPLY), TRANSFER_MULTIPLY));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_REPLACE),  TRANSFER_REPLACE));
+       add_item(mode_item = new VModePatchItem(this, _("PorterDuff..."), -1));
+       mode_item->add_submenu(submenu = new VModePatchSubMenu(mode_item));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DST),      TRANSFER_DST));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DST_ATOP), TRANSFER_DST_ATOP));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DST_IN),   TRANSFER_DST_IN));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DST_OUT),  TRANSFER_DST_OUT));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DST_OVER), TRANSFER_DST_OVER));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SRC),      TRANSFER_SRC));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SRC_ATOP), TRANSFER_SRC_ATOP));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SRC_IN),   TRANSFER_SRC_IN));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SRC_OUT),  TRANSFER_SRC_OUT));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SRC_OVER), TRANSFER_SRC_OVER));
+       add_item(mode_item = new VModePatchItem(this, _("Logical..."), -1));
+       mode_item->add_submenu(submenu = new VModePatchSubMenu(mode_item));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_MIN),      TRANSFER_MIN));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_MAX),      TRANSFER_MAX));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DARKEN),   TRANSFER_DARKEN));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_LIGHTEN),  TRANSFER_LIGHTEN));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_AND),      TRANSFER_AND));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_OR),       TRANSFER_OR));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_XOR),      TRANSFER_XOR));
+       add_item(mode_item = new VModePatchItem(this, _("graphic art..."), -1));
+       mode_item->add_submenu(submenu = new VModePatchSubMenu(mode_item));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_OVERLAY),  TRANSFER_OVERLAY));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SCREEN),   TRANSFER_SCREEN));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_BURN),     TRANSFER_BURN));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DODGE),    TRANSFER_DODGE));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_DIFFERENCE),TRANSFER_DIFFERENCE));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_HARDLIGHT),TRANSFER_HARDLIGHT));
+       submenu->add_submenuitem(new VModeSubMenuItem(submenu, mode_to_text(TRANSFER_SOFTLIGHT),TRANSFER_SOFTLIGHT));
 }
 
 void VModePatch::update(int mode)
@@ -343,6 +381,13 @@ void VModePatch::update(int mode)
        {
                VModePatchItem *item = (VModePatchItem*)get_item(i);
                item->set_checked(item->mode == mode);
+               VModePatchSubMenu *submenu = (VModePatchSubMenu *)item->get_submenu();
+               if( !submenu ) continue;
+               int n = submenu->total_items();
+               for( int j=0; j<n; ++j ) {
+                       VModePatchItem *subitem = (VModePatchItem*)submenu->get_item(j);
+                       subitem->set_checked(subitem->mode == mode);
+               }
        }
 }
 
@@ -350,29 +395,36 @@ void VModePatch::update(int mode)
 const char* VModePatch::mode_to_text(int mode)
 {
        switch(mode) {
-               case TRANSFER_NORMAL:           return _("Normal");
-               case TRANSFER_ADDITION:         return _("Addition");
-               case TRANSFER_SUBTRACT:         return _("Subtract");
-               case TRANSFER_MULTIPLY:         return _("Multiply");
-               case TRANSFER_DIVIDE:           return _("Divide");
-               case TRANSFER_REPLACE:          return _("Replace");
-               case TRANSFER_MAX:              return _("Max");
-               case TRANSFER_MIN:              return _("Min");
-               case TRANSFER_AVERAGE:          return _("Average");
-               case TRANSFER_DARKEN:           return _("Darken");
-               case TRANSFER_LIGHTEN:          return _("Lighten");
-               case TRANSFER_DST:              return _("Dst");
-               case TRANSFER_DST_ATOP:         return _("DstAtop");
-               case TRANSFER_DST_IN:           return _("DstIn");
-               case TRANSFER_DST_OUT:          return _("DstOut");
-               case TRANSFER_DST_OVER:         return _("DstOver");
-               case TRANSFER_SRC:              return _("Src");
-               case TRANSFER_SRC_ATOP:         return _("SrcAtop");
-               case TRANSFER_SRC_IN:           return _("SrcIn");
-               case TRANSFER_SRC_OUT:          return _("SrcOut");
-               case TRANSFER_SRC_OVER:         return _("SrcOver");
-               case TRANSFER_OR:               return _("Or");
-               case TRANSFER_XOR:              return _("Xor");
+       case TRANSFER_NORMAL:           return _("Normal");
+       case TRANSFER_ADDITION:         return _("Addition");
+       case TRANSFER_SUBTRACT:         return _("Subtract");
+       case TRANSFER_MULTIPLY:         return _("Multiply");
+       case TRANSFER_DIVIDE:           return _("Divide");
+       case TRANSFER_REPLACE:          return _("Replace");
+       case TRANSFER_MAX:              return _("Max");
+       case TRANSFER_MIN:              return _("Min");
+       case TRANSFER_DARKEN:           return _("Darken");
+       case TRANSFER_LIGHTEN:          return _("Lighten");
+       case TRANSFER_DST:              return _("Dst");
+       case TRANSFER_DST_ATOP:         return _("DstAtop");
+       case TRANSFER_DST_IN:           return _("DstIn");
+       case TRANSFER_DST_OUT:          return _("DstOut");
+       case TRANSFER_DST_OVER:         return _("DstOver");
+       case TRANSFER_SRC:              return _("Src");
+       case TRANSFER_SRC_ATOP:         return _("SrcAtop");
+       case TRANSFER_SRC_IN:           return _("SrcIn");
+       case TRANSFER_SRC_OUT:          return _("SrcOut");
+       case TRANSFER_SRC_OVER:         return _("SrcOver");
+       case TRANSFER_AND:              return _("And");
+       case TRANSFER_OR:               return _("Or");
+       case TRANSFER_XOR:              return _("Xor");
+       case TRANSFER_OVERLAY:          return _("Overlay");
+       case TRANSFER_SCREEN:           return _("Screen");
+       case TRANSFER_BURN:             return _("Burn");
+       case TRANSFER_DODGE:            return _("Dodge");
+       case TRANSFER_HARDLIGHT:        return _("Hardlight");
+       case TRANSFER_SOFTLIGHT:        return _("Softlight");
+       case TRANSFER_DIFFERENCE:       return _("Difference");
        }
        return _("Normal");
 }
@@ -389,6 +441,37 @@ VModePatchItem::VModePatchItem(VModePatch *popup, const char *text, int mode)
 
 int VModePatchItem::handle_event()
 {
+       if( mode >= 0 ) {
+               popup->mode = mode;
+//             popup->set_icon(popup->patch->patchbay->mode_to_icon(mode));
+               popup->handle_event();
+       }
+       return 1;
+}
+
+VModePatchSubMenu::VModePatchSubMenu(VModePatchItem *mode_item)
+{
+       this->mode_item = mode_item;
+}
+VModePatchSubMenu::~VModePatchSubMenu()
+{
+}
+
+VModeSubMenuItem::VModeSubMenuItem(VModePatchSubMenu *submenu, const char *text, int mode)
+ : BC_MenuItem(text)
+{
+       this->submenu = submenu;
+       this->mode = mode;
+       VModePatch *popup = submenu->mode_item->popup;
+       if(this->mode == popup->mode) set_checked(1);
+}
+VModeSubMenuItem::~VModeSubMenuItem()
+{
+}
+
+int VModeSubMenuItem::handle_event()
+{
+       VModePatch *popup = submenu->mode_item->popup;
        popup->mode = mode;
 //     popup->set_icon(popup->patch->patchbay->mode_to_icon(mode));
        popup->handle_event();
index e368c8ec131e8786af402080ecf9fce241bd744a..ff6b98d35ace1476b96c74da74c4970b5a0d2c49 100644 (file)
@@ -22,6 +22,8 @@
 #ifndef VPATCHGUI_H
 #define VPATCHGUI_H
 
+#include "bcmenuitem.h"
+#include "bcmenupopup.h"
 #include "floatauto.inc"
 #include "guicast.h"
 #include "patchgui.h"
@@ -108,6 +110,26 @@ public:
        int mode;
 };
 
+class VModePatchSubMenu : public BC_SubMenu
+{
+public:
+       VModePatchSubMenu(VModePatchItem *mode_item);
+       ~VModePatchSubMenu();
+
+       VModePatchItem *mode_item;
+};
+
+class VModeSubMenuItem : public BC_MenuItem
+{
+public:
+       VModeSubMenuItem(VModePatchSubMenu *submenu, const char *text, int mode);
+       ~VModeSubMenuItem();
+
+       int handle_event();
+       VModePatchSubMenu *submenu;
+       int mode;
+};
+
 class VKeyModePatch : public VModePatch
 {
 public:
index 6279bc6f0f4727b63fc4633bc21be3e0e4e4cf27..86a1e005bfa0ed14f13f49bea72e92c2c1843b59 100644 (file)
@@ -130,6 +130,7 @@ int BC_MenuItem::deactivate_submenus(BC_MenuPopup *exclude)
        {
                submenu->deactivate_submenus(exclude);
                submenu->deactivate_menu();
+               submenu->popup_menu = 0;
                highlighted = 0;
        }
        return 0;
@@ -149,6 +150,7 @@ int BC_MenuItem::activate_submenu()
                        &new_x,
                        &new_y,
                        &tempwin);
+               submenu->popup_menu = menu_popup->popup_menu;
                submenu->activate_menu(new_x + 5, new_y, menu_popup->w - 10, h, 0, 0);
                highlighted = 1;
        }
@@ -430,6 +432,11 @@ int BC_MenuItem::add_submenu(BC_SubMenu *submenu)
        return 0;
 }
 
+BC_SubMenu* BC_MenuItem::get_submenu()
+{
+       return submenu;
+}
+
 char* BC_MenuItem::get_text()
 {
        return text;
index 58aaa1d3f1e9d0e9256362b9a6835a14173d5ad5..5a2faf2139ecf761432b39b40f7c5473092e0344 100644 (file)
@@ -66,6 +66,7 @@ public:
        int draw();
        BC_WindowBase* get_top_level();
        BC_PopupMenu* get_popup_menu();
+       BC_SubMenu *get_submenu();
 
 private:
        BC_WindowBase *top_level;
index 1888e6cfdf514dfe9562bb0c5358dea8cd9a0917..9c679a3d002cb5ed71e9615690c97eb5a024644b 100644 (file)
@@ -428,7 +428,13 @@ BC_Popup* BC_MenuPopup::get_popup()
 
 int BC_MenuPopup::cursor_inside()
 {
-       return !popup || !popup->cursor_above() ? 0 : 1;
+       if( !popup ) return 0;
+       if( popup->cursor_above() ) return 1;
+       for( int i=0; i<menu_items.size(); ++i ) {
+               if( !menu_items[i]->submenu ) continue;
+               if( menu_items[i]->submenu->cursor_inside() ) return 1;
+       }
+       return 0;
 }
 
 int BC_MenuPopup::get_w()
index b97208fa0f4c73a4ec67efdcea3d30f20fcd3db0..b6d54fe0e9fc822526bfa64447f975678c86facd 100644 (file)
@@ -3761,9 +3761,11 @@ int BC_WindowBase::dump_windows()
                this, (void*)this->win, title, w,h,x,y, typeid(*this).name());
        for(int i = 0; i < subwindows->size(); i++)
                subwindows->get(i)->dump_windows();
-       for(int i = 0; i < popups.size(); i++)
-               printf("\tBC_WindowBase::dump_windows popup=%p win=%p\n",
-                       popups.get(i), (void*)popups.get(i)->win);
+       for(int i = 0; i < popups.size(); i++) {
+               BC_WindowBase *p = popups[i];
+               printf("\tBC_WindowBase::dump_windows popup=%p win=%p '%s', %dx%d+%d+%d %s\n",
+                       p, (void*)p->win, p->title, p->w,p->h,p->x,p->y, typeid(*p).name());
+       }
        return 0;
 }
 
index e1ca0961f06d410598354baffc938d00762db24a..359867fdd2fe7720efb25013ec82bd5dcd852289 100644 (file)
@@ -29,6 +29,7 @@
 #include "language.h"
 #include "overlayframe.h"
 #include "pluginvclient.h"
+#include "vpatchgui.h"
 #include "vframe.h"
 
 #include <string.h>
@@ -149,33 +150,7 @@ OverlayConfig::OverlayConfig()
 
 const char* OverlayConfig::mode_to_text(int mode)
 {
-       switch(mode) {
-       case TRANSFER_NORMAL:           return _("Normal");
-       case TRANSFER_ADDITION:         return _("Addition");
-       case TRANSFER_SUBTRACT:         return _("Subtract");
-       case TRANSFER_MULTIPLY:         return _("Multiply");
-       case TRANSFER_DIVIDE:           return _("Divide");
-       case TRANSFER_REPLACE:          return _("Replace");
-       case TRANSFER_MAX:              return _("Max");
-       case TRANSFER_MIN:              return _("Min");
-       case TRANSFER_AVERAGE:          return _("Average");
-       case TRANSFER_DARKEN:           return _("Darken");
-       case TRANSFER_LIGHTEN:          return _("Lighten");
-       case TRANSFER_DST:              return _("Dst");
-       case TRANSFER_DST_ATOP:         return _("DstAtop");
-       case TRANSFER_DST_IN:           return _("DstIn");
-       case TRANSFER_DST_OUT:          return _("DstOut");
-       case TRANSFER_DST_OVER:         return _("DstOver");
-       case TRANSFER_SRC:              return _("Src");
-       case TRANSFER_SRC_ATOP:         return _("SrcAtop");
-       case TRANSFER_SRC_IN:           return _("SrcIn");
-       case TRANSFER_SRC_OUT:          return _("SrcOut");
-       case TRANSFER_SRC_OVER:         return _("SrcOver");
-       case TRANSFER_OR:               return _("Or");
-       case TRANSFER_XOR:              return _("Xor");
-       default:                        break;
-       }
-       return _("Normal");
+       return VModePatch::mode_to_text(mode);
 }
 
 const char* OverlayConfig::direction_to_text(int direction)
@@ -479,141 +454,109 @@ int Overlay::handle_opengl()
                "       gl_FragColor = result;\n"
                "}\n";
 
-
-// NORMAL
-static const char *blend_normal_frag =
+#define QQ(q)#q
+#define SS(s)QQ(s)
+
+#define GL_STD_FRAG(FN) static const char *blend_##FN##_frag = \
+       "       vec4 result;\n" \
+       "       result.rgb = "SS(COLOR_##FN(1.0, src_color.rgb, src_color.a, dst_color.rgb, dst_color.a))";\n" \
+       "       result.a = "SS(ALPHA_##FN(1.0, src_color.a, dst_color.a))";\n" \
+
+#define GL_VEC_FRAG(FN) static const char *blend_##FN##_frag = \
+       "       vec4 result;\n" \
+       "       result.r = "SS(COLOR_##FN(1.0, src_color.r, src_color.a, dst_color.r, dst_color.a))";\n" \
+       "       result.g = "SS(COLOR_##FN(1.0, src_color.g, src_color.a, dst_color.g, dst_color.a))";\n" \
+       "       result.b = "SS(COLOR_##FN(1.0, src_color.b, src_color.a, dst_color.b, dst_color.a))";\n" \
+       "       result.a = "SS(ALPHA_##FN(1.0, src_color.a, dst_color.a))";\n" \
+       "       result = clamp(result, 0.0, 1.0);\n" \
+
+#undef mabs
+#define mabs abs
+#undef mmin
+#define mmin min
+#undef mmax
+#define mmax max
+
+#undef ZERO
+#define ZERO 0.0
+#undef ONE
+#define ONE 1.0
+#undef TWO
+#define TWO 2.0
+
+static const char *blend_NORMAL_frag =
        "       vec4 result = mix(src_color, src_color, src_color.a);\n";
 
-// ADDITION
-static const char *blend_add_frag =
+static const char *blend_ADDITION_frag =
        "       vec4 result = dst_color + src_color;\n"
        "       result = clamp(result, 0.0, 1.0);\n";
 
-// SUBTRACT
-static const char *blend_subtract_frag =
+static const char *blend_SUBTRACT_frag =
        "       vec4 result = dst_color - src_color;\n"
        "       result = clamp(result, 0.0, 1.0);\n";
 
-// MULTIPLY
-static const char *blend_multiply_frag =
-       "       vec4 result = dst_color * src_color;\n";
-
-// DIVIDE
-static const char *blend_divide_frag =
-       "       vec4 result = dst_color / src_color;\n"
-       "       if(src_color.r == 0.) result.r = 1.0;\n"
-       "       if(src_color.g == 0.) result.g = 1.0;\n"
-       "       if(src_color.b == 0.) result.b = 1.0;\n"
-       "       if(src_color.a == 0.) result.a = 1.0;\n"
-       "       result = clamp(result, 0.0, 1.0);\n";
-
-// MAX
-static const char *blend_max_frag =
-       "       vec4 result = max(src_color, dst_color);\n";
-
-// MIN
-static const char *blend_min_frag =
-       "       vec4 result = min(src_color, dst_color);\n";
-
-// AVERAGE
-static const char *blend_average_frag =
-       "       vec4 result = (src_color + dst_color) * 0.5;\n";
-
-// DARKEN
-static const char *blend_darken_frag =
-       "       vec4 result = vec4(src_color.rgb * (1.0 - dst_color.a) +"
-                       " dst_color.rgb * (1.0 - src_color.a) +"
-                       " min(src_color.rgb, dst_color.rgb), "
-                       " src_color.a + dst_color.a - src_color.a * dst_color.a);\n"
-       "       result = clamp(result, 0.0, 1.0);\n";
-
-// LIGHTEN
-static const char *blend_lighten_frag =
-       "       vec4 result = vec4(src_color.rgb * (1.0 - dst_color.a) +"
-                       " dst_color.rgb * (1.0 - src_color.a) +"
-                       " max(src_color.rgb, dst_color.rgb), "
-                       " src_color.a + dst_color.a - src_color.a * dst_color.a);\n"
-       "       result = clamp(result, 0.0, 1.0);\n";
-
-// DST
-static const char *blend_dst_frag =
-       "       vec4 result = dst_color;\n";
-
-// DST_ATOP
-static const char *blend_dst_atop_frag =
-       "       vec4 result = vec4(src_color.rgb * dst_color.a + "
-                       "(1.0 - src_color.a) * dst_color.rgb, dst_color.a);\n";
-
-// DST_IN
-static const char *blend_dst_in_frag =
-       "       vec4 result = src_color * dst_color.a;\n";
-
-// DST_OUT
-static const char *blend_dst_out_frag =
-       "       vec4 result = src_color * (1.0 - dst_color.a);\n";
-
-// DST_OVER
-static const char *blend_dst_over_frag =
-       "       vec4 result = vec4(src_color.rgb + (1.0 - src_color.a) * dst_color.rgb, "
-                       " dst_color.a + src_color.a - dst_color.a * src_color.a);\n";
-
-// SRC
-static const char *blend_src_frag =
+static const char *blend_REPLACE_frag =
        "       vec4 result = src_color;\n";
 
-// SRC_ATOP
-static const char *blend_src_atop_frag =
-       "       vec4 result = vec4(dst_color.rgb * src_color.a + "
-                       "src_color.rgb * (1.0 - dst_color.a), src_color.a);\n";
-
-// SRC_IN
-static const char *blend_src_in_frag =
-       "       vec4 result = dst_color * src_color.a;\n";
-
-// SRC_OUT
-static const char *blend_src_out_frag =
-       "       vec4 result = dst_color * (1.0 - src_color.a);\n";
-
-// SRC_OVER
-static const char *blend_src_over_frag =
-       "       vec4 result = vec4(dst_color.rgb + (1.0 - dst_color.a) * src_color.rgb, "
-                               "dst_color.a + src_color.a - dst_color.a * src_color.a);\n";
-
-// OR
-static const char *blend_or_frag =
-       "       vec4 result = src_color + dst_color - src_color * dst_color;\n";
-
-// XOR
-static const char *blend_xor_frag =
-       "       vec4 result = vec4(dst_color.rgb * (1.0 - src_color.a) + "
-                       "(1.0 - dst_color.a) * src_color.rgb, "
-                       "dst_color.a + src_color.a - 2.0 * dst_color.a * src_color.a);\n";
+GL_STD_FRAG(MULTIPLY);
+GL_VEC_FRAG(DIVIDE);
+GL_VEC_FRAG(MAX);
+GL_VEC_FRAG(MIN);
+GL_VEC_FRAG(DARKEN);
+GL_VEC_FRAG(LIGHTEN);
+GL_STD_FRAG(DST);
+GL_STD_FRAG(DST_ATOP);
+GL_STD_FRAG(DST_IN);
+GL_STD_FRAG(DST_OUT);
+GL_STD_FRAG(DST_OVER);
+GL_STD_FRAG(SRC);
+GL_STD_FRAG(SRC_ATOP);
+GL_STD_FRAG(SRC_IN);
+GL_STD_FRAG(SRC_OUT);
+GL_STD_FRAG(SRC_OVER);
+GL_STD_FRAG(AND);
+GL_STD_FRAG(OR);
+GL_STD_FRAG(XOR);
+GL_VEC_FRAG(OVERLAY);
+GL_STD_FRAG(SCREEN);
+GL_VEC_FRAG(BURN);
+GL_VEC_FRAG(DODGE);
+GL_VEC_FRAG(HARDLIGHT);
+GL_VEC_FRAG(SOFTLIGHT);
+GL_VEC_FRAG(DIFFERENCE);
 
 static const char * const overlay_shaders[TRANSFER_TYPES] = {
-               blend_normal_frag,      // TRANSFER_NORMAL
-               blend_add_frag,         // TRANSFER_ADDITION
-               blend_subtract_frag,    // TRANSFER_SUBTRACT
-               blend_multiply_frag,    // TRANSFER_MULTIPLY
-               blend_divide_frag,      // TRANSFER_DIVIDE
-               blend_src_frag,         // TRANSFER_REPLACE
-               blend_max_frag,         // TRANSFER_MAX
-               blend_min_frag,         // TRANSFER_MIN
-               blend_average_frag,     // TRANSFER_AVERAGE
-               blend_darken_frag,      // TRANSFER_DARKEN
-               blend_lighten_frag,     // TRANSFER_LIGHTEN
-               blend_dst_frag,         // TRANSFER_DST
-               blend_dst_atop_frag,    // TRANSFER_DST_ATOP
-               blend_dst_in_frag,      // TRANSFER_DST_IN
-               blend_dst_out_frag,     // TRANSFER_DST_OUT
-               blend_dst_over_frag,    // TRANSFER_DST_OVER
-               blend_src_frag,         // TRANSFER_SRC
-               blend_src_atop_frag,    // TRANSFER_SRC_ATOP
-               blend_src_in_frag,      // TRANSFER_SRC_IN
-               blend_src_out_frag,     // TRANSFER_SRC_OUT
-               blend_src_over_frag,    // TRANSFER_SRC_OVER
-               blend_or_frag,          // TRANSFER_OR
-               blend_xor_frag          // TRANSFER_XOR
-       };
+       blend_NORMAL_frag,      // TRANSFER_NORMAL
+       blend_ADDITION_frag,    // TRANSFER_ADDITION
+       blend_SUBTRACT_frag,    // TRANSFER_SUBTRACT
+       blend_MULTIPLY_frag,    // TRANSFER_MULTIPLY
+       blend_DIVIDE_frag,      // TRANSFER_DIVIDE
+       blend_REPLACE_frag,     // TRANSFER_REPLACE
+       blend_MAX_frag,         // TRANSFER_MAX
+       blend_MIN_frag,         // TRANSFER_MIN
+       blend_DARKEN_frag,      // TRANSFER_DARKEN
+       blend_LIGHTEN_frag,     // TRANSFER_LIGHTEN
+       blend_DST_frag,         // TRANSFER_DST
+       blend_DST_ATOP_frag,    // TRANSFER_DST_ATOP
+       blend_DST_IN_frag,      // TRANSFER_DST_IN
+       blend_DST_OUT_frag,     // TRANSFER_DST_OUT
+       blend_DST_OVER_frag,    // TRANSFER_DST_OVER
+       blend_SRC_frag,         // TRANSFER_SRC
+       blend_SRC_ATOP_frag,    // TRANSFER_SRC_ATOP
+       blend_SRC_IN_frag,      // TRANSFER_SRC_IN
+       blend_SRC_OUT_frag,     // TRANSFER_SRC_OUT
+       blend_SRC_OVER_frag,    // TRANSFER_SRC_OVER
+       blend_AND_frag,         // TRANSFER_AND
+       blend_OR_frag,          // TRANSFER_OR
+       blend_XOR_frag,         // TRANSFER_XOR
+       blend_OVERLAY_frag,     // TRANSFER_OVERLAY
+       blend_SCREEN_frag,      // TRANSFER_SCREEN
+       blend_BURN_frag,        // TRANSFER_BURN
+       blend_DODGE_frag,       // TRANSFER_DODGE
+       blend_HARDLIGHT_frag,   // TRANSFER_HARDLIGHT
+       blend_SOFTLIGHT_frag,   // TRANSFER_SOFTLIGHT
+       blend_DIFFERENCE_frag,  // TRANSFER_DIFFERENCE
+};
 
        glDisable(GL_BLEND);
        VFrame *dst = get_output(output_layer);
diff --git a/cinelerra-5.1/plugins/theme_blond/data/mode_and.png b/cinelerra-5.1/plugins/theme_blond/data/mode_and.png
new file mode 100644 (file)
index 0000000..dbbc4e2
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blond/data/mode_and.png differ
diff --git a/cinelerra-5.1/plugins/theme_blond/data/mode_average.png b/cinelerra-5.1/plugins/theme_blond/data/mode_average.png
deleted file mode 100644 (file)
index 3edf852..0000000
Binary files a/cinelerra-5.1/plugins/theme_blond/data/mode_average.png and /dev/null differ
diff --git a/cinelerra-5.1/plugins/theme_blond/data/mode_burn.png b/cinelerra-5.1/plugins/theme_blond/data/mode_burn.png
new file mode 100644 (file)
index 0000000..f465a6b
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blond/data/mode_burn.png differ
diff --git a/cinelerra-5.1/plugins/theme_blond/data/mode_difference.png b/cinelerra-5.1/plugins/theme_blond/data/mode_difference.png
new file mode 100644 (file)
index 0000000..c036b9d
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blond/data/mode_difference.png differ
diff --git a/cinelerra-5.1/plugins/theme_blond/data/mode_dodge.png b/cinelerra-5.1/plugins/theme_blond/data/mode_dodge.png
new file mode 100644 (file)
index 0000000..68eed2a
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blond/data/mode_dodge.png differ
diff --git a/cinelerra-5.1/plugins/theme_blond/data/mode_hardlight.png b/cinelerra-5.1/plugins/theme_blond/data/mode_hardlight.png
new file mode 100644 (file)
index 0000000..d9b9b64
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blond/data/mode_hardlight.png differ
diff --git a/cinelerra-5.1/plugins/theme_blond/data/mode_overlay.png b/cinelerra-5.1/plugins/theme_blond/data/mode_overlay.png
new file mode 100644 (file)
index 0000000..5351dae
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blond/data/mode_overlay.png differ
diff --git a/cinelerra-5.1/plugins/theme_blond/data/mode_screen.png b/cinelerra-5.1/plugins/theme_blond/data/mode_screen.png
new file mode 100644 (file)
index 0000000..4d34376
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blond/data/mode_screen.png differ
diff --git a/cinelerra-5.1/plugins/theme_blond/data/mode_softlight.png b/cinelerra-5.1/plugins/theme_blond/data/mode_softlight.png
new file mode 100644 (file)
index 0000000..6a101a6
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blond/data/mode_softlight.png differ
diff --git a/cinelerra-5.1/plugins/theme_blond_cv/data/mode_and.png b/cinelerra-5.1/plugins/theme_blond_cv/data/mode_and.png
new file mode 100644 (file)
index 0000000..dbbc4e2
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blond_cv/data/mode_and.png differ
diff --git a/cinelerra-5.1/plugins/theme_blond_cv/data/mode_average.png b/cinelerra-5.1/plugins/theme_blond_cv/data/mode_average.png
deleted file mode 100644 (file)
index 3edf852..0000000
Binary files a/cinelerra-5.1/plugins/theme_blond_cv/data/mode_average.png and /dev/null differ
diff --git a/cinelerra-5.1/plugins/theme_blond_cv/data/mode_burn.png b/cinelerra-5.1/plugins/theme_blond_cv/data/mode_burn.png
new file mode 100644 (file)
index 0000000..f465a6b
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blond_cv/data/mode_burn.png differ
diff --git a/cinelerra-5.1/plugins/theme_blond_cv/data/mode_difference.png b/cinelerra-5.1/plugins/theme_blond_cv/data/mode_difference.png
new file mode 100644 (file)
index 0000000..c036b9d
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blond_cv/data/mode_difference.png differ
diff --git a/cinelerra-5.1/plugins/theme_blond_cv/data/mode_dodge.png b/cinelerra-5.1/plugins/theme_blond_cv/data/mode_dodge.png
new file mode 100644 (file)
index 0000000..68eed2a
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blond_cv/data/mode_dodge.png differ
diff --git a/cinelerra-5.1/plugins/theme_blond_cv/data/mode_hardlight.png b/cinelerra-5.1/plugins/theme_blond_cv/data/mode_hardlight.png
new file mode 100644 (file)
index 0000000..d9b9b64
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blond_cv/data/mode_hardlight.png differ
diff --git a/cinelerra-5.1/plugins/theme_blond_cv/data/mode_overlay.png b/cinelerra-5.1/plugins/theme_blond_cv/data/mode_overlay.png
new file mode 100644 (file)
index 0000000..5351dae
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blond_cv/data/mode_overlay.png differ
diff --git a/cinelerra-5.1/plugins/theme_blond_cv/data/mode_screen.png b/cinelerra-5.1/plugins/theme_blond_cv/data/mode_screen.png
new file mode 100644 (file)
index 0000000..4d34376
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blond_cv/data/mode_screen.png differ
diff --git a/cinelerra-5.1/plugins/theme_blond_cv/data/mode_softlight.png b/cinelerra-5.1/plugins/theme_blond_cv/data/mode_softlight.png
new file mode 100644 (file)
index 0000000..6a101a6
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blond_cv/data/mode_softlight.png differ
diff --git a/cinelerra-5.1/plugins/theme_blue/data/mode_and.png b/cinelerra-5.1/plugins/theme_blue/data/mode_and.png
new file mode 100644 (file)
index 0000000..dbbc4e2
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blue/data/mode_and.png differ
diff --git a/cinelerra-5.1/plugins/theme_blue/data/mode_average.png b/cinelerra-5.1/plugins/theme_blue/data/mode_average.png
deleted file mode 100644 (file)
index 3edf852..0000000
Binary files a/cinelerra-5.1/plugins/theme_blue/data/mode_average.png and /dev/null differ
diff --git a/cinelerra-5.1/plugins/theme_blue/data/mode_burn.png b/cinelerra-5.1/plugins/theme_blue/data/mode_burn.png
new file mode 100644 (file)
index 0000000..f465a6b
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blue/data/mode_burn.png differ
diff --git a/cinelerra-5.1/plugins/theme_blue/data/mode_difference.png b/cinelerra-5.1/plugins/theme_blue/data/mode_difference.png
new file mode 100644 (file)
index 0000000..c036b9d
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blue/data/mode_difference.png differ
diff --git a/cinelerra-5.1/plugins/theme_blue/data/mode_dodge.png b/cinelerra-5.1/plugins/theme_blue/data/mode_dodge.png
new file mode 100644 (file)
index 0000000..68eed2a
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blue/data/mode_dodge.png differ
diff --git a/cinelerra-5.1/plugins/theme_blue/data/mode_hardlight.png b/cinelerra-5.1/plugins/theme_blue/data/mode_hardlight.png
new file mode 100644 (file)
index 0000000..d9b9b64
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blue/data/mode_hardlight.png differ
diff --git a/cinelerra-5.1/plugins/theme_blue/data/mode_overlay.png b/cinelerra-5.1/plugins/theme_blue/data/mode_overlay.png
new file mode 100644 (file)
index 0000000..5351dae
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blue/data/mode_overlay.png differ
diff --git a/cinelerra-5.1/plugins/theme_blue/data/mode_screen.png b/cinelerra-5.1/plugins/theme_blue/data/mode_screen.png
new file mode 100644 (file)
index 0000000..4d34376
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blue/data/mode_screen.png differ
diff --git a/cinelerra-5.1/plugins/theme_blue/data/mode_softlight.png b/cinelerra-5.1/plugins/theme_blue/data/mode_softlight.png
new file mode 100644 (file)
index 0000000..6a101a6
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blue/data/mode_softlight.png differ
diff --git a/cinelerra-5.1/plugins/theme_blue_dot/data/mode_and.png b/cinelerra-5.1/plugins/theme_blue_dot/data/mode_and.png
new file mode 100644 (file)
index 0000000..dbbc4e2
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blue_dot/data/mode_and.png differ
diff --git a/cinelerra-5.1/plugins/theme_blue_dot/data/mode_average.png b/cinelerra-5.1/plugins/theme_blue_dot/data/mode_average.png
deleted file mode 100644 (file)
index 0b2fdef..0000000
Binary files a/cinelerra-5.1/plugins/theme_blue_dot/data/mode_average.png and /dev/null differ
diff --git a/cinelerra-5.1/plugins/theme_blue_dot/data/mode_burn.png b/cinelerra-5.1/plugins/theme_blue_dot/data/mode_burn.png
new file mode 100644 (file)
index 0000000..f465a6b
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blue_dot/data/mode_burn.png differ
diff --git a/cinelerra-5.1/plugins/theme_blue_dot/data/mode_difference.png b/cinelerra-5.1/plugins/theme_blue_dot/data/mode_difference.png
new file mode 100644 (file)
index 0000000..c036b9d
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blue_dot/data/mode_difference.png differ
diff --git a/cinelerra-5.1/plugins/theme_blue_dot/data/mode_dodge.png b/cinelerra-5.1/plugins/theme_blue_dot/data/mode_dodge.png
new file mode 100644 (file)
index 0000000..68eed2a
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blue_dot/data/mode_dodge.png differ
diff --git a/cinelerra-5.1/plugins/theme_blue_dot/data/mode_hardlight.png b/cinelerra-5.1/plugins/theme_blue_dot/data/mode_hardlight.png
new file mode 100644 (file)
index 0000000..d9b9b64
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blue_dot/data/mode_hardlight.png differ
diff --git a/cinelerra-5.1/plugins/theme_blue_dot/data/mode_overlay.png b/cinelerra-5.1/plugins/theme_blue_dot/data/mode_overlay.png
new file mode 100644 (file)
index 0000000..5351dae
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blue_dot/data/mode_overlay.png differ
diff --git a/cinelerra-5.1/plugins/theme_blue_dot/data/mode_screen.png b/cinelerra-5.1/plugins/theme_blue_dot/data/mode_screen.png
new file mode 100644 (file)
index 0000000..4d34376
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blue_dot/data/mode_screen.png differ
diff --git a/cinelerra-5.1/plugins/theme_blue_dot/data/mode_softlight.png b/cinelerra-5.1/plugins/theme_blue_dot/data/mode_softlight.png
new file mode 100644 (file)
index 0000000..6a101a6
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_blue_dot/data/mode_softlight.png differ
diff --git a/cinelerra-5.1/plugins/theme_bright/data/mode_and.png b/cinelerra-5.1/plugins/theme_bright/data/mode_and.png
new file mode 100644 (file)
index 0000000..dbbc4e2
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_bright/data/mode_and.png differ
diff --git a/cinelerra-5.1/plugins/theme_bright/data/mode_average.png b/cinelerra-5.1/plugins/theme_bright/data/mode_average.png
deleted file mode 100644 (file)
index 3edf852..0000000
Binary files a/cinelerra-5.1/plugins/theme_bright/data/mode_average.png and /dev/null differ
diff --git a/cinelerra-5.1/plugins/theme_bright/data/mode_burn.png b/cinelerra-5.1/plugins/theme_bright/data/mode_burn.png
new file mode 100644 (file)
index 0000000..f465a6b
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_bright/data/mode_burn.png differ
diff --git a/cinelerra-5.1/plugins/theme_bright/data/mode_difference.png b/cinelerra-5.1/plugins/theme_bright/data/mode_difference.png
new file mode 100644 (file)
index 0000000..c036b9d
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_bright/data/mode_difference.png differ
diff --git a/cinelerra-5.1/plugins/theme_bright/data/mode_dodge.png b/cinelerra-5.1/plugins/theme_bright/data/mode_dodge.png
new file mode 100644 (file)
index 0000000..68eed2a
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_bright/data/mode_dodge.png differ
diff --git a/cinelerra-5.1/plugins/theme_bright/data/mode_hardlight.png b/cinelerra-5.1/plugins/theme_bright/data/mode_hardlight.png
new file mode 100644 (file)
index 0000000..d9b9b64
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_bright/data/mode_hardlight.png differ
diff --git a/cinelerra-5.1/plugins/theme_bright/data/mode_overlay.png b/cinelerra-5.1/plugins/theme_bright/data/mode_overlay.png
new file mode 100644 (file)
index 0000000..5351dae
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_bright/data/mode_overlay.png differ
diff --git a/cinelerra-5.1/plugins/theme_bright/data/mode_screen.png b/cinelerra-5.1/plugins/theme_bright/data/mode_screen.png
new file mode 100644 (file)
index 0000000..4d34376
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_bright/data/mode_screen.png differ
diff --git a/cinelerra-5.1/plugins/theme_bright/data/mode_softlight.png b/cinelerra-5.1/plugins/theme_bright/data/mode_softlight.png
new file mode 100644 (file)
index 0000000..6a101a6
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_bright/data/mode_softlight.png differ
diff --git a/cinelerra-5.1/plugins/theme_hulk/data/mode_and.png b/cinelerra-5.1/plugins/theme_hulk/data/mode_and.png
new file mode 100644 (file)
index 0000000..dbbc4e2
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_hulk/data/mode_and.png differ
diff --git a/cinelerra-5.1/plugins/theme_hulk/data/mode_average.png b/cinelerra-5.1/plugins/theme_hulk/data/mode_average.png
deleted file mode 100644 (file)
index 3edf852..0000000
Binary files a/cinelerra-5.1/plugins/theme_hulk/data/mode_average.png and /dev/null differ
diff --git a/cinelerra-5.1/plugins/theme_hulk/data/mode_burn.png b/cinelerra-5.1/plugins/theme_hulk/data/mode_burn.png
new file mode 100644 (file)
index 0000000..f465a6b
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_hulk/data/mode_burn.png differ
diff --git a/cinelerra-5.1/plugins/theme_hulk/data/mode_difference.png b/cinelerra-5.1/plugins/theme_hulk/data/mode_difference.png
new file mode 100644 (file)
index 0000000..c036b9d
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_hulk/data/mode_difference.png differ
diff --git a/cinelerra-5.1/plugins/theme_hulk/data/mode_dodge.png b/cinelerra-5.1/plugins/theme_hulk/data/mode_dodge.png
new file mode 100644 (file)
index 0000000..68eed2a
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_hulk/data/mode_dodge.png differ
diff --git a/cinelerra-5.1/plugins/theme_hulk/data/mode_hardlight.png b/cinelerra-5.1/plugins/theme_hulk/data/mode_hardlight.png
new file mode 100644 (file)
index 0000000..d9b9b64
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_hulk/data/mode_hardlight.png differ
diff --git a/cinelerra-5.1/plugins/theme_hulk/data/mode_overlay.png b/cinelerra-5.1/plugins/theme_hulk/data/mode_overlay.png
new file mode 100644 (file)
index 0000000..5351dae
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_hulk/data/mode_overlay.png differ
diff --git a/cinelerra-5.1/plugins/theme_hulk/data/mode_screen.png b/cinelerra-5.1/plugins/theme_hulk/data/mode_screen.png
new file mode 100644 (file)
index 0000000..4d34376
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_hulk/data/mode_screen.png differ
diff --git a/cinelerra-5.1/plugins/theme_hulk/data/mode_softlight.png b/cinelerra-5.1/plugins/theme_hulk/data/mode_softlight.png
new file mode 100644 (file)
index 0000000..6a101a6
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_hulk/data/mode_softlight.png differ
diff --git a/cinelerra-5.1/plugins/theme_pinklady/data/mode_and.png b/cinelerra-5.1/plugins/theme_pinklady/data/mode_and.png
new file mode 100644 (file)
index 0000000..dbbc4e2
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_pinklady/data/mode_and.png differ
diff --git a/cinelerra-5.1/plugins/theme_pinklady/data/mode_average.png b/cinelerra-5.1/plugins/theme_pinklady/data/mode_average.png
deleted file mode 100644 (file)
index 3edf852..0000000
Binary files a/cinelerra-5.1/plugins/theme_pinklady/data/mode_average.png and /dev/null differ
diff --git a/cinelerra-5.1/plugins/theme_pinklady/data/mode_burn.png b/cinelerra-5.1/plugins/theme_pinklady/data/mode_burn.png
new file mode 100644 (file)
index 0000000..f465a6b
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_pinklady/data/mode_burn.png differ
diff --git a/cinelerra-5.1/plugins/theme_pinklady/data/mode_difference.png b/cinelerra-5.1/plugins/theme_pinklady/data/mode_difference.png
new file mode 100644 (file)
index 0000000..c036b9d
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_pinklady/data/mode_difference.png differ
diff --git a/cinelerra-5.1/plugins/theme_pinklady/data/mode_dodge.png b/cinelerra-5.1/plugins/theme_pinklady/data/mode_dodge.png
new file mode 100644 (file)
index 0000000..68eed2a
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_pinklady/data/mode_dodge.png differ
diff --git a/cinelerra-5.1/plugins/theme_pinklady/data/mode_hardlight.png b/cinelerra-5.1/plugins/theme_pinklady/data/mode_hardlight.png
new file mode 100644 (file)
index 0000000..d9b9b64
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_pinklady/data/mode_hardlight.png differ
diff --git a/cinelerra-5.1/plugins/theme_pinklady/data/mode_overlay.png b/cinelerra-5.1/plugins/theme_pinklady/data/mode_overlay.png
new file mode 100644 (file)
index 0000000..5351dae
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_pinklady/data/mode_overlay.png differ
diff --git a/cinelerra-5.1/plugins/theme_pinklady/data/mode_screen.png b/cinelerra-5.1/plugins/theme_pinklady/data/mode_screen.png
new file mode 100644 (file)
index 0000000..4d34376
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_pinklady/data/mode_screen.png differ
diff --git a/cinelerra-5.1/plugins/theme_pinklady/data/mode_softlight.png b/cinelerra-5.1/plugins/theme_pinklady/data/mode_softlight.png
new file mode 100644 (file)
index 0000000..6a101a6
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_pinklady/data/mode_softlight.png differ
diff --git a/cinelerra-5.1/plugins/theme_suv/data/mode_and.png b/cinelerra-5.1/plugins/theme_suv/data/mode_and.png
new file mode 100644 (file)
index 0000000..dbbc4e2
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_suv/data/mode_and.png differ
diff --git a/cinelerra-5.1/plugins/theme_suv/data/mode_average.png b/cinelerra-5.1/plugins/theme_suv/data/mode_average.png
deleted file mode 100644 (file)
index 3edf852..0000000
Binary files a/cinelerra-5.1/plugins/theme_suv/data/mode_average.png and /dev/null differ
diff --git a/cinelerra-5.1/plugins/theme_suv/data/mode_burn.png b/cinelerra-5.1/plugins/theme_suv/data/mode_burn.png
new file mode 100644 (file)
index 0000000..f465a6b
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_suv/data/mode_burn.png differ
diff --git a/cinelerra-5.1/plugins/theme_suv/data/mode_difference.png b/cinelerra-5.1/plugins/theme_suv/data/mode_difference.png
new file mode 100644 (file)
index 0000000..c036b9d
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_suv/data/mode_difference.png differ
diff --git a/cinelerra-5.1/plugins/theme_suv/data/mode_dodge.png b/cinelerra-5.1/plugins/theme_suv/data/mode_dodge.png
new file mode 100644 (file)
index 0000000..68eed2a
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_suv/data/mode_dodge.png differ
diff --git a/cinelerra-5.1/plugins/theme_suv/data/mode_hardlight.png b/cinelerra-5.1/plugins/theme_suv/data/mode_hardlight.png
new file mode 100644 (file)
index 0000000..d9b9b64
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_suv/data/mode_hardlight.png differ
diff --git a/cinelerra-5.1/plugins/theme_suv/data/mode_overlay.png b/cinelerra-5.1/plugins/theme_suv/data/mode_overlay.png
new file mode 100644 (file)
index 0000000..5351dae
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_suv/data/mode_overlay.png differ
diff --git a/cinelerra-5.1/plugins/theme_suv/data/mode_screen.png b/cinelerra-5.1/plugins/theme_suv/data/mode_screen.png
new file mode 100644 (file)
index 0000000..4d34376
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_suv/data/mode_screen.png differ
diff --git a/cinelerra-5.1/plugins/theme_suv/data/mode_softlight.png b/cinelerra-5.1/plugins/theme_suv/data/mode_softlight.png
new file mode 100644 (file)
index 0000000..6a101a6
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_suv/data/mode_softlight.png differ
diff --git a/cinelerra-5.1/plugins/theme_unflat/data/mode_and.png b/cinelerra-5.1/plugins/theme_unflat/data/mode_and.png
new file mode 100644 (file)
index 0000000..dbbc4e2
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_unflat/data/mode_and.png differ
diff --git a/cinelerra-5.1/plugins/theme_unflat/data/mode_average.png b/cinelerra-5.1/plugins/theme_unflat/data/mode_average.png
deleted file mode 100644 (file)
index 3edf852..0000000
Binary files a/cinelerra-5.1/plugins/theme_unflat/data/mode_average.png and /dev/null differ
diff --git a/cinelerra-5.1/plugins/theme_unflat/data/mode_burn.png b/cinelerra-5.1/plugins/theme_unflat/data/mode_burn.png
new file mode 100644 (file)
index 0000000..f465a6b
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_unflat/data/mode_burn.png differ
diff --git a/cinelerra-5.1/plugins/theme_unflat/data/mode_difference.png b/cinelerra-5.1/plugins/theme_unflat/data/mode_difference.png
new file mode 100644 (file)
index 0000000..c036b9d
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_unflat/data/mode_difference.png differ
diff --git a/cinelerra-5.1/plugins/theme_unflat/data/mode_dodge.png b/cinelerra-5.1/plugins/theme_unflat/data/mode_dodge.png
new file mode 100644 (file)
index 0000000..68eed2a
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_unflat/data/mode_dodge.png differ
diff --git a/cinelerra-5.1/plugins/theme_unflat/data/mode_hardlight.png b/cinelerra-5.1/plugins/theme_unflat/data/mode_hardlight.png
new file mode 100644 (file)
index 0000000..d9b9b64
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_unflat/data/mode_hardlight.png differ
diff --git a/cinelerra-5.1/plugins/theme_unflat/data/mode_overlay.png b/cinelerra-5.1/plugins/theme_unflat/data/mode_overlay.png
new file mode 100644 (file)
index 0000000..5351dae
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_unflat/data/mode_overlay.png differ
diff --git a/cinelerra-5.1/plugins/theme_unflat/data/mode_screen.png b/cinelerra-5.1/plugins/theme_unflat/data/mode_screen.png
new file mode 100644 (file)
index 0000000..4d34376
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_unflat/data/mode_screen.png differ
diff --git a/cinelerra-5.1/plugins/theme_unflat/data/mode_softlight.png b/cinelerra-5.1/plugins/theme_unflat/data/mode_softlight.png
new file mode 100644 (file)
index 0000000..6a101a6
Binary files /dev/null and b/cinelerra-5.1/plugins/theme_unflat/data/mode_softlight.png differ