Credit Andrew - improve in-tree documentation
[goodguy/cinelerra.git] / cinelerra / overlaydirect.C
1 #include "overlayframe.h"
2
3 /* Direct translate / blend **********************************************/
4
5 #define XBLEND(FN, temp_type, type, max, components, ofs, round) { \
6         temp_type opcty = fade * max + round, trnsp = max - opcty; \
7         type** output_rows = (type**)output->get_rows(); \
8         type** input_rows = (type**)input->get_rows(); \
9         ix *= components;  ox *= components; \
10  \
11         for(int i = pkg->out_row1; i < pkg->out_row2; i++) { \
12                 type* in_row = input_rows[i + iy] + ix; \
13                 type* output = output_rows[i] + ox; \
14                 for(int j = 0; j < ow; j++) { \
15                         if( components == 4 ) { \
16                                 temp_type r, g, b, a; \
17                                 ALPHA4_BLEND(FN, temp_type, in_row, output, max, ofs, ofs, round); \
18                                 ALPHA4_STORE(output, ofs, max); \
19                         } \
20                         else { \
21                                 temp_type r, g, b; \
22                                 ALPHA3_BLEND(FN, temp_type, in_row, output, max, ofs, ofs, round); \
23                                 ALPHA3_STORE(output, ofs, max); \
24                         } \
25                         in_row += components;  output += components; \
26                 } \
27         } \
28         break; \
29 }
30
31 #define XBLEND_ONLY(FN) { \
32         switch(input->get_color_model()) { \
33         case BC_RGB_FLOAT:      XBLEND(FN, z_float,   z_float,    1.f,    3, 0,      0.f); \
34         case BC_RGBA_FLOAT:     XBLEND(FN, z_float,   z_float,    1.f,    4, 0,      0.f); \
35         case BC_RGB888:         XBLEND(FN, z_int32_t, z_uint8_t,  0xff,   3, 0,      .5f); \
36         case BC_YUV888:         XBLEND(FN, z_int32_t, z_uint8_t,  0xff,   3, 0x80,   .5f); \
37         case BC_RGBA8888:       XBLEND(FN, z_int32_t, z_uint8_t,  0xff,   4, 0,      .5f); \
38         case BC_YUVA8888:       XBLEND(FN, z_int32_t, z_uint8_t,  0xff,   4, 0x80,   .5f); \
39         case BC_RGB161616:      XBLEND(FN, z_int64_t, z_uint16_t, 0xffff, 3, 0,      .5f); \
40         case BC_YUV161616:      XBLEND(FN, z_int64_t, z_uint16_t, 0xffff, 3, 0x8000, .5f); \
41         case BC_RGBA16161616:   XBLEND(FN, z_int64_t, z_uint16_t, 0xffff, 4, 0,      .5f); \
42         case BC_YUVA16161616:   XBLEND(FN, z_int64_t, z_uint16_t, 0xffff, 4, 0x8000, .5f); \
43         } \
44         break; \
45 }
46
47 DirectPackage::DirectPackage()
48 {
49 }
50
51 DirectUnit::DirectUnit(DirectEngine *server)
52  : LoadClient(server)
53 {
54         this->engine = server;
55 }
56
57 DirectUnit::~DirectUnit()
58 {
59 }
60
61 void DirectUnit::process_package(LoadPackage *package)
62 {
63         DirectPackage *pkg = (DirectPackage*)package;
64
65         VFrame *output = engine->output;
66         VFrame *input = engine->input;
67         int mode = engine->mode;
68         float fade =
69                 BC_CModels::has_alpha(input->get_color_model()) &&
70                 mode == TRANSFER_REPLACE ? 1.f : engine->alpha;
71
72         int ix = engine->in_x1;
73         int ox = engine->out_x1;
74         int ow = engine->out_x2 - ox;
75         int iy = engine->in_y1 - engine->out_y1;
76
77         BLEND_SWITCH(XBLEND_ONLY);
78 }
79
80 DirectEngine::DirectEngine(int cpus)
81  : LoadServer(cpus, cpus)
82 {
83 }
84
85 DirectEngine::~DirectEngine()
86 {
87 }
88
89 void DirectEngine::init_packages()
90 {
91         if(in_x1 < 0) { out_x1 -= in_x1; in_x1 = 0; }
92         if(in_y1 < 0) { out_y1 -= in_y1; in_y1 = 0; }
93         if(out_x1 < 0) { in_x1 -= out_x1; out_x1 = 0; }
94         if(out_y1 < 0) { in_y1 -= out_y1; out_y1 = 0; }
95         if(out_x2 > output->get_w()) out_x2 = output->get_w();
96         if(out_y2 > output->get_h()) out_y2 = output->get_h();
97         int out_w = out_x2 - out_x1;
98         int out_h = out_y2 - out_y1;
99         if( !out_w || !out_h ) return;
100
101         int rows = out_h;
102         int pkgs = get_total_packages();
103         int row1 = out_y1, row2 = row1;
104         for(int i = 0; i < pkgs; row1=row2 ) {
105                 DirectPackage *package = (DirectPackage*)get_package(i);
106                 row2 = ++i * rows / pkgs + out_y1;
107                 package->out_row1 = row1;
108                 package->out_row2 = row2;
109         }
110 }
111
112 LoadClient* DirectEngine::new_client()
113 {
114         return new DirectUnit(this);
115 }
116
117 LoadPackage* DirectEngine::new_package()
118 {
119         return new DirectPackage;
120 }
121
122