1 #include "overlayframe.h"
3 /* Nearest Neighbor scale / translate / blend ********************/
5 #define XBLEND_3NN(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(); \
11 for(int i = pkg->out_row1; i < pkg->out_row2; i++) { \
12 int *lx = engine->in_lookup_x; \
13 type* in_row = input_rows[*ly++]; \
14 type* output = output_rows[i] + ox; \
15 for(int j = 0; j < ow; j++) { \
17 if( components == 4 ) { \
18 temp_type r, g, b, a; \
19 ALPHA4_BLEND(FN, temp_type, in_row, output, max, ofs, ofs, round); \
20 ALPHA4_STORE(output, ofs, max); \
24 ALPHA3_BLEND(FN, temp_type, in_row, output, max, ofs, ofs, round); \
25 ALPHA3_STORE(output, ofs, max); \
27 output += components; \
33 #define XBLEND_NN(FN) { \
34 switch(input->get_color_model()) { \
35 case BC_RGB_FLOAT: XBLEND_3NN(FN, z_float, z_float, 1.f, 3, 0, 0.f); \
36 case BC_RGBA_FLOAT: XBLEND_3NN(FN, z_float, z_float, 1.f, 4, 0, 0.f); \
37 case BC_RGB888: XBLEND_3NN(FN, z_int32_t, z_uint8_t, 0xff, 3, 0, .5f); \
38 case BC_YUV888: XBLEND_3NN(FN, z_int32_t, z_uint8_t, 0xff, 3, 0x80, .5f); \
39 case BC_RGBA8888: XBLEND_3NN(FN, z_int32_t, z_uint8_t, 0xff, 4, 0, .5f); \
40 case BC_YUVA8888: XBLEND_3NN(FN, z_int32_t, z_uint8_t, 0xff, 4, 0x80, .5f); \
41 case BC_RGB161616: XBLEND_3NN(FN, z_int64_t, z_uint16_t, 0xffff, 3, 0, .5f); \
42 case BC_YUV161616: XBLEND_3NN(FN, z_int64_t, z_uint16_t, 0xffff, 3, 0x8000, .5f); \
43 case BC_RGBA16161616: XBLEND_3NN(FN, z_int64_t, z_uint16_t, 0xffff, 4, 0, .5f); \
44 case BC_YUVA16161616: XBLEND_3NN(FN, z_int64_t, z_uint16_t, 0xffff, 4, 0x8000, .5f); \
49 NNPackage::NNPackage()
53 NNUnit::NNUnit(NNEngine *server)
56 this->engine = server;
63 void NNUnit::process_package(LoadPackage *package)
65 NNPackage *pkg = (NNPackage*)package;
66 VFrame *output = engine->output;
67 VFrame *input = engine->input;
68 int mode = engine->mode;
70 BC_CModels::has_alpha(input->get_color_model()) &&
71 mode == TRANSFER_REPLACE ? 1.f : engine->alpha;
73 int ox = engine->out_x1i;
74 int ow = engine->out_x2i - ox;
75 int *ly = engine->in_lookup_y + pkg->out_row1;
77 BLEND_SWITCH(XBLEND_NN);
80 NNEngine::NNEngine(int cpus)
81 : LoadServer(cpus, cpus)
95 void NNEngine::init_packages()
97 int in_w = input->get_w();
98 int in_h = input->get_h();
99 int out_w = output->get_w();
100 int out_h = output->get_h();
102 float in_subw = in_x2 - in_x1;
103 float in_subh = in_y2 - in_y1;
104 float out_subw = out_x2 - out_x1;
105 float out_subh = out_y2 - out_y1;
106 int first, last, count, i;
109 out_x1i = rint(out_x1);
110 out_x2i = rint(out_x2);
111 if(out_x1i < 0) out_x1i = 0;
112 if(out_x1i > out_w) out_x1i = out_w;
113 if(out_x2i < 0) out_x2i = 0;
114 if(out_x2i > out_w) out_x2i = out_w;
115 int out_wi = out_x2i - out_x1i;
116 if( !out_wi ) return;
118 delete[] in_lookup_x;
119 in_lookup_x = new int[out_wi];
120 delete[] in_lookup_y;
121 in_lookup_y = new int[out_h];
123 switch(input->get_color_model()) {
127 case BC_RGBA16161616:
134 for(i = out_x1i; i < out_x2i; i++) {
135 int in = (i - out_x1 + .5) * in_subw / out_subw + in_x1;
141 if(in >= 0 && in < in_w && in >= in_x1 && i >= 0 && i < out_w) {
144 in_lookup_x[0] = in * components;
147 in_lookup_x[count] = (in-last)*components;
156 out_x2i = first + count;
159 for(i = out_y1; i < out_y2; i++) {
160 int in = (i - out_y1+.5) * in_subh / out_subh + in_y1;
161 if(in < in_y1) in = in_y1;
162 if(in > in_y2) in = in_y2;
163 if(in >= 0 && in < in_h && i >= 0 && i < out_h) {
164 if(count == 0) first = i;
172 out_y2 = first + count;
175 int pkgs = get_total_packages();
176 int row1 = out_y1, row2 = row1;
177 for(int i = 0; i < pkgs; row1=row2 ) {
178 NNPackage *package = (NNPackage*)get_package(i);
179 row2 = ++i * rows / pkgs + out_y1;
180 package->out_row1 = row1;
181 package->out_row2 = row2;
185 LoadClient* NNEngine::new_client()
187 return new NNUnit(this);
190 LoadPackage* NNEngine::new_package()
192 return new NNPackage;