-// 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()
-{
-}