1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved.
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Use of this source code is governed by a BSD-style license that can be
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// found in the LICENSE file.
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fxge/fx_ge.h"
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fxcodec/fx_codec.h"
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "dib_int.h"
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst FX_BYTE g_GammaRamp[256] = {
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0,   0,   0,   0,   0,   0,   0,   1,   1,   1,   1,   1,   1,   1,   1,   1,
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    1,   1,   2,   2,   2,   2,   2,   2,   2,   2,   3,   3,   3,   3,   3,   3,
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    4,   4,   4,   4,   4,   5,   5,   5,   5,   6,   6,   6,   6,   7,   7,   7,
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    8,   8,   8,   8,   9,   9,   9,  10,  10,  10,  11,  11,  12,  12,  12,  13,
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    13,  13,  14,  14,  15,  15,  16,  16,  17,  17,  17,  18,  18,  19,  19,  20,
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    20,  21,  22,  22,  23,  23,  24,  24,  25,  25,  26,  27,  27,  28,  29,  29,
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    30,  30,  31,  32,  32,  33,  34,  35,  35,  36,  37,  37,  38,  39,  40,  41,
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    41,  42,  43,  44,  45,  45,  46,  47,  48,  49,  50,  51,  51,  52,  53,  54,
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    55,  56,  57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    71,  72,  73,  74,  76,  77,  78,  79,  80,  81,  82,  84,  85,  86,  87,  88,
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    90,  91,  92,  93,  95,  96,  97,  99, 100, 101, 103, 104, 105, 107, 108, 109,
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    111, 112, 114, 115, 116, 118, 119, 121, 122, 124, 125, 127, 128, 130, 131, 133,
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    134, 136, 138, 139, 141, 142, 144, 146, 147, 149, 151, 152, 154, 156, 157, 159,
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    161, 163, 164, 166, 168, 170, 171, 173, 175, 177, 179, 181, 183, 184, 186, 188,
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220,
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    222, 224, 226, 229, 231, 233, 235, 237, 239, 242, 244, 246, 248, 250, 253, 255,
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst FX_BYTE g_GammaInverse[256] = {
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0,  13,  22,  28,  34,  38,  42,  46,  50,  53,  56,  59,  61,  64,  66,  69,
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    71,  73,  75,  77,  79,  81,  83,  85,  86,  88,  90,  92,  93,  95,  96,  98,
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    99, 101, 102, 104, 105, 106, 108, 109, 110, 112, 113, 114, 115, 117, 118, 119,
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    120, 121, 122, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136,
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 148, 149, 150, 151,
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    152, 153, 154, 155, 155, 156, 157, 158, 159, 159, 160, 161, 162, 163, 163, 164,
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    165, 166, 167, 167, 168, 169, 170, 170, 171, 172, 173, 173, 174, 175, 175, 176,
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    177, 178, 178, 179, 180, 180, 181, 182, 182, 183, 184, 185, 185, 186, 187, 187,
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    188, 189, 189, 190, 190, 191, 192, 192, 193, 194, 194, 195, 196, 196, 197, 197,
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    198, 199, 199, 200, 200, 201, 202, 202, 203, 203, 204, 205, 205, 206, 206, 207,
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    208, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, 214, 215, 215, 216,
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    216, 217, 218, 218, 219, 219, 220, 220, 221, 221, 222, 222, 223, 223, 224, 224,
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    225, 226, 226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233,
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 240,
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 246, 247, 247, 248,
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    248, 249, 249, 250, 250, 251, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255,
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst FX_BYTE _color_sqrt[256] = {
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00, 0x03, 0x07, 0x0B, 0x0F, 0x12, 0x16, 0x19, 0x1D, 0x20, 0x23, 0x26, 0x29, 0x2C, 0x2F, 0x32,
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x35, 0x37, 0x3A, 0x3C, 0x3F, 0x41, 0x43, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56,
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x57, 0x59, 0x5B, 0x5C, 0x5E, 0x60, 0x61, 0x63, 0x64, 0x65, 0x67, 0x68, 0x69, 0x6B, 0x6C, 0x6D,
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6E, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E,
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E,
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x8F, 0x90, 0x91, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C,
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA4, 0xA5, 0xA6, 0xA7, 0xA7, 0xA8,
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xA9, 0xAA, 0xAA, 0xAB, 0xAC, 0xAD, 0xAD, 0xAE, 0xAF, 0xB0, 0xB0, 0xB1, 0xB2, 0xB3, 0xB3, 0xB4,
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xB5, 0xB5, 0xB6, 0xB7, 0xB7, 0xB8, 0xB9, 0xBA, 0xBA, 0xBB, 0xBC, 0xBC, 0xBD, 0xBE, 0xBE, 0xBF,
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xC0, 0xC0, 0xC1, 0xC2, 0xC2, 0xC3, 0xC4, 0xC4, 0xC5, 0xC6, 0xC6, 0xC7, 0xC7, 0xC8, 0xC9, 0xC9,
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xCA, 0xCB, 0xCB, 0xCC, 0xCC, 0xCD, 0xCE, 0xCE, 0xCF, 0xD0, 0xD0, 0xD1, 0xD1, 0xD2, 0xD3, 0xD3,
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xD4, 0xD4, 0xD5, 0xD6, 0xD6, 0xD7, 0xD7, 0xD8, 0xD9, 0xD9, 0xDA, 0xDA, 0xDB, 0xDC, 0xDC, 0xDD,
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xDD, 0xDE, 0xDE, 0xDF, 0xE0, 0xE0, 0xE1, 0xE1, 0xE2, 0xE2, 0xE3, 0xE4, 0xE4, 0xE5, 0xE5, 0xE6,
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xE6, 0xE7, 0xE7, 0xE8, 0xE9, 0xE9, 0xEA, 0xEA, 0xEB, 0xEB, 0xEC, 0xEC, 0xED, 0xED, 0xEE, 0xEE,
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xEF, 0xF0, 0xF0, 0xF1, 0xF1, 0xF2, 0xF2, 0xF3, 0xF3, 0xF4, 0xF4, 0xF5, 0xF5, 0xF6, 0xF6, 0xF7,
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xF7, 0xF8, 0xF8, 0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint _BLEND(int blend_mode, int back_color, int src_color)
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    switch (blend_mode) {
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_BLEND_NORMAL:
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return src_color;
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_BLEND_MULTIPLY:
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return src_color * back_color / 255;
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_BLEND_SCREEN:
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return src_color + back_color - src_color * back_color / 255;
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_BLEND_OVERLAY:
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return _BLEND(FXDIB_BLEND_HARDLIGHT, src_color, back_color);
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_BLEND_DARKEN:
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return src_color < back_color ? src_color : back_color;
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_BLEND_LIGHTEN:
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return src_color > back_color ? src_color : back_color;
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_BLEND_COLORDODGE: {
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (src_color == 255) {
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return src_color;
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int result = back_color * 255 / (255 - src_color);
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (result > 255) {
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return 255;
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return result;
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_BLEND_COLORBURN: {
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (src_color == 0) {
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return src_color;
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int result = (255 - back_color) * 255 / src_color;
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (result > 255) {
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    result = 255;
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return 255 - result;
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_BLEND_HARDLIGHT:
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_color < 128) {
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return (src_color * back_color * 2) / 255;
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return _BLEND(FXDIB_BLEND_SCREEN, back_color, 2 * src_color - 255);
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_BLEND_SOFTLIGHT: {
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (src_color < 128) {
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return back_color - (255 - 2 * src_color) * back_color * (255 - back_color) / 255 / 255;
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return back_color + (2 * src_color - 255) * (_color_sqrt[back_color] - back_color) / 255;
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_BLEND_DIFFERENCE:
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return back_color < src_color ? src_color - back_color : back_color - src_color;
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_BLEND_EXCLUSION:
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return back_color + src_color - 2 * back_color * src_color / 255;
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return src_color;
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstruct _RGB {
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int red;
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int green;
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int blue;
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic inline int _Lum(_RGB color)
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return (color.red * 30 + color.green * 59 + color.blue * 11) / 100;
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic _RGB _ClipColor(_RGB color)
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int l = _Lum(color);
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int n = color.red;
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (color.green < n) {
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        n = color.green;
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (color.blue < n) {
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        n = color.blue;
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int x = color.red;
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (color.green > x) {
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        x = color.green;
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (color.blue > x) {
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        x = color.blue;
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (n < 0) {
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        color.red = l + ((color.red - l) * l / (l - n));
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        color.green = l + ((color.green - l) * l / (l - n));
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        color.blue = l + ((color.blue - l) * l / (l - n));
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (x > 255) {
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        color.red = l + ((color.red - l) * (255 - l) / (x - l));
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        color.green = l + ((color.green - l) * (255 - l) / (x - l));
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        color.blue = l + ((color.blue - l) * (255 - l) / (x - l));
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return color;
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic _RGB _SetLum(_RGB color, int l)
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int d = l - _Lum(color);
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    color.red += d;
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    color.green += d;
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    color.blue += d;
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return _ClipColor(color);
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic int _Sat(_RGB color)
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int n = color.red;
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (color.green < n) {
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        n = color.green;
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (color.blue < n) {
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        n = color.blue;
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int x = color.red;
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (color.green > x) {
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        x = color.green;
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (color.blue > x) {
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        x = color.blue;
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return x - n;
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic _RGB _SetSat(_RGB color, int s)
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int* max = &color.red;
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int* mid = &color.red;
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int* min = &color.red;
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (color.green > *max) {
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        max = &color.green;
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (color.blue > *max) {
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        max = &color.blue;
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (color.green < *min) {
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        min = &color.green;
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (color.blue < *min) {
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        min = &color.blue;
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (*max == *min) {
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        color.red = 0;
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        color.green = 0;
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        color.blue = 0;
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return color;
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (max == &color.red) {
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (min == &color.green) {
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            mid = &color.blue;
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            mid = &color.green;
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (max == &color.green) {
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (min == &color.red) {
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            mid = &color.blue;
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            mid = &color.red;
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (min == &color.green) {
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            mid = &color.red;
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            mid = &color.green;
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (*max > *min) {
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *mid = (*mid - *min) * s / (*max - *min);
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *max = s;
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *min = 0;
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return color;
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _RGB_Blend(int blend_mode, FX_LPCBYTE src_scan, FX_BYTE* dest_scan, int results[3])
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _RGB src, back, result;
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    src.red = src_scan[2];
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    src.green = src_scan[1];
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    src.blue = src_scan[0];
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    back.red = dest_scan[2];
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    back.green = dest_scan[1];
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    back.blue = dest_scan[0];
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    switch (blend_mode) {
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_BLEND_HUE:
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            result = _SetLum(_SetSat(src, _Sat(back)), _Lum(back));
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_BLEND_SATURATION:
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            result = _SetLum(_SetSat(back, _Sat(src)), _Lum(back));
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_BLEND_COLOR:
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            result = _SetLum(src, _Lum(back));
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_BLEND_LUMINOSITY:
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            result = _SetLum(back, _Lum(src));
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    results[0] = result.blue;
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    results[1] = result.green;
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    results[2] = result.red;
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Argb2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, FX_LPCBYTE clip_scan)
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    src_scan += 3;
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha = *src_scan;
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = clip_scan[col] * src_alpha / 255;
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE back_alpha = *dest_scan;
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!back_alpha) {
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = src_alpha;
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (src_alpha) {
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan ++;
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src_scan += 4;
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_Rgba2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_alpha_scan, int pixel_count, FX_LPCBYTE clip_scan)
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha = *src_alpha_scan++;
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = clip_scan[col] * src_alpha / 255;
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE back_alpha = *dest_scan;
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!back_alpha) {
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = src_alpha;
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (src_alpha) {
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan ++;
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_Rgb2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, FX_LPCBYTE clip_scan)
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (clip_scan) {
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int i = 0; i < width; i ++) {
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_UNION(*dest_scan, *clip_scan);
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            clip_scan ++;
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXSYS_memset8(dest_scan, 0xff, width);
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_Argb2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              FX_LPCBYTE src_alpha_scan, FX_LPBYTE dst_alpha_scan, void* pIccTransform)
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ICodec_IccModule* pIccModule = NULL;
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pIccTransform) {
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (blend_type) {
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int blended_color;
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha_scan) {
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < pixel_count; col ++) {
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE back_alpha = *dst_alpha_scan;
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (back_alpha == 0) {
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    int src_alpha = *src_alpha_scan++;
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (clip_scan) {
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        src_alpha = clip_scan[col] * src_alpha / 255;
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (src_alpha) {
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        if (pIccTransform) {
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        } else {
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            *dest_scan =  FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        }
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dst_alpha_scan = src_alpha;
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan ++;
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dst_alpha_scan ++;
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_scan += 3;
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    continue;
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE src_alpha = *src_alpha_scan++;
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (clip_scan) {
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_alpha = clip_scan[col] * src_alpha / 255;
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (src_alpha == 0) {
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan ++;
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dst_alpha_scan ++;
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_scan += 3;
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    continue;
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE gray;
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (pIccTransform) {
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (bNonseparableBlend) {
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dst_alpha_scan++;
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += 3;
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < pixel_count; col ++) {
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE back_alpha = *dst_alpha_scan;
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (back_alpha == 0) {
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    int src_alpha = src_scan[3];
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (clip_scan) {
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        src_alpha = clip_scan[col] * src_alpha / 255;
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (src_alpha) {
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        if (pIccTransform) {
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        } else {
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            *dest_scan =  FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        }
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dst_alpha_scan = src_alpha;
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan ++;
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dst_alpha_scan ++;
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_scan += 4;
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    continue;
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE src_alpha = src_scan[3];
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (clip_scan) {
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_alpha = clip_scan[col] * src_alpha / 255;
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (src_alpha == 0) {
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan ++;
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dst_alpha_scan ++;
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_scan += 4;
390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    continue;
391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE gray;
395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (pIccTransform) {
396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dst_alpha_scan++;
403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += 4;
404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_alpha_scan) {
408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < pixel_count; col ++) {
409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE back_alpha = *dst_alpha_scan;
410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (back_alpha == 0) {
411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int src_alpha = *src_alpha_scan++;
412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (clip_scan) {
413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_alpha = clip_scan[col] * src_alpha / 255;
414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (src_alpha) {
416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (pIccTransform) {
417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } else {
419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan =  FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dst_alpha_scan = src_alpha;
422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dst_alpha_scan ++;
425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += 3;
426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_alpha = *src_alpha_scan++;
429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan) {
430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = clip_scan[col] * src_alpha / 255;
431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 0) {
433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dst_alpha_scan ++;
435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += 3;
436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE gray;
441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pIccTransform) {
442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dst_alpha_scan++;
449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += 3;
450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else
452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < pixel_count; col ++) {
453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE back_alpha = *dst_alpha_scan;
454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (back_alpha == 0) {
455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int src_alpha = src_scan[3];
456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (clip_scan) {
457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_alpha = clip_scan[col] * src_alpha / 255;
458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (src_alpha) {
460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (pIccTransform) {
461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } else {
463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan =  FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dst_alpha_scan = src_alpha;
466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dst_alpha_scan ++;
469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += 4;
470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_alpha = src_scan[3];
473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan) {
474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = clip_scan[col] * src_alpha / 255;
475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 0) {
477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dst_alpha_scan ++;
479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += 4;
480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE gray;
485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pIccTransform) {
486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dst_alpha_scan++;
493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += 4;
494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Argb2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count,
497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    int blend_type, FX_LPCBYTE clip_scan,
498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    FX_LPCBYTE src_alpha_scan, void* pIccTransform)
499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ICodec_IccModule* pIccModule = NULL;
501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BYTE gray;
502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pIccTransform) {
503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (blend_type) {
506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int blended_color;
508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha_scan) {
509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < pixel_count; col ++) {
510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int src_alpha = *src_alpha_scan++;
511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (clip_scan) {
512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_alpha = clip_scan[col] * src_alpha / 255;
513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (src_alpha) {
515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (pIccTransform) {
516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } else {
518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (bNonseparableBlend) {
521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += 3;
528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else
530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < pixel_count; col ++) {
531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int src_alpha = src_scan[3];
532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (clip_scan) {
533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_alpha = clip_scan[col] * src_alpha / 255;
534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (src_alpha) {
536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (pIccTransform) {
537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } else {
539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (bNonseparableBlend) {
542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += 4;
549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_alpha_scan) {
553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < pixel_count; col ++) {
554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_alpha = *src_alpha_scan++;
555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan) {
556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = clip_scan[col] * src_alpha / 255;
557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha) {
559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (pIccTransform) {
560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += 3;
568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else
570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < pixel_count; col ++) {
571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_alpha = src_scan[3];
572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan) {
573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = clip_scan[col] * src_alpha / 255;
574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha) {
576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (pIccTransform) {
577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += 4;
585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_Bpp, int pixel_count,
588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   int blend_type, FX_LPCBYTE clip_scan,
589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   void* pIccTransform)
590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ICodec_IccModule* pIccModule = NULL;
592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BYTE gray;
593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pIccTransform) {
594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (blend_type) {
597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int blended_color;
599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < pixel_count; col ++) {
600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pIccTransform) {
601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (bNonseparableBlend) {
606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan && clip_scan[col] < 255) {
610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = gray;
613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += src_Bpp;
616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pIccTransform) {
621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan && clip_scan[col] < 255) {
626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = gray;
629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan ++;
631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src_scan += src_Bpp;
632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_Rgb2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_Bpp, int pixel_count,
635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                             int blend_type, FX_LPCBYTE clip_scan,
636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                             FX_LPBYTE dest_alpha_scan, void* pIccTransform)
637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ICodec_IccModule* pIccModule = NULL;
639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pIccTransform) {
640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (blend_type) {
643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int blended_color;
644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < pixel_count; col ++) {
646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int back_alpha = *dest_alpha_scan;
647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (back_alpha == 0) {
648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (pIccTransform) {
649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_alpha_scan++;
655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += src_Bpp;
656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_alpha = 255;
659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan) {
660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = clip_scan[col];
661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 0) {
663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_alpha_scan ++;
665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += src_Bpp;
666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_alpha_scan++ = dest_alpha;
670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int alpha_ratio = src_alpha * 255 / dest_alpha;
671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE gray;
672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pIccTransform) {
673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (bNonseparableBlend) {
678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += src_Bpp;
684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha = 255;
689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = clip_scan[col];
691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 255) {
693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pIccTransform) {
694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_alpha_scan++ = 255;
700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += src_Bpp;
701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_alpha_scan ++;
706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += src_Bpp;
707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int back_alpha = *dest_alpha_scan;
710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *dest_alpha_scan++ = dest_alpha;
712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int alpha_ratio = src_alpha * 255 / dest_alpha;
713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE gray;
714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pIccTransform) {
715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan ++;
721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src_scan += src_Bpp;
722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_Argb2Argb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                             FX_LPBYTE dest_alpha_scan, FX_LPCBYTE src_alpha_scan)
726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int blended_colors[3];
728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (dest_alpha_scan == NULL) {
730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha_scan == NULL) {
731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE back_alpha = 0;
732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < pixel_count; col ++) {
733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                back_alpha = dest_scan[3];
734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (back_alpha == 0) {
735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (clip_scan) {
736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        int src_alpha = clip_scan[col] * src_scan[3] / 255;
737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        FXARGB_SETDIB(dest_scan, (FXARGB_GETDIB(src_scan) & 0xffffff) | (src_alpha << 24));
738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } else {
739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        FXARGB_COPY(dest_scan, src_scan);
740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan += 4;
742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_scan += 4;
743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    continue;
744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE src_alpha;
746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (clip_scan == NULL) {
747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_alpha = src_scan[3];
748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_alpha = clip_scan[col] * src_scan[3] / 255;
750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (src_alpha == 0) {
752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan += 4;
753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_scan += 4;
754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    continue;
755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[3] = dest_alpha;
758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int alpha_ratio = src_alpha * 255 / dest_alpha;
759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (bNonseparableBlend) {
760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int color = 0; color < 3; color ++) {
763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (blend_type) {
764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        int blended = bNonseparableBlend ? blended_colors[color] :
765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      _BLEND(blend_type, *dest_scan, *src_scan);
766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } else {
769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan ++;
772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_scan ++;
773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan ++;
776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < pixel_count; col ++) {
779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE back_alpha = dest_scan[3];
780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (back_alpha == 0) {
781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (clip_scan) {
782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        FXARGB_SETDIB(dest_scan, FXARGB_MAKE((src_alpha << 24), src_scan[2], src_scan[1], *src_scan));
784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } else {
785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        FXARGB_SETDIB(dest_scan, FXARGB_MAKE((*src_alpha_scan << 24), src_scan[2], src_scan[1], *src_scan));
786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan += 4;
788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_scan += 3;
789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_alpha_scan ++;
790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    continue;
791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE src_alpha;
793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (clip_scan == NULL) {
794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_alpha = *src_alpha_scan ++;
795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_alpha = clip_scan[col] * (*src_alpha_scan ++) / 255;
797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (src_alpha == 0) {
799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan += 4;
800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_scan += 3;
801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    continue;
802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[3] = dest_alpha;
805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int alpha_ratio = src_alpha * 255 / dest_alpha;
806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (bNonseparableBlend) {
807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int color = 0; color < 3; color ++) {
810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (blend_type) {
811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        int blended = bNonseparableBlend ? blended_colors[color] :
812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      _BLEND(blend_type, *dest_scan, *src_scan);
813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } else {
816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan ++;
819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_scan ++;
820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha_scan) {
826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < pixel_count; col ++) {
827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE back_alpha = *dest_alpha_scan;
828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (back_alpha == 0) {
829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (clip_scan) {
830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_alpha_scan = src_alpha;
832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan++ = *src_scan++;
833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan++ = *src_scan++;
834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan++ = *src_scan++;
835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } else {
836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_alpha_scan = *src_alpha_scan;
837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan++ = *src_scan++;
838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan++ = *src_scan++;
839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan++ = *src_scan++;
840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_alpha_scan ++;
842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_alpha_scan ++;
843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    continue;
844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE src_alpha;
846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (clip_scan == NULL) {
847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_alpha = *src_alpha_scan ++;
848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_alpha = clip_scan[col] * (*src_alpha_scan ++) / 255;
850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (src_alpha == 0) {
852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan += 3;
853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_scan += 3;
854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_alpha_scan ++;
855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    continue;
856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_alpha_scan ++ = dest_alpha;
859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int alpha_ratio = src_alpha * 255 / dest_alpha;
860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (bNonseparableBlend) {
861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int color = 0; color < 3; color ++) {
864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (blend_type) {
865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        int blended = bNonseparableBlend ? blended_colors[color] :
866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      _BLEND(blend_type, *dest_scan, *src_scan);
867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } else {
870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan ++;
873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_scan ++;
874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < pixel_count; col ++) {
878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE back_alpha = *dest_alpha_scan;
879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (back_alpha == 0) {
880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (clip_scan) {
881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        int src_alpha = clip_scan[col] * src_scan[3] / 255;
882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_alpha_scan = src_alpha;
883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan++ = *src_scan++;
884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan++ = *src_scan++;
885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan++ = *src_scan++;
886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } else {
887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_alpha_scan = src_scan[3];
888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan++ = *src_scan++;
889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan++ = *src_scan++;
890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan++ = *src_scan++;
891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_alpha_scan ++;
893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_scan ++;
894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    continue;
895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE src_alpha;
897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (clip_scan == NULL) {
898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_alpha = src_scan[3];
899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_alpha = clip_scan[col] * src_scan[3] / 255;
901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (src_alpha == 0) {
903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan += 3;
904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_scan += 4;
905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_alpha_scan ++;
906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    continue;
907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_alpha_scan++ = dest_alpha;
910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int alpha_ratio = src_alpha * 255 / dest_alpha;
911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (bNonseparableBlend) {
912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int color = 0; color < 3; color ++) {
915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (blend_type) {
916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        int blended = bNonseparableBlend ? blended_colors[color] :
917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      _BLEND(blend_type, *dest_scan, *src_scan);
918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } else {
921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan ++;
924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_scan ++;
925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan ++;
927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_Rgb2Argb_Blend_NoClip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp,
932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dest_alpha_scan)
933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int blended_colors[3];
935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int src_gap = src_Bpp - 3;
937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (dest_alpha_scan == NULL) {
938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE back_alpha = dest_scan[3];
940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (back_alpha == 0) {
941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (src_Bpp == 4) {
942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FXARGB_SETDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += 4;
947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += src_Bpp;
948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[3] = 0xff;
951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (bNonseparableBlend) {
952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int color = 0; color < 3; color ++) {
955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int src_color = *src_scan;
956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int blended = bNonseparableBlend ? blended_colors[color] :
957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              _BLEND(blend_type, *dest_scan, src_color);
958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan ++;
961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += src_gap;
964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE back_alpha = *dest_alpha_scan;
968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (back_alpha == 0) {
969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_alpha_scan++ = 0xff;
973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += src_gap;
974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_alpha_scan++ = 0xff;
977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (bNonseparableBlend) {
978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int color = 0; color < 3; color ++) {
981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int src_color = *src_scan;
982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int blended = bNonseparableBlend ? blended_colors[color] :
983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              _BLEND(blend_type, *dest_scan, src_color);
984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan ++;
987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += src_gap;
989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Argb_Blend_Clip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp, FX_LPCBYTE clip_scan,
993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dest_alpha_scan)
994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int blended_colors[3];
996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int src_gap = src_Bpp - 3;
998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (dest_alpha_scan == NULL) {
999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
1000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_alpha = *clip_scan ++;
1001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE back_alpha = dest_scan[3];
1002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (back_alpha == 0) {
1003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
1004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
1005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
1006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += src_gap;
1007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
1008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 0) {
1011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += 4;
1012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += src_Bpp;
1013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[3] = dest_alpha;
1017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int alpha_ratio = src_alpha * 255 / dest_alpha;
1018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (bNonseparableBlend) {
1019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
1020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int color = 0; color < 3; color ++) {
1022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int src_color = *src_scan;
1023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int blended = bNonseparableBlend ? blended_colors[color] :
1024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              _BLEND(blend_type, *dest_scan, src_color);
1025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
1026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
1027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
1028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan ++;
1029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
1031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += src_gap;
1032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
1035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_alpha = *clip_scan ++;
1036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE back_alpha = *dest_alpha_scan;
1037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (back_alpha == 0) {
1038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
1039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
1040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
1041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += src_gap;
1042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_alpha_scan++;
1043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 0) {
1046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += 3;
1047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_alpha_scan++;
1048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += src_Bpp;
1049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_alpha_scan++ = dest_alpha;
1053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int alpha_ratio = src_alpha * 255 / dest_alpha;
1054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (bNonseparableBlend) {
1055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
1056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int color = 0; color < 3; color ++) {
1058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int src_color = *src_scan;
1059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int blended = bNonseparableBlend ? blended_colors[color] :
1060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              _BLEND(blend_type, *dest_scan, src_color);
1061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
1062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
1063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
1064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan ++;
1065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += src_gap;
1067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Argb_NoBlend_Clip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp, FX_LPCBYTE clip_scan,
1071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dest_alpha_scan)
1072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int src_gap = src_Bpp - 3;
1074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (dest_alpha_scan == NULL) {
1075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
1076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_alpha = clip_scan[col];
1077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 255) {
1078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
1079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
1080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
1081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = 255;
1082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += src_gap;
1083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 0) {
1086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += 4;
1087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += src_Bpp;
1088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int back_alpha = dest_scan[3];
1091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[3] = dest_alpha;
1093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int alpha_ratio = src_alpha * 255 / dest_alpha;
1094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int color = 0; color < 3; color ++) {
1095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
1096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
1097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan ++;
1098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
1100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += src_gap;
1101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
1104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_alpha = clip_scan[col];
1105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 255) {
1106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
1107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
1108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
1109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_alpha_scan++ = 255;
1110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += src_gap;
1111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 0) {
1114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += 3;
1115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_alpha_scan ++;
1116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += src_Bpp;
1117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int back_alpha = *dest_alpha_scan;
1120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_alpha_scan ++ = dest_alpha;
1122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int alpha_ratio = src_alpha * 255 / dest_alpha;
1123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int color = 0; color < 3; color ++) {
1124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
1125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
1126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan ++;
1127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += src_gap;
1129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Argb_NoBlend_NoClip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp,
1133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dest_alpha_scan)
1134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (dest_alpha_scan == NULL) {
1136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
1137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_Bpp == 4) {
1138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FXARGB_SETDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
1139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
1140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
1141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
1143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += src_Bpp;
1144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_gap = src_Bpp - 3;
1147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
1148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = *src_scan++;
1149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = *src_scan++;
1150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = *src_scan++;
1151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_alpha_scan++ = 0xff;
1152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += src_gap;
1153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Argb2Rgb_Blend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, FX_LPCBYTE clip_scan,
1157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE src_alpha_scan)
1158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int blended_colors[3];
1160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int dest_gap = dest_Bpp - 3;
1162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_alpha_scan == NULL) {
1163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
1164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_alpha;
1165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan) {
1166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = src_scan[3] * (*clip_scan++) / 255;
1167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
1168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = src_scan[3];
1169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 0) {
1171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += dest_Bpp;
1172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += 4;
1173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (bNonseparableBlend) {
1176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
1177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int color = 0; color < 3; color ++) {
1179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int back_color = *dest_scan;
1180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int blended = bNonseparableBlend ? blended_colors[color] :
1181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              _BLEND(blend_type, back_color, *src_scan);
1182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
1183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
1184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan ++;
1185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += dest_gap;
1187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
1188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
1191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_alpha;
1192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan) {
1193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255;
1194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
1195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = *src_alpha_scan++;
1196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 0) {
1198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += dest_Bpp;
1199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += 3;
1200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (bNonseparableBlend) {
1203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
1204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int color = 0; color < 3; color ++) {
1206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int back_color = *dest_scan;
1207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int blended = bNonseparableBlend ? blended_colors[color] :
1208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              _BLEND(blend_type, back_color, *src_scan);
1209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
1210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
1211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan ++;
1212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += dest_gap;
1214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Argb2Rgb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, FX_LPCBYTE clip_scan,
1218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE src_alpha_scan)
1219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int dest_gap = dest_Bpp - 3;
1221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_alpha_scan == NULL) {
1222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
1223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_alpha;
1224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan) {
1225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = src_scan[3] * (*clip_scan++) / 255;
1226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
1227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = src_scan[3];
1228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 255) {
1230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
1231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
1232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
1233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += dest_gap;
1234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan ++;
1235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 0) {
1238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += dest_Bpp;
1239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += 4;
1240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int color = 0; color < 3; color ++) {
1243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
1244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
1245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan ++;
1246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += dest_gap;
1248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
1249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
1252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_alpha;
1253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan) {
1254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255;
1255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
1256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = *src_alpha_scan++;
1257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 255) {
1259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
1260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
1261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
1262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += dest_gap;
1263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 0) {
1266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += dest_Bpp;
1267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += 3;
1268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int color = 0; color < 3; color ++) {
1271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
1272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
1273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan ++;
1274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += dest_gap;
1276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Rgb_Blend_NoClip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp)
1280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int blended_colors[3];
1282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int dest_gap = dest_Bpp - 3;
1284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int src_gap = src_Bpp - 3;
1285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < width; col ++) {
1286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (bNonseparableBlend) {
1287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
1288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int color = 0; color < 3; color ++) {
1290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int back_color = *dest_scan;
1291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_color = *src_scan;
1292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended = bNonseparableBlend ? blended_colors[color] :
1293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                          _BLEND(blend_type, back_color, src_color);
1294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = blended;
1295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
1296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
1297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += dest_gap;
1299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src_scan += src_gap;
1300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Rgb_Blend_Clip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan)
1303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int blended_colors[3];
1305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int dest_gap = dest_Bpp - 3;
1307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int src_gap = src_Bpp - 3;
1308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < width; col ++) {
1309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE src_alpha = *clip_scan ++;
1310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
1311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += dest_Bpp;
1312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += src_Bpp;
1313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
1314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (bNonseparableBlend) {
1316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
1317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int color = 0; color < 3; color ++) {
1319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_color = *src_scan;
1320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int back_color = *dest_scan;
1321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended = bNonseparableBlend ? blended_colors[color] :
1322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                          _BLEND(blend_type, back_color, src_color);
1323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
1324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
1325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
1326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += dest_gap;
1328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src_scan += src_gap;
1329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp)
1332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (dest_Bpp == src_Bpp) {
1334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXSYS_memcpy32(dest_scan, src_scan, width * dest_Bpp);
1335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < width; col ++) {
1338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[0] = src_scan[0];
1339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[1] = src_scan[1];
1340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[2] = src_scan[2];
1341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += dest_Bpp;
1342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src_scan += src_Bpp;
1343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Rgb_NoBlend_Clip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan)
1346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < width; col ++) {
1348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha = clip_scan[col];
1349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 255) {
1350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = src_scan[0];
1351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = src_scan[1];
1352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = src_scan[2];
1353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (src_alpha) {
1354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
1355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
1356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
1357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
1358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
1359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
1360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
1361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += dest_Bpp - 2;
1362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += src_Bpp - 2;
1363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
1364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += dest_Bpp;
1366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src_scan += src_Bpp;
1367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_Argb2Argb_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
1370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                       FX_LPBYTE dest_alpha_scan, FX_LPCBYTE src_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
1371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPBYTE dp = src_cache_scan;
1373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_alpha_scan) {
1375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (dest_alpha_scan == NULL) {
1376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < pixel_count; col ++) {
1377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dp[3] = *src_alpha_scan++;
1379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += 3;
1380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dp += 4;
1381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha_scan = NULL;
1383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
1384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pIccModule->TranslateScanline(pIccTransform, dp, src_scan, pixel_count);
1385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (dest_alpha_scan == NULL) {
1388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < pixel_count; col ++) {
1389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dp[3] = src_scan[3];
1391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += 4;
1392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dp += 4;
1393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
1395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended_colors[3];
1396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < pixel_count; col ++) {
1398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1);
1399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE back_alpha = *dest_alpha_scan;
1400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (back_alpha == 0) {
1401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (clip_scan) {
1402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        int src_alpha = clip_scan[col] * src_scan[3] / 255;
1403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_alpha_scan = src_alpha;
1404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan++ = *src_cache_scan++;
1405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan++ = *src_cache_scan++;
1406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan++ = *src_cache_scan++;
1407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } else {
1408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_alpha_scan = src_scan[3];
1409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan++ = *src_cache_scan++;
1410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan++ = *src_cache_scan++;
1411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan++ = *src_cache_scan++;
1412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
1413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_alpha_scan ++;
1414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_scan += 4;
1415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    continue;
1416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE src_alpha;
1418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (clip_scan == NULL) {
1419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_alpha = src_scan[3];
1420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
1421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_alpha = clip_scan[col] * src_scan[3] / 255;
1422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += 4;
1424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (src_alpha == 0) {
1425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan += 3;
1426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_cache_scan += 3;
1427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_alpha_scan ++;
1428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    continue;
1429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_alpha_scan ++ = dest_alpha;
1432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int alpha_ratio = src_alpha * 255 / dest_alpha;
1433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (bNonseparableBlend) {
1434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    _RGB_Blend(blend_type, src_cache_scan, dest_scan, blended_colors);
1435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int color = 0; color < 3; color ++) {
1437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (blend_type) {
1438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        int blended = bNonseparableBlend ? blended_colors[color] :
1439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      _BLEND(blend_type, *dest_scan, *src_cache_scan);
1440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        blended = FXDIB_ALPHA_MERGE(*src_cache_scan, blended, back_alpha);
1441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
1442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } else {
1443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_cache_scan, alpha_ratio);
1444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
1445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan ++;
1446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_cache_scan ++;
1447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
1450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _CompositeRow_Argb2Argb(dest_scan, src_cache_scan, pixel_count, blend_type, clip_scan, dest_alpha_scan, src_alpha_scan);
1453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_Rgb2Argb_Blend_NoClip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp,
1455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dest_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
1456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_Bpp == 3) {
1459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dp = src_cache_scan;
1462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
1463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += 4;
1465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dp += 3;
1466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _CompositeRow_Rgb2Argb_Blend_NoClip(dest_scan, src_cache_scan, width, blend_type, 3, dest_alpha_scan);
1469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Argb_Blend_Clip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp, FX_LPCBYTE clip_scan,
1471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dest_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
1472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_Bpp == 3) {
1475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dp = src_cache_scan;
1478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
1479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += 4;
1481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dp += 3;
1482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _CompositeRow_Rgb2Argb_Blend_Clip(dest_scan, src_cache_scan, width, blend_type, 3, clip_scan, dest_alpha_scan);
1485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Argb_NoBlend_Clip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp, FX_LPCBYTE clip_scan,
1487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dest_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
1488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_Bpp == 3) {
1491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dp = src_cache_scan;
1494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
1495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += 4;
1497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dp += 3;
1498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _CompositeRow_Rgb2Argb_NoBlend_Clip(dest_scan, src_cache_scan, width, 3, clip_scan, dest_alpha_scan);
1501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Argb_NoBlend_NoClip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp,
1503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dest_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
1504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_Bpp == 3) {
1507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dp = src_cache_scan;
1510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
1511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += 4;
1513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dp += 3;
1514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _CompositeRow_Rgb2Argb_NoBlend_NoClip(dest_scan, src_cache_scan, width, 3, dest_alpha_scan);
1517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Argb2Rgb_Blend_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, FX_LPCBYTE clip_scan,
1519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE src_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
1520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_alpha_scan) {
1523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int blended_colors[3];
1526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int dest_gap = dest_Bpp - 3;
1528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
1529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1);
1530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_alpha;
1531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan) {
1532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = src_scan[3] * (*clip_scan++) / 255;
1533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
1534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = src_scan[3];
1535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += 4;
1537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 0) {
1538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += dest_Bpp;
1539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_cache_scan += 3;
1540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (bNonseparableBlend) {
1543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _RGB_Blend(blend_type, src_cache_scan, dest_scan, blended_colors);
1544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int color = 0; color < 3; color ++) {
1546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int back_color = *dest_scan;
1547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int blended = bNonseparableBlend ? blended_colors[color] :
1548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              _BLEND(blend_type, back_color, *src_cache_scan);
1549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
1550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
1551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_cache_scan ++;
1552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += dest_gap;
1554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _CompositeRow_Argb2Rgb_Blend(dest_scan, src_cache_scan, width, blend_type, dest_Bpp, clip_scan, src_alpha_scan);
1558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Argb2Rgb_NoBlend_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, FX_LPCBYTE clip_scan,
1560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE src_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
1561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_alpha_scan) {
1564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int dest_gap = dest_Bpp - 3;
1567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
1568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1);
1569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_alpha;
1570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan) {
1571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = src_scan[3] * (*clip_scan++) / 255;
1572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
1573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = src_scan[3];
1574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += 4;
1576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 255) {
1577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_cache_scan++;
1578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_cache_scan++;
1579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_cache_scan++;
1580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += dest_gap;
1581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 0) {
1584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += dest_Bpp;
1585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_cache_scan += 3;
1586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int color = 0; color < 3; color ++) {
1589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_cache_scan, src_alpha);
1590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
1591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_cache_scan ++;
1592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += dest_gap;
1594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _CompositeRow_Argb2Rgb_NoBlend(dest_scan, src_cache_scan, width, dest_Bpp, clip_scan, src_alpha_scan);
1598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Rgb_Blend_NoClip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp,
1600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE src_cache_scan, void* pIccTransform)
1601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_Bpp == 3) {
1604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dp = src_cache_scan;
1607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
1608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += 4;
1610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dp += 3;
1611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _CompositeRow_Rgb2Rgb_Blend_NoClip(dest_scan, src_cache_scan, width, blend_type, dest_Bpp, 3);
1614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Rgb_Blend_Clip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan,
1616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE src_cache_scan, void* pIccTransform)
1617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_Bpp == 3) {
1620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dp = src_cache_scan;
1623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
1624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += 4;
1626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dp += 3;
1627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _CompositeRow_Rgb2Rgb_Blend_Clip(dest_scan, src_cache_scan, width, blend_type, dest_Bpp, 3, clip_scan);
1630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp,
1632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE src_cache_scan, void* pIccTransform)
1633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_Bpp == 3) {
1636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dp = src_cache_scan;
1639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
1640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += 4;
1642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dp += 3;
1643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _CompositeRow_Rgb2Rgb_NoBlend_NoClip(dest_scan, src_cache_scan, width, dest_Bpp, 3);
1646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Rgb_NoBlend_Clip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan,
1648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE src_cache_scan, void* pIccTransform)
1649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_Bpp == 3) {
1652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dp = src_cache_scan;
1655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
1656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += 4;
1658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dp += 3;
1659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _CompositeRow_Rgb2Rgb_NoBlend_Clip(dest_scan, src_cache_scan, width, dest_Bpp, 3, clip_scan);
1662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_8bppPal2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, FX_LPCBYTE pPalette, int pixel_count,
1664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                       int blend_type, FX_LPCBYTE clip_scan,
1665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                       FX_LPCBYTE src_alpha_scan)
1666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_alpha_scan) {
1668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (blend_type) {
1669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended_color;
1671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < pixel_count; col ++) {
1672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE gray = pPalette[*src_scan];
1673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int src_alpha = *src_alpha_scan++;
1674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (clip_scan) {
1675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_alpha = clip_scan[col] * src_alpha / 255;
1676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (bNonseparableBlend) {
1678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
1679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
1681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (src_alpha) {
1682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
1683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
1684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan = gray;
1685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
1687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan ++;
1688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
1690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < pixel_count; col ++) {
1692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE gray = pPalette[*src_scan];
1693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_alpha = *src_alpha_scan++;
1694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan) {
1695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = clip_scan[col] * src_alpha / 255;
1696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha) {
1698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
1699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
1700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = gray;
1701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
1703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
1704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (blend_type) {
1707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended_color;
1709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < pixel_count; col ++) {
1710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE gray = pPalette[*src_scan];
1711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (bNonseparableBlend) {
1712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
1713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
1715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (clip_scan && clip_scan[col] < 255) {
1716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
1717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
1718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan = gray;
1719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
1721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan ++;
1722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
1724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < pixel_count; col ++) {
1726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE gray = pPalette[*src_scan];
1727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan && clip_scan[col] < 255) {
1728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
1729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
1730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = gray;
1731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
1733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
1734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_8bppPal2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, FX_LPCBYTE pPalette, int pixel_count,
1738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        int blend_type, FX_LPCBYTE clip_scan,
1739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        FX_LPBYTE dest_alpha_scan, FX_LPCBYTE src_alpha_scan)
1740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_alpha_scan) {
1742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (blend_type) {
1743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended_color;
1745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < pixel_count; col ++) {
1746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE gray = pPalette[*src_scan];
1747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan ++;
1748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE back_alpha = *dest_alpha_scan;
1749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (back_alpha == 0) {
1750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    int src_alpha = *src_alpha_scan ++;
1751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (clip_scan) {
1752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        src_alpha = clip_scan[col] * src_alpha / 255;
1753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
1754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (src_alpha) {
1755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan = gray;
1756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_alpha_scan = src_alpha;
1757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
1758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan ++;
1759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_alpha_scan ++;
1760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    continue;
1761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE src_alpha = *src_alpha_scan++;
1763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (clip_scan) {
1764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_alpha = clip_scan[col] * src_alpha / 255;
1765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (src_alpha == 0) {
1767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan ++;
1768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_alpha_scan ++;
1769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    continue;
1770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_alpha_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int alpha_ratio = src_alpha * 255 / (*dest_alpha_scan);
1773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (bNonseparableBlend) {
1774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
1775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
1777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
1778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_alpha_scan ++;
1779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
1780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
1782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < pixel_count; col ++) {
1784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE gray = pPalette[*src_scan];
1785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
1786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE back_alpha = *dest_alpha_scan;
1787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (back_alpha == 0) {
1788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int src_alpha = *src_alpha_scan ++;
1789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (clip_scan) {
1790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_alpha = clip_scan[col] * src_alpha / 255;
1791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (src_alpha) {
1793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan = gray;
1794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_alpha_scan = src_alpha;
1795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
1797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_alpha_scan ++;
1798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_alpha = *src_alpha_scan++;
1801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan) {
1802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = clip_scan[col] * src_alpha / 255;
1803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 0) {
1805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
1806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_alpha_scan ++;
1807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_alpha_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int alpha_ratio = src_alpha * 255 / (*dest_alpha_scan);
1811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_alpha_scan ++;
1812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
1813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
1814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (blend_type) {
1817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended_color;
1819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < pixel_count; col ++) {
1820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE gray = pPalette[*src_scan];
1821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan ++;
1822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (clip_scan == NULL || clip_scan[col] == 255) {
1823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan++ = gray;
1824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_alpha_scan++ = 255;
1825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    continue;
1826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int src_alpha = clip_scan[col];
1828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (src_alpha == 0) {
1829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan ++;
1830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_alpha_scan ++;
1831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    continue;
1832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int back_alpha = *dest_alpha_scan;
1834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_alpha_scan ++ = dest_alpha;
1836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int alpha_ratio = src_alpha * 255 / dest_alpha;
1837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (bNonseparableBlend) {
1838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
1839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
1841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
1842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
1843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
1845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < pixel_count; col ++) {
1847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE gray = pPalette[*src_scan];
1848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
1849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan == NULL || clip_scan[col] == 255) {
1850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = gray;
1851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_alpha_scan++ = 255;
1852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_alpha = clip_scan[col];
1855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 0) {
1856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
1857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_alpha_scan ++;
1858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int back_alpha = *dest_alpha_scan;
1861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_alpha_scan ++ = dest_alpha;
1863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int alpha_ratio = src_alpha * 255 / dest_alpha;
1864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
1865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
1866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_1bppPal2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left,
1870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                       FX_LPCBYTE pPalette, int pixel_count, int blend_type, FX_LPCBYTE clip_scan)
1871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int reset_gray = pPalette[0];
1873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int set_gray = pPalette[1];
1874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (blend_type) {
1875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int blended_color;
1877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < pixel_count; col ++) {
1878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray;
1879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (bNonseparableBlend) {
1880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
1881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
1883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan && clip_scan[col] < 255) {
1884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
1885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
1886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = gray;
1887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
1889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
1893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray;
1894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan && clip_scan[col] < 255) {
1895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
1896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
1897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = gray;
1898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan ++;
1900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_1bppPal2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left,
1903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        FX_LPCBYTE pPalette, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
1904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        FX_LPBYTE dest_alpha_scan)
1905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int reset_gray = pPalette[0];
1907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int set_gray = pPalette[1];
1908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (blend_type) {
1909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int blended_color;
1911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < pixel_count; col ++) {
1912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray;
1913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan == NULL || clip_scan[col] == 255) {
1914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = gray;
1915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_alpha_scan ++ = 255;
1916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_alpha = clip_scan[col];
1919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 0) {
1920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
1921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_alpha_scan ++;
1922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int back_alpha = *dest_alpha_scan;
1925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_alpha_scan ++ = dest_alpha;
1927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int alpha_ratio = src_alpha * 255 / dest_alpha;
1928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (bNonseparableBlend) {
1929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
1930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
1932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
1933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
1934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
1938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray;
1939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan == NULL || clip_scan[col] == 255) {
1940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = gray;
1941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_alpha_scan ++ = 255;
1942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
1943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha = clip_scan[col];
1945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
1946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
1947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_alpha_scan ++;
1948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
1949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int back_alpha = *dest_alpha_scan;
1951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *dest_alpha_scan ++ = dest_alpha;
1953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int alpha_ratio = src_alpha * 255 / dest_alpha;
1954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
1955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan ++;
1956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_8bppRgb2Rgb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, FX_DWORD* pPalette, int pixel_count,
1959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int DestBpp, FX_LPCBYTE clip_scan,
1960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE src_alpha_scan)
1961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_alpha_scan) {
1963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int dest_gap = DestBpp - 3;
1964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_ARGB argb = 0;
1965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < pixel_count; col ++) {
1966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            argb = pPalette[*src_scan];
1967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_r = FXARGB_R(argb);
1968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_g = FXARGB_G(argb);
1969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_b = FXARGB_B(argb);
1970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
1971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_alpha = 0;
1972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan) {
1973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255;
1974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
1975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = *src_alpha_scan++;
1976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 255) {
1978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = src_b;
1979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = src_g;
1980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = src_r;
1981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += dest_gap;
1982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 0) {
1985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += DestBpp;
1986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha);
1989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
1990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha);
1991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
1992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha);
1993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
1994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += dest_gap;
1995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_ARGB argb = 0;
1998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < pixel_count; col ++) {
1999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            argb = pPalette[*src_scan];
2000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_r = FXARGB_R(argb);
2001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_g = FXARGB_G(argb);
2002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_b = FXARGB_B(argb);
2003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan && clip_scan[col] < 255) {
2004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, clip_scan[col]);
2005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
2006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, clip_scan[col]);
2007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
2008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, clip_scan[col]);
2009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
2010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
2011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = src_b;
2012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = src_g;
2013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = src_r;
2014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
2015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (DestBpp == 4) {
2016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan++;
2017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
2018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
2019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_1bppRgb2Rgb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left,
2023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_DWORD* pPalette, int pixel_count, int DestBpp, FX_LPCBYTE clip_scan)
2024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int reset_r, reset_g, reset_b;
2026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int set_r, set_g, set_b;
2027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    reset_r = FXARGB_R(pPalette[0]);
2028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    reset_g = FXARGB_G(pPalette[0]);
2029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    reset_b = FXARGB_B(pPalette[0]);
2030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    set_r = FXARGB_R(pPalette[1]);
2031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    set_g = FXARGB_G(pPalette[1]);
2032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    set_b = FXARGB_B(pPalette[1]);
2033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
2034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_r, src_g, src_b;
2035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
2036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_r = set_r;
2037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_g = set_g;
2038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_b = set_b;
2039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_r = reset_r;
2041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_g = reset_g;
2042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_b = reset_b;
2043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan && clip_scan[col] < 255) {
2045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, clip_scan[col]);
2046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, clip_scan[col]);
2048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, clip_scan[col]);
2050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = src_b;
2053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = src_g;
2054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = src_r;
2055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (DestBpp == 4) {
2057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan++;
2058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_8bppRgb2Argb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width,
2062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_DWORD* pPalette, FX_LPCBYTE clip_scan,
2063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE src_alpha_scan)
2064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_alpha_scan) {
2066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
2067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_ARGB argb = pPalette[*src_scan];
2068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
2069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_r = FXARGB_R(argb);
2070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_g = FXARGB_G(argb);
2071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_b = FXARGB_B(argb);
2072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE back_alpha = dest_scan[3];
2073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (back_alpha == 0) {
2074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (clip_scan) {
2075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
2076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
2077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
2078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FXARGB_SETDIB(dest_scan, FXARGB_MAKE(*src_alpha_scan, src_r, src_g, src_b));
2079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
2080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += 4;
2081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha_scan ++;
2082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
2083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
2084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_alpha;
2085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan == NULL) {
2086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = *src_alpha_scan ++;
2087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
2088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = clip_scan[col] * (*src_alpha_scan++) / 255;
2089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
2090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 0) {
2091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += 4;
2092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
2093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
2094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[3] = dest_alpha;
2096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int alpha_ratio = src_alpha * 255 / dest_alpha;
2097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else
2106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
2107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_ARGB argb = pPalette[*src_scan];
2108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_r = FXARGB_R(argb);
2109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_g = FXARGB_G(argb);
2110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_b = FXARGB_B(argb);
2111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan == NULL || clip_scan[col] == 255) {
2112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = src_b;
2113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = src_g;
2114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = src_r;
2115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = 255;
2116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan ++;
2117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
2118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
2119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_alpha = clip_scan[col];
2120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 0) {
2121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += 4;
2122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan ++;
2123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
2124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
2125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int back_alpha = dest_scan[3];
2126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[3] = dest_alpha;
2128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int alpha_ratio = src_alpha * 255 / dest_alpha;
2129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
2137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_8bppRgb2Rgba_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width,
2140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        FX_DWORD* pPalette, FX_LPCBYTE clip_scan,
2141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        FX_LPBYTE dest_alpha_scan, FX_LPCBYTE src_alpha_scan)
2142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_alpha_scan) {
2144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
2145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_ARGB argb = pPalette[*src_scan];
2146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
2147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_r = FXARGB_R(argb);
2148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_g = FXARGB_G(argb);
2149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_b = FXARGB_B(argb);
2150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE back_alpha = *dest_alpha_scan;
2151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (back_alpha == 0) {
2152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (clip_scan) {
2153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
2154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_alpha_scan ++ = src_alpha;
2155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
2156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_alpha_scan ++ = *src_alpha_scan;
2157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
2158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan ++ = src_b;
2159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan ++ = src_g;
2160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan ++ = src_r;
2161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha_scan ++;
2162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
2163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
2164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_alpha;
2165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan == NULL) {
2166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = *src_alpha_scan++;
2167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
2168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_alpha = clip_scan[col] * (*src_alpha_scan++) / 255;
2169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
2170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 0) {
2171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += 3;
2172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_alpha_scan ++;
2173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
2174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
2175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_alpha_scan ++ = dest_alpha;
2177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int alpha_ratio = src_alpha * 255 / dest_alpha;
2178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else
2186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
2187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_ARGB argb = pPalette[*src_scan];
2188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_r = FXARGB_R(argb);
2189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_g = FXARGB_G(argb);
2190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_b = FXARGB_B(argb);
2191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan == NULL || clip_scan[col] == 255) {
2192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = src_b;
2193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = src_g;
2194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = src_r;
2195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_alpha_scan++ = 255;
2196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan ++;
2197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
2198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
2199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_alpha = clip_scan[col];
2200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 0) {
2201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += 3;
2202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_alpha_scan ++;
2203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan ++;
2204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
2205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
2206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int back_alpha = *dest_alpha_scan;
2207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_alpha_scan ++ = dest_alpha;
2209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int alpha_ratio = src_alpha * 255 / dest_alpha;
2210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
2217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_1bppRgb2Argb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width,
2220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_DWORD* pPalette, FX_LPCBYTE clip_scan)
2221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int reset_r, reset_g, reset_b;
2223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int set_r, set_g, set_b;
2224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    reset_r = FXARGB_R(pPalette[0]);
2225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    reset_g = FXARGB_G(pPalette[0]);
2226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    reset_b = FXARGB_B(pPalette[0]);
2227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    set_r = FXARGB_R(pPalette[1]);
2228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    set_g = FXARGB_G(pPalette[1]);
2229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    set_b = FXARGB_B(pPalette[1]);
2230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < width; col ++) {
2231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_r, src_g, src_b;
2232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
2233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_r = set_r;
2234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_g = set_g;
2235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_b = set_b;
2236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_r = reset_r;
2238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_g = reset_g;
2239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_b = reset_b;
2240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan == NULL || clip_scan[col] == 255) {
2242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = src_b;
2243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = src_g;
2244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = src_r;
2245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = 255;
2246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha = clip_scan[col];
2249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
2250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
2251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int back_alpha = dest_scan[3];
2254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[3] = dest_alpha;
2256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int alpha_ratio = src_alpha * 255 / dest_alpha;
2257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan ++;
2259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan ++;
2261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan ++;
2263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan ++;
2264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_1bppRgb2Rgba_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width,
2267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        FX_DWORD* pPalette, FX_LPCBYTE clip_scan,
2268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        FX_LPBYTE dest_alpha_scan)
2269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int reset_r, reset_g, reset_b;
2271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int set_r, set_g, set_b;
2272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    reset_r = FXARGB_R(pPalette[0]);
2273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    reset_g = FXARGB_G(pPalette[0]);
2274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    reset_b = FXARGB_B(pPalette[0]);
2275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    set_r = FXARGB_R(pPalette[1]);
2276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    set_g = FXARGB_G(pPalette[1]);
2277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    set_b = FXARGB_B(pPalette[1]);
2278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < width; col ++) {
2279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_r, src_g, src_b;
2280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
2281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_r = set_r;
2282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_g = set_g;
2283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_b = set_b;
2284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_r = reset_r;
2286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_g = reset_g;
2287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_b = reset_b;
2288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan == NULL || clip_scan[col] == 255) {
2290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = src_b;
2291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = src_g;
2292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = src_r;
2293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_alpha_scan++ = 255;
2294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha = clip_scan[col];
2297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
2298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 3;
2299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_alpha_scan ++;
2300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int back_alpha = *dest_alpha_scan;
2303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *dest_alpha_scan ++ = dest_alpha;
2305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int alpha_ratio = src_alpha * 255 / dest_alpha;
2306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan ++;
2308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan ++;
2310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan ++;
2312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_ByteMask2Argb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
2315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                 int blend_type, FX_LPCBYTE clip_scan)
2316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
2318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha;
2319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
2320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
2321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * src_scan[col] / 255;
2323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE back_alpha = dest_scan[3];
2325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (back_alpha == 0) {
2326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
2327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
2328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
2331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
2332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[3] = dest_alpha;
2336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int alpha_ratio = src_alpha * 255 / dest_alpha;
2337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
2338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended_colors[3];
2339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_scan[3];
2340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[0] = src_b;
2341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[1] = src_g;
2342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[2] = src_r;
2343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
2344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
2345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
2347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
2349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (blend_type) {
2350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended = _BLEND(blend_type, *dest_scan, src_b);
2351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
2352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = _BLEND(blend_type, *dest_scan, src_g);
2355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
2356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = _BLEND(blend_type, *dest_scan, src_r);
2359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
2360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += 2;
2369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_ByteMask2Rgba(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
2372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                 int blend_type, FX_LPCBYTE clip_scan,
2373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                 FX_LPBYTE dest_alpha_scan)
2374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
2376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha;
2377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
2378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
2379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * src_scan[col] / 255;
2381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE back_alpha = *dest_alpha_scan;
2383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (back_alpha == 0) {
2384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan ++ = src_b;
2385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan ++ = src_g;
2386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan ++ = src_r;
2387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_alpha_scan ++ = src_alpha;
2388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
2391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 3;
2392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_alpha_scan ++;
2393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *dest_alpha_scan ++ = dest_alpha;
2397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int alpha_ratio = src_alpha * 255 / dest_alpha;
2398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
2399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended_colors[3];
2400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_scan[3];
2401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[0] = src_b;
2402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[1] = src_g;
2403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[2] = src_r;
2404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
2405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
2406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
2408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
2410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (blend_type) {
2412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended = _BLEND(blend_type, *dest_scan, src_b);
2413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
2414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = _BLEND(blend_type, *dest_scan, src_g);
2417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
2418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = _BLEND(blend_type, *dest_scan, src_r);
2421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
2422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_ByteMask2Rgb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
2435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                int blend_type, int Bpp, FX_LPCBYTE clip_scan)
2436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
2438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha;
2439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
2440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
2441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * src_scan[col] / 255;
2443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
2445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += Bpp;
2446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
2449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended_colors[3];
2450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_scan[3];
2451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[0] = src_b;
2452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[1] = src_g;
2453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[2] = src_r;
2454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
2455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], src_alpha);
2456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], src_alpha);
2458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], src_alpha);
2460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (blend_type) {
2461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended = _BLEND(blend_type, *dest_scan, src_b);
2462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
2463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = _BLEND(blend_type, *dest_scan, src_g);
2465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
2466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = _BLEND(blend_type, *dest_scan, src_r);
2468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
2469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha);
2471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha);
2473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha);
2475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += Bpp - 2;
2477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_ByteMask2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int pixel_count,
2480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                 FX_LPCBYTE clip_scan)
2481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
2483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha;
2484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
2485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
2486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * src_scan[col] / 255;
2488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE back_alpha = *dest_scan;
2490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!back_alpha) {
2491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = src_alpha;
2492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (src_alpha) {
2493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan ++;
2496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_ByteMask2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_gray,
2499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                 int pixel_count, FX_LPCBYTE clip_scan)
2500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
2502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha;
2503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
2504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
2505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * src_scan[col] / 255;
2507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha) {
2509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, src_alpha);
2510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan ++;
2512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_ByteMask2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_gray,
2515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                  int pixel_count, FX_LPCBYTE clip_scan,
2516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                  FX_LPBYTE dest_alpha_scan)
2517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
2519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha;
2520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
2521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
2522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * src_scan[col] / 255;
2524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE back_alpha = *dest_alpha_scan;
2526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (back_alpha == 0) {
2527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan ++ = src_gray;
2528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_alpha_scan ++ = src_alpha;
2529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
2532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_alpha_scan ++;
2534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *dest_alpha_scan++ = dest_alpha;
2538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int alpha_ratio = src_alpha * 255 / dest_alpha;
2539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, alpha_ratio);
2540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan ++;
2541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_BitMask2Argb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
2544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                int src_left, int pixel_count, int blend_type, FX_LPCBYTE clip_scan)
2545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
2547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_ARGB argb = FXARGB_MAKE(0xff, src_r, src_g, src_b);
2548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < pixel_count; col ++) {
2549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
2550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FXARGB_SETDIB(dest_scan, argb);
2551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
2552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
2553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
2555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
2557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
2558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
2559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha;
2562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
2563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * clip_scan[col] / 255;
2564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha;
2566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE back_alpha = dest_scan[3];
2568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (back_alpha == 0) {
2569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
2570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
2571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[3] = dest_alpha;
2575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int alpha_ratio = src_alpha * 255 / dest_alpha;
2576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
2577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended_colors[3];
2578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_scan[3];
2579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[0] = src_b;
2580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[1] = src_g;
2581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[2] = src_r;
2582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
2583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
2584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
2586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
2588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (blend_type) {
2589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended = _BLEND(blend_type, *dest_scan, src_b);
2590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
2591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = _BLEND(blend_type, *dest_scan, src_g);
2594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
2595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = _BLEND(blend_type, *dest_scan, src_r);
2598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
2599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += 2;
2608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_BitMask2Rgba(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
2611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                int src_left, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
2612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                FX_LPBYTE dest_alpha_scan)
2613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
2615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < pixel_count; col ++) {
2616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
2617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[0] = src_b;
2618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[1] = src_g;
2619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[2] = src_r;
2620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_alpha_scan = mask_alpha;
2621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
2622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 3;
2623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_alpha_scan ++;
2624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
2626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
2628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
2629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 3;
2630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_alpha_scan ++;
2631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha;
2634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
2635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * clip_scan[col] / 255;
2636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha;
2638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE back_alpha = dest_scan[3];
2640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (back_alpha == 0) {
2641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan ++ = src_b;
2642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan ++ = src_g;
2643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan ++ = src_r;
2644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_alpha_scan ++ = mask_alpha;
2645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *dest_alpha_scan ++ = dest_alpha;
2649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int alpha_ratio = src_alpha * 255 / dest_alpha;
2650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
2651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended_colors[3];
2652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_scan[3];
2653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[0] = src_b;
2654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[1] = src_g;
2655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[2] = src_r;
2656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
2657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
2658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
2660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
2662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (blend_type) {
2664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended = _BLEND(blend_type, *dest_scan, src_b);
2665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
2666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = _BLEND(blend_type, *dest_scan, src_g);
2669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
2670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = _BLEND(blend_type, *dest_scan, src_r);
2673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
2674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_BitMask2Rgb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
2687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               int src_left, int pixel_count, int blend_type, int Bpp, FX_LPCBYTE clip_scan)
2688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
2690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < pixel_count; col ++) {
2691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
2692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[2] = src_r;
2693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[1] = src_g;
2694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[0] = src_b;
2695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
2696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += Bpp;
2697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
2699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
2701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
2702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += Bpp;
2703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha;
2706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
2707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * clip_scan[col] / 255;
2708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha;
2710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
2712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += Bpp;
2713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
2716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended_colors[3];
2717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_scan[3];
2718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[0] = src_b;
2719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[1] = src_g;
2720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[2] = src_r;
2721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
2722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], src_alpha);
2723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], src_alpha);
2725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], src_alpha);
2727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (blend_type) {
2728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended = _BLEND(blend_type, *dest_scan, src_b);
2729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
2730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan++;
2731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = _BLEND(blend_type, *dest_scan, src_g);
2732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
2733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan++;
2734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = _BLEND(blend_type, *dest_scan, src_r);
2735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
2736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha);
2738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha);
2740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha);
2742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += Bpp - 2;
2744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_BitMask2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_left,
2747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                int pixel_count, FX_LPCBYTE clip_scan)
2748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
2750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
2751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha;
2755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
2756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * clip_scan[col] / 255;
2757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha;
2759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE back_alpha = *dest_scan;
2761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!back_alpha) {
2762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = src_alpha;
2763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (src_alpha) {
2764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan ++;
2767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_BitMask2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_gray,
2770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                int src_left, int pixel_count, FX_LPCBYTE clip_scan)
2771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
2773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
2774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha;
2778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
2779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * clip_scan[col] / 255;
2780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha;
2782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha) {
2784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, src_alpha);
2785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan ++;
2787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_BitMask2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_gray,
2790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                 int src_left, int pixel_count, FX_LPCBYTE clip_scan,
2791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                 FX_LPBYTE dest_alpha_scan)
2792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
2794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
2795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_alpha_scan ++;
2797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha;
2800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
2801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * clip_scan[col] / 255;
2802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha;
2804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE back_alpha = *dest_alpha_scan;
2806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (back_alpha == 0) {
2807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan ++ = src_gray;
2808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_alpha_scan ++ = src_alpha;
2809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
2812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
2813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_alpha_scan ++;
2814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *dest_alpha_scan++ = dest_alpha;
2818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int alpha_ratio = src_alpha * 255 / dest_alpha;
2819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, alpha_ratio);
2820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan ++;
2821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_Argb2Argb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, int blend_type, FX_LPCBYTE clip_scan)
2824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int blended_colors[3];
2826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
2827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
2828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE back_alpha = dest_scan[3];
2829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (back_alpha == 0) {
2830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (clip_scan) {
2831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int src_alpha = clip_scan[col] * src_scan[3] / 255;
2832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[3] = src_alpha;
2833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[0] = src_scan[2];
2834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[1] = src_scan[1];
2835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[2] = src_scan[0];
2836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
2837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FXARGB_RGBORDERCOPY(dest_scan, src_scan);
2838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
2839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
2840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += 4;
2841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE src_alpha;
2844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan == NULL) {
2845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = src_scan[3];
2846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = clip_scan[col] * src_scan[3] / 255;
2848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
2850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
2851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += 4;
2852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[3] = dest_alpha;
2856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int alpha_ratio = src_alpha * 255 / dest_alpha;
2857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (bNonseparableBlend) {
2858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE dest_scan_o[3];
2859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[0] = dest_scan[2];
2860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[1] = dest_scan[1];
2861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[2] = dest_scan[0];
2862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
2863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int color = 0; color < 3; color ++) {
2865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int index = 2 - color;
2866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (blend_type) {
2867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int blended = bNonseparableBlend ? blended_colors[color] :
2868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              _BLEND(blend_type, dest_scan[index], *src_scan);
2869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
2870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], blended, alpha_ratio);
2871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
2872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], *src_scan, alpha_ratio);
2873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
2874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
2875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += 4;
2877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src_scan++;
2878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp)
2881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int blended_colors[3];
2883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
2884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int src_gap = src_Bpp - 3;
2885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < width; col ++) {
2886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE back_alpha = dest_scan[3];
2887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (back_alpha == 0) {
2888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_Bpp == 4) {
2889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FXARGB_SETRGBORDERDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
2890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
2891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
2892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
2893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
2894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += src_Bpp;
2895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[3] = 0xff;
2898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (bNonseparableBlend)	{
2899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE dest_scan_o[3];
2900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[0] = dest_scan[2];
2901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[1] = dest_scan[1];
2902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[2] = dest_scan[0];
2903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
2904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int color = 0; color < 3; color ++) {
2906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int index = 2 - color;
2907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_color = FX_GAMMA(*src_scan);
2908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended = bNonseparableBlend ? blended_colors[color] :
2909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                          _BLEND(blend_type, dest_scan[index], src_color);
2910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[index] = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
2911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
2912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += 4;
2914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src_scan += src_gap;
2915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Argb2Rgb_Blend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, FX_LPCBYTE clip_scan)
2918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int blended_colors[3];
2920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
2921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < width; col ++) {
2922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE src_alpha;
2923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
2924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = src_scan[3] * (*clip_scan++) / 255;
2925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = src_scan[3];
2927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
2929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += dest_Bpp;
2930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += 4;
2931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
2932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (bNonseparableBlend) {
2934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE dest_scan_o[3];
2935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[0] = dest_scan[2];
2936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[1] = dest_scan[1];
2937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[2] = dest_scan[0];
2938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
2939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int color = 0; color < 3; color ++) {
2941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int index = 2 - color;
2942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int back_color = FX_GAMMA(dest_scan[index]);
2943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended = bNonseparableBlend ? blended_colors[color] :
2944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                          _BLEND(blend_type, back_color, *src_scan);
2945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[index] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
2946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
2947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += dest_Bpp;
2949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src_scan ++;
2950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp)
2953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int src_gap = src_Bpp - 3;
2955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < width; col ++) {
2956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_Bpp == 4) {
2957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FXARGB_SETRGBORDERDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
2958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
2960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += 4;
2962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src_scan += src_Bpp;
2963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp)
2966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int blended_colors[3];
2968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
2969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int src_gap = src_Bpp - 3;
2970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < width; col ++) {
2971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (bNonseparableBlend) {
2972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE dest_scan_o[3];
2973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[0] = dest_scan[2];
2974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[1] = dest_scan[1];
2975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[2] = dest_scan[0];
2976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
2977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int color = 0; color < 3; color ++) {
2979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int index = 2 - color;
2980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int back_color = FX_GAMMA(dest_scan[index]);
2981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_color = FX_GAMMA(*src_scan);
2982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended = bNonseparableBlend ? blended_colors[color] :
2983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                          _BLEND(blend_type, back_color, src_color);
2984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[index] = FX_GAMMA_INVERSE(blended);
2985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
2986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += dest_Bpp;
2988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src_scan += src_gap;
2989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, FX_LPCBYTE clip_scan)
2992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < width; col ++) {
2994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE src_alpha;
2995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
2996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = src_scan[3] * (*clip_scan++) / 255;
2997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
2998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = src_scan[3];
2999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 255) {
3001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = FX_GAMMA_INVERSE(*src_scan++);
3002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = FX_GAMMA_INVERSE(*src_scan++);
3003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = FX_GAMMA_INVERSE(*src_scan++);
3004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += dest_Bpp;
3005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
3006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
3007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
3009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += dest_Bpp;
3010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += 4;
3011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
3012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int color = 0; color < 3; color ++) {
3014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int index = 2 - color;
3015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[index] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[index]), *src_scan, src_alpha));
3016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
3017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += dest_Bpp;
3019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src_scan ++;
3020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
3022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp)
3023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
3024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < width; col ++) {
3025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[2] = src_scan[0];
3026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[1] = src_scan[1];
3027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[0] = src_scan[2];
3028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += dest_Bpp;
3029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src_scan += src_Bpp;
3030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
3032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp, FX_LPCBYTE clip_scan)
3033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
3034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int blended_colors[3];
3035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
3036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int src_gap = src_Bpp - 3;
3037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < width; col ++) {
3038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha = *clip_scan ++;
3039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE back_alpha = dest_scan[3];
3040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (back_alpha == 0) {
3041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = FX_GAMMA(*src_scan++);
3042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = FX_GAMMA(*src_scan++);
3043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = FX_GAMMA(*src_scan++);
3044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += src_gap;
3045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
3046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
3047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
3049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
3050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += src_Bpp;
3051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
3052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
3054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[3] = dest_alpha;
3055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int alpha_ratio = src_alpha * 255 / dest_alpha;
3056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (bNonseparableBlend) {
3057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE dest_scan_o[3];
3058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[0] = dest_scan[2];
3059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[1] = dest_scan[1];
3060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[2] = dest_scan[0];
3061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
3062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int color = 0; color < 3; color ++) {
3064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int index = 2 - color;
3065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_color = FX_GAMMA(*src_scan);
3066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended = bNonseparableBlend ? blended_colors[color] :
3067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                          _BLEND(blend_type, dest_scan[index], src_color);
3068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
3069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], blended, alpha_ratio);
3070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
3071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += 4;
3073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src_scan += src_gap;
3074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
3076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan)
3077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
3078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int blended_colors[3];
3079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
3080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int src_gap = src_Bpp - 3;
3081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < width; col ++) {
3082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE src_alpha = *clip_scan ++;
3083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
3084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += dest_Bpp;
3085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += src_Bpp;
3086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
3087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (bNonseparableBlend) {
3089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE dest_scan_o[3];
3090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[0] = dest_scan[2];
3091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[1] = dest_scan[1];
3092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[2] = dest_scan[0];
3093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
3094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int color = 0; color < 3; color ++) {
3096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int index = 2 - color;
3097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int src_color = FX_GAMMA(*src_scan);
3098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int back_color = FX_GAMMA(dest_scan[index]);
3099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended = bNonseparableBlend ? blended_colors[color] :
3100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                          _BLEND(blend_type, back_color, src_color);
3101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[index] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
3102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
3103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += dest_Bpp;
3105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src_scan += src_gap;
3106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
3108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp, FX_LPCBYTE clip_scan)
3109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
3110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int src_gap = src_Bpp - 3;
3111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < width; col ++) {
3112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha = clip_scan[col];
3113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 255) {
3114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = FX_GAMMA(*src_scan++);
3115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = FX_GAMMA(*src_scan++);
3116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = FX_GAMMA(*src_scan++);
3117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[3] = 255;
3118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
3119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan  += src_gap;
3120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
3121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
3123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
3124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += src_Bpp;
3125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
3126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int back_alpha = dest_scan[3];
3128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
3129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[3] = dest_alpha;
3130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int alpha_ratio = src_alpha * 255 / dest_alpha;
3131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int color = 0; color < 3; color ++) {
3132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int index = 2 - color;
3133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], FX_GAMMA(*src_scan), alpha_ratio);
3134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
3135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += 4;
3137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src_scan += src_gap;
3138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
3140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan)
3141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
3142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < width; col ++) {
3143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha = clip_scan[col];
3144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 255) {
3145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = src_scan[0];
3146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = src_scan[1];
3147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = src_scan[2];
3148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (src_alpha) {
3149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), FX_GAMMA(*src_scan), src_alpha));
3150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
3151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), FX_GAMMA(*src_scan), src_alpha));
3152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
3153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), FX_GAMMA(*src_scan), src_alpha));
3154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += dest_Bpp;
3155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan += src_Bpp - 2;
3156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
3157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += dest_Bpp;
3159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src_scan += src_Bpp;
3160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
3162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, FX_ARGB* pPalette, int pixel_count,
3163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int DestBpp, FX_LPCBYTE clip_scan)
3164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
3165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
3166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_ARGB argb = pPalette ? pPalette[*src_scan] : (*src_scan) * 0x010101;
3167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_r = FXARGB_R(argb);
3168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_g = FXARGB_G(argb);
3169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_b = FXARGB_B(argb);
3170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan && clip_scan[col] < 255) {
3171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, clip_scan[col]);
3172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, clip_scan[col]);
3173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, clip_scan[col]);
3174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
3175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = src_b;
3176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = src_g;
3177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = src_r;
3178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += DestBpp;
3180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src_scan ++;
3181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
3183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left,
3184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_ARGB* pPalette, int pixel_count, int DestBpp, FX_LPCBYTE clip_scan)
3185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
3186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int reset_r, reset_g, reset_b;
3187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int set_r, set_g, set_b;
3188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pPalette) {
3189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        reset_r = FXARGB_R(pPalette[0]);
3190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        reset_g = FXARGB_G(pPalette[0]);
3191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        reset_b = FXARGB_B(pPalette[0]);
3192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        set_r = FXARGB_R(pPalette[1]);
3193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        set_g = FXARGB_G(pPalette[1]);
3194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        set_b = FXARGB_B(pPalette[1]);
3195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
3196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        reset_r = reset_g = reset_b = 0;
3197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        set_r = set_g = set_b = 255;
3198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
3200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_r, src_g, src_b;
3201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
3202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_r = set_r;
3203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_g = set_g;
3204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_b = set_b;
3205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
3206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_r = reset_r;
3207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_g = reset_g;
3208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_b = reset_b;
3209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan && clip_scan[col] < 255) {
3211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, clip_scan[col]);
3212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, clip_scan[col]);
3213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, clip_scan[col]);
3214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
3215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = src_b;
3216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = src_g;
3217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = src_r;
3218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += DestBpp;
3220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
3222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width,
3223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_ARGB* pPalette, FX_LPCBYTE clip_scan)
3224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
3225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < width; col ++) {
3226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_r, src_g, src_b;
3227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pPalette) {
3228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_ARGB argb = pPalette[*src_scan];
3229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_r = FXARGB_R(argb);
3230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_g = FXARGB_G(argb);
3231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_b = FXARGB_B(argb);
3232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
3233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_r = src_g = src_b = *src_scan;
3234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan == NULL || clip_scan[col] == 255) {
3236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = FX_GAMMA(src_b);
3237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = FX_GAMMA(src_g);
3238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = FX_GAMMA(src_r);
3239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[3] = 255;
3240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
3241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
3242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
3243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha = clip_scan[col];
3245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
3246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
3247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan ++;
3248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
3249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int back_alpha = dest_scan[3];
3251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
3252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[3] = dest_alpha;
3253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int alpha_ratio = src_alpha * 255 / dest_alpha;
3254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], FX_GAMMA(src_b), alpha_ratio);
3255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], FX_GAMMA(src_g), alpha_ratio);
3256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], FX_GAMMA(src_r), alpha_ratio);
3257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += 4;
3258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src_scan ++;
3259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
3261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width,
3262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_ARGB* pPalette, FX_LPCBYTE clip_scan)
3263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
3264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int reset_r, reset_g, reset_b;
3265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int set_r, set_g, set_b;
3266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pPalette) {
3267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        reset_r = FXARGB_R(pPalette[0]);
3268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        reset_g = FXARGB_G(pPalette[0]);
3269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        reset_b = FXARGB_B(pPalette[0]);
3270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        set_r = FXARGB_R(pPalette[1]);
3271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        set_g = FXARGB_G(pPalette[1]);
3272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        set_b = FXARGB_B(pPalette[1]);
3273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
3274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        reset_r = reset_g = reset_b = 0;
3275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        set_r = set_g = set_b = 255;
3276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < width; col ++) {
3278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_r, src_g, src_b;
3279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
3280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_r = set_r;
3281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_g = set_g;
3282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_b = set_b;
3283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
3284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_r = reset_r;
3285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_g = reset_g;
3286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_b = reset_b;
3287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan == NULL || clip_scan[col] == 255) {
3289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = FX_GAMMA(src_b);
3290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = FX_GAMMA(src_g);
3291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = FX_GAMMA(src_r);
3292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[3] = 255;
3293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
3294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
3295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha = clip_scan[col];
3297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
3298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
3299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
3300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int back_alpha = dest_scan[3];
3302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
3303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[3] = dest_alpha;
3304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int alpha_ratio = src_alpha * 255 / dest_alpha;
3305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], FX_GAMMA(src_b), alpha_ratio);
3306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], FX_GAMMA(src_g), alpha_ratio);
3307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], FX_GAMMA(src_r), alpha_ratio);
3308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += 4;
3309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
3311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_ByteMask2Argb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
3312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int blend_type, FX_LPCBYTE clip_scan)
3313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
3314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
3315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha;
3316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
3317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
3318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
3319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * src_scan[col] / 255;
3320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE back_alpha = dest_scan[3];
3322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (back_alpha == 0) {
3323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
3324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
3325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
3326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
3328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
3329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
3330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
3332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[3] = dest_alpha;
3333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int alpha_ratio = src_alpha * 255 / dest_alpha;
3334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
3335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended_colors[3];
3336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_scan[3];
3337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE dest_scan_o[3];
3338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[0] = src_b;
3339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[1] = src_g;
3340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[2] = src_r;
3341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[0] = dest_scan[2];
3342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[1] = dest_scan[1];
3343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[2] = dest_scan[0];
3344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
3345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], alpha_ratio);
3346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], alpha_ratio);
3347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], alpha_ratio);
3348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (blend_type) {
3349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended = _BLEND(blend_type, dest_scan[2], src_b);
3350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
3351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, alpha_ratio);
3352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = _BLEND(blend_type, dest_scan[1], src_g);
3353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
3354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, alpha_ratio);
3355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = _BLEND(blend_type, dest_scan[0], src_r);
3356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
3357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, alpha_ratio);
3358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
3359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, alpha_ratio);
3360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, alpha_ratio);
3361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, alpha_ratio);
3362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += 4;
3364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
3366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_ByteMask2Rgb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
3367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int blend_type, int Bpp, FX_LPCBYTE clip_scan)
3368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
3369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
3370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha;
3371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
3372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
3373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
3374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * src_scan[col] / 255;
3375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
3377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += Bpp;
3378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
3379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
3381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended_colors[3];
3382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_scan[3];
3383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE dest_scan_o[3];
3384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[0] = src_b;
3385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[1] = src_g;
3386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[2] = src_r;
3387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[0] = dest_scan[2];
3388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[1] = dest_scan[1];
3389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[2] = dest_scan[0];
3390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
3391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], src_alpha);
3392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], src_alpha);
3393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], src_alpha);
3394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (blend_type) {
3395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended = _BLEND(blend_type, dest_scan[2], src_b);
3396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, src_alpha);
3397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = _BLEND(blend_type, dest_scan[1], src_g);
3398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, src_alpha);
3399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = _BLEND(blend_type, dest_scan[0], src_r);
3400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, src_alpha);
3401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
3402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, src_alpha);
3403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, src_alpha);
3404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, src_alpha);
3405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += Bpp;
3407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
3409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_BitMask2Argb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
3410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_left, int pixel_count, int blend_type, FX_LPCBYTE clip_scan)
3411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
3412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
3413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_ARGB argb = FXARGB_MAKE(0xff, src_r, src_g, src_b);
3414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < pixel_count; col ++) {
3415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
3416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FXARGB_SETRGBORDERDIB(dest_scan, argb);
3417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
3418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
3419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
3421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
3423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
3424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
3425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
3426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha;
3428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
3429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * clip_scan[col] / 255;
3430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
3431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha;
3432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE back_alpha = dest_scan[3];
3434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (back_alpha == 0) {
3435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
3436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += 4;
3437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
3438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
3440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan[3] = dest_alpha;
3441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int alpha_ratio = src_alpha * 255 / dest_alpha;
3442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
3443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended_colors[3];
3444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_scan[3];
3445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE dest_scan_o[3];
3446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[0] = src_b;
3447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[1] = src_g;
3448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[2] = src_r;
3449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[0] = dest_scan[2];
3450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[1] = dest_scan[1];
3451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[2] = dest_scan[0];
3452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
3453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], alpha_ratio);
3454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], alpha_ratio);
3455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], alpha_ratio);
3456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (blend_type) {
3457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended = _BLEND(blend_type, dest_scan[2], src_b);
3458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
3459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, alpha_ratio);
3460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = _BLEND(blend_type, dest_scan[1], src_g);
3461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
3462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, alpha_ratio);
3463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = _BLEND(blend_type, dest_scan[0], src_r);
3464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
3465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, alpha_ratio);
3466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
3467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, alpha_ratio);
3468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, alpha_ratio);
3469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, alpha_ratio);
3470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += 4;
3472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
3474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CompositeRow_BitMask2Rgb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
3475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_left, int pixel_count, int blend_type, int Bpp, FX_LPCBYTE clip_scan)
3476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
3477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
3478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < pixel_count; col ++) {
3479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
3480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[2] = src_b;
3481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[1] = src_g;
3482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[0] = src_r;
3483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
3484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += Bpp;
3485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
3487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int col = 0; col < pixel_count; col ++) {
3489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
3490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += Bpp;
3491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
3492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int src_alpha;
3494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
3495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha * clip_scan[col] / 255;
3496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
3497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_alpha = mask_alpha;
3498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_alpha == 0) {
3500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += Bpp;
3501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
3502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
3504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended_colors[3];
3505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE src_scan[3];
3506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE dest_scan_o[3];
3507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[0] = src_b;
3508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[1] = src_g;
3509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan[2] = src_r;
3510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[0] = dest_scan[2];
3511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[1] = dest_scan[1];
3512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan_o[2] = dest_scan[0];
3513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
3514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], src_alpha);
3515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], src_alpha);
3516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], src_alpha);
3517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (blend_type) {
3518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int back_color = FX_GAMMA(dest_scan[2]);
3519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int blended = _BLEND(blend_type, back_color, src_b);
3520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
3521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            back_color = FX_GAMMA(dest_scan[1]);
3522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = _BLEND(blend_type, back_color, src_g);
3523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
3524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            back_color = FX_GAMMA(dest_scan[0]);
3525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            blended = _BLEND(blend_type, back_color, src_r);
3526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
3527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
3528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), src_b, src_alpha));
3529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), src_g, src_alpha));
3530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), src_r, src_alpha));
3531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += Bpp;
3533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
3535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline FX_BOOL _ScanlineCompositor_InitSourceMask(FXDIB_Format dest_format, int alpha_flag, FX_DWORD mask_color, int& mask_alpha,
3536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int& mask_red, int& mask_green, int& mask_blue, int& mask_black,
3537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        void* icc_module, void* pIccTransform)
3538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
3539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ICodec_IccModule* pIccModule = (ICodec_IccModule*)icc_module;
3540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (alpha_flag >> 8) {
3541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        mask_alpha = alpha_flag & 0xff;
3542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        mask_red = FXSYS_GetCValue(mask_color);
3543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        mask_green = FXSYS_GetMValue(mask_color);
3544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        mask_blue = FXSYS_GetYValue(mask_color);
3545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        mask_black = FXSYS_GetKValue(mask_color);
3546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
3547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        mask_alpha = FXARGB_A(mask_color);
3548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        mask_red = FXARGB_R(mask_color);
3549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        mask_green = FXARGB_G(mask_color);
3550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        mask_blue = FXARGB_B(mask_color);
3551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (dest_format == FXDIB_8bppMask) {
3553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
3554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ((dest_format & 0xff) == 8) {
3556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pIccTransform) {
3557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            mask_color = (alpha_flag >> 8) ? FXCMYK_TODIB(mask_color) : FXARGB_TODIB(mask_color);
3558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE gray_p = (FX_LPBYTE)&mask_color;
3559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pIccModule->TranslateScanline(pIccTransform, gray_p, gray_p, 1);
3560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            mask_red = dest_format & 0x0400 ? FX_CCOLOR(gray_p[0]) : gray_p[0];
3561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
3562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (alpha_flag >> 8) {
3563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE r, g, b;
3564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                AdobeCMYK_to_sRGB1(mask_red, mask_green, mask_blue, mask_black,
3565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   r, g, b);
3566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                mask_red = FXRGB2GRAY(r, g, b);
3567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
3568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                mask_red = FXRGB2GRAY(mask_red, mask_green, mask_blue);
3569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
3570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (dest_format & 0x0400) {
3571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                mask_red = FX_CCOLOR(mask_red);
3572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
3573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
3575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE mask_color_p = (FX_LPBYTE)&mask_color;
3576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        mask_color = (alpha_flag >> 8) ? FXCMYK_TODIB(mask_color) : FXARGB_TODIB(mask_color);
3577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pIccTransform) {
3578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pIccModule->TranslateScanline(pIccTransform, mask_color_p, mask_color_p, 1);
3579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            mask_red = mask_color_p[2];
3580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            mask_green = mask_color_p[1];
3581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            mask_blue = mask_color_p[0];
3582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (alpha_flag >> 8) {
3583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            AdobeCMYK_to_sRGB1(mask_color_p[0], mask_color_p[1], mask_color_p[2], mask_color_p[3],
3584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               mask_color_p[2], mask_color_p[1], mask_color_p[0]);
3585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            mask_red = mask_color_p[2];
3586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            mask_green = mask_color_p[1];
3587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            mask_blue = mask_color_p[0];
3588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
3591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
3592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _ScanlineCompositor_InitSourcePalette(FXDIB_Format src_format, FXDIB_Format dest_format,
3593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_DWORD*& pDestPalette, FX_DWORD* pSrcPalette,
3594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        void* icc_module, void* pIccTransform)
3595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
3596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ICodec_IccModule* pIccModule = (ICodec_IccModule*)icc_module;
3597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL isSrcCmyk = src_format & 0x0400 ? TRUE : FALSE;
3598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL isDstCmyk = dest_format & 0x0400 ? TRUE : FALSE;
3599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pDestPalette = NULL;
3600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pIccTransform) {
3601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pSrcPalette) {
3602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if ((dest_format & 0xff) == 8) {
3603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int pal_count = 1 << (src_format & 0xff);
3604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count);
3605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!gray_pal) {
3606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return;
3607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
3608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pDestPalette = (FX_DWORD*)gray_pal;
3609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int i = 0; i < pal_count; i ++) {
3610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FX_DWORD color = isSrcCmyk ? FXCMYK_TODIB(pSrcPalette[i]) : FXARGB_TODIB(pSrcPalette[i]);
3611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pIccModule->TranslateScanline(pIccTransform, gray_pal, (FX_LPCBYTE)&color, 1);
3612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    gray_pal ++;
3613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
3614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
3615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int palsize = 1 << (src_format & 0xff);
3616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pDestPalette = FX_Alloc(FX_DWORD, palsize);
3617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!pDestPalette) {
3618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return;
3619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
3620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int i = 0; i < palsize; i ++) {
3621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FX_DWORD color = isSrcCmyk ? FXCMYK_TODIB(pSrcPalette[i]) : FXARGB_TODIB(pSrcPalette[i]);
3622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)&color, (FX_LPCBYTE)&color, 1);
3623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pDestPalette[i] = isDstCmyk ? FXCMYK_TODIB(color) : FXARGB_TODIB(color);
3624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
3625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
3626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
3627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int pal_count = 1 << (src_format & 0xff);
3628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count);
3629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!gray_pal) {
3630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return;
3631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
3632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pal_count == 2) {
3633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                gray_pal[0] = 0;
3634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                gray_pal[1] = 255;
3635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
3636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int i = 0; i < pal_count; i++) {
3637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    gray_pal[i] = i;
3638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
3639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
3640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if ((dest_format & 0xff) == 8) {
3641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pIccModule->TranslateScanline(pIccTransform, gray_pal, gray_pal, pal_count);
3642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pDestPalette = (FX_DWORD*)gray_pal;
3643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
3644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pDestPalette = FX_Alloc(FX_DWORD, pal_count);
3645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!pDestPalette) {
3646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FX_Free(gray_pal);
3647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return;
3648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
3649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int i = 0; i < pal_count; i ++) {
3650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)&pDestPalette[i], &gray_pal[i], 1);
3651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pDestPalette[i] = isDstCmyk ? FXCMYK_TODIB(pDestPalette[i]) : FXARGB_TODIB(pDestPalette[i]);
3652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
3653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_Free(gray_pal);
3654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
3655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
3657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pSrcPalette) {
3658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if ((dest_format & 0xff) == 8) {
3659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int pal_count = 1 << (src_format & 0xff);
3660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count);
3661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!gray_pal) {
3662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return;
3663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
3664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pDestPalette = (FX_DWORD*)gray_pal;
3665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (isSrcCmyk) {
3666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    for (int i = 0; i < pal_count; i ++) {
3667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        FX_CMYK cmyk = pSrcPalette[i];
3668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        FX_BYTE r, g, b;
3669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk),
3670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                           r, g, b);
3671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *gray_pal ++ = FXRGB2GRAY(r, g, b);
3672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
3673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else
3674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    for (int i = 0; i < pal_count; i ++) {
3675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        FX_ARGB argb = pSrcPalette[i];
3676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *gray_pal ++ = FXRGB2GRAY(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb));
3677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
3678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
3679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int palsize = 1 << (src_format & 0xff);
3680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pDestPalette = FX_Alloc(FX_DWORD, palsize);
3681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!pDestPalette) {
3682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return;
3683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
3684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (isDstCmyk == isSrcCmyk) {
3685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FXSYS_memcpy32(pDestPalette, pSrcPalette, palsize * sizeof(FX_DWORD));
3686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
3687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    for (int i = 0; i < palsize; i ++) {
3688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        FX_CMYK cmyk = pSrcPalette[i];
3689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        FX_BYTE r, g, b;
3690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk),
3691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                           r, g, b);
3692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        pDestPalette[i] = FXARGB_MAKE(0xff, r, g, b);
3693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
3694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
3695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
3696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
3697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if ((dest_format & 0xff) == 8) {
3698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int pal_count = 1 << (src_format & 0xff);
3699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count);
3700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!gray_pal) {
3701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return;
3702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
3703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (pal_count == 2) {
3704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    gray_pal[0] = 0;
3705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    gray_pal[1] = 255;
3706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
3707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    for (int i = 0; i < pal_count; i++) {
3708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        gray_pal[i] = i;
3709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
3710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
3711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pDestPalette = (FX_DWORD*)gray_pal;
3712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
3713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int palsize = 1 << (src_format & 0xff);
3714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pDestPalette = FX_Alloc(FX_DWORD, palsize);
3715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!pDestPalette) {
3716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return;
3717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
3718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (palsize == 2) {
3719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pDestPalette[0] = isSrcCmyk ? 255 : 0xff000000;
3720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pDestPalette[1] = isSrcCmyk ? 0 : 0xffffffff;
3721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
3722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    for (int i = 0; i < palsize; i++) {
3723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        pDestPalette[i] = isSrcCmyk ? FX_CCOLOR(i) : (i * 0x10101);
3724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
3725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
3726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (isSrcCmyk != isDstCmyk) {
3727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    for (int i = 0; i < palsize; i ++) {
3728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        FX_CMYK cmyk = pDestPalette[i];
3729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        FX_BYTE r, g, b;
3730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk),
3731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                           r, g, b);
3732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        pDestPalette[i] = FXARGB_MAKE(0xff, r, g, b);
3733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
3734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
3735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
3736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
3739ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ScanlineCompositor::CFX_ScanlineCompositor()
3740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
3741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pSrcPalette = NULL;
3742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCacheScanline = NULL;
3743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_CacheSize = 0;
3744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bRgbByteOrder = FALSE;
3745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_BlendType = FXDIB_BLEND_NORMAL;
3746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
3747ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ScanlineCompositor::~CFX_ScanlineCompositor()
3748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
3749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pSrcPalette) {
3750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_pSrcPalette);
3751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCacheScanline) {
3753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_pCacheScanline);
3754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
3756ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_ScanlineCompositor::Init(FXDIB_Format dest_format, FXDIB_Format src_format, FX_INT32 width, FX_DWORD* pSrcPalette,
3757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                     FX_DWORD mask_color, int blend_type, FX_BOOL bClip, FX_BOOL bRgbByteOrder, int alpha_flag, void* pIccTransform)
3758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
3759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_SrcFormat = src_format;
3760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DestFormat = dest_format;
3761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_BlendType = blend_type;
3762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bRgbByteOrder = bRgbByteOrder;
3763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ICodec_IccModule* pIccModule = NULL;
3764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (CFX_GEModule::Get()->GetCodecModule()) {
3765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
3766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pIccModule == NULL) {
3768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccTransform = NULL;
3769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pIccTransform = pIccTransform;
3771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ((dest_format & 0xff) == 1) {
3772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
3773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_SrcFormat == FXDIB_1bppMask || m_SrcFormat == FXDIB_8bppMask) {
3775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return _ScanlineCompositor_InitSourceMask(dest_format, alpha_flag, mask_color,
3776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, m_MaskBlack,
3777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pIccModule, pIccTransform);
3778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pIccTransform == NULL && (~src_format & 0x0400) && (dest_format & 0x0400)) {
3780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
3781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ((m_SrcFormat & 0xff) <= 8) {
3783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (dest_format == FXDIB_8bppMask) {
3784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return TRUE;
3785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _ScanlineCompositor_InitSourcePalette(src_format, dest_format, m_pSrcPalette, pSrcPalette,
3787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                              pIccModule, pIccTransform);
3788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Transparency = (dest_format == FXDIB_Argb ? 1 : 0)
3789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                         + (dest_format & 0x0200 ? 2 : 0)
3790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                         + (dest_format & 0x0400 ? 4 : 0)
3791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                         + ((src_format & 0xff) == 1 ? 8 : 0);
3792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
3793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Transparency = (src_format & 0x0200 ? 0 : 1)
3795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                     + (dest_format & 0x0200 ? 0 : 2)
3796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                     + (blend_type == FXDIB_BLEND_NORMAL ? 4 : 0)
3797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                     + (bClip ? 8 : 0)
3798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                     + (src_format & 0x0400 ? 16 : 0)
3799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                     + (dest_format & 0x0400 ? 32 : 0)
3800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                     + (pIccTransform ? 64 : 0);
3801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
3802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
3803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_ScanlineCompositor::CompositeRgbBitmapLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, FX_LPCBYTE clip_scan,
3804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE src_extra_alpha, FX_LPBYTE dst_extra_alpha)
3805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
3806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int src_Bpp = (m_SrcFormat & 0xff) >> 3;
3807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int dest_Bpp = (m_DestFormat & 0xff) >> 3;
3808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int dest_Size = width * dest_Bpp + 4;
3809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_bRgbByteOrder) {
3810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        switch (m_Transparency) {
3811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 0:
3812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 4:
3813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 8:
3814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 12:
3815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Argb2Argb_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, clip_scan);
3816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 1:
3818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, src_Bpp);
3819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 2:
3821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 10:
3822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Argb2Rgb_Blend_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan);
3823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 3:
3825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp);
3826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 5:
3828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(dest_scan, src_scan, width, src_Bpp);
3829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 6:
3831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 14:
3832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, width, dest_Bpp, clip_scan);
3833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 7:
3835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder(dest_scan, src_scan, width, dest_Bpp, src_Bpp);
3836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 9:
3838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan);
3839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 11:
3841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, clip_scan);
3842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 13:
3844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder(dest_scan, src_scan, width, src_Bpp, clip_scan);
3845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 15:
3847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder(dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan);
3848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
3851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_DestFormat == FXDIB_8bppMask) {
3853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_SrcFormat & 0x0200) {
3854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_SrcFormat == FXDIB_Argb) {
3855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Argb2Mask(dest_scan, src_scan, width, clip_scan);
3856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
3857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgba2Mask(dest_scan, src_extra_alpha, width, clip_scan);
3858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
3859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
3860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _CompositeRow_Rgb2Mask(dest_scan, src_scan, width, clip_scan);
3861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if ((m_DestFormat & 0xff) == 8) {
3863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_DestFormat & 0x0400) {
3864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int i = 0; i < width; i ++) {
3865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = ~*dest_scan;
3866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan++;
3867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
3868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_SrcFormat & 0x0200) {
3870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_DestFormat & 0x0200) {
3871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Argb2Graya(dest_scan, src_scan, width, m_BlendType, clip_scan, src_extra_alpha, dst_extra_alpha, m_pIccTransform);
3872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
3873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Argb2Gray(dest_scan, src_scan, width, m_BlendType, clip_scan, src_extra_alpha, m_pIccTransform);
3874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
3875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
3876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_DestFormat & 0x0200) {
3877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Graya(dest_scan, src_scan, src_Bpp, width, m_BlendType, clip_scan, dst_extra_alpha, m_pIccTransform);
3878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
3879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Gray(dest_scan, src_scan, src_Bpp, width, m_BlendType, clip_scan, m_pIccTransform);
3880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
3881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_DestFormat & 0x0400) {
3883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int i = 0; i < width; i ++) {
3884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = ~*dest_scan;
3885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan++;
3886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
3887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
3889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (dest_Size > m_CacheSize) {
3890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pCacheScanline = FX_Realloc(FX_BYTE, m_pCacheScanline, dest_Size);
3891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!m_pCacheScanline) {
3892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return;
3893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
3894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_CacheSize = dest_Size;
3895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        switch (m_Transparency) {
3897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 0:
3898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 4:
3899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 8:
3900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 4+8: {
3901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    _CompositeRow_Argb2Argb(dest_scan, src_scan, width, m_BlendType, clip_scan,
3902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                            dst_extra_alpha, src_extra_alpha);
3903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
3904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 64:
3906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 4+64:
3907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 8+64:
3908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 4+8+64: {
3909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    _CompositeRow_Argb2Argb_Transform(dest_scan, src_scan, width, m_BlendType, clip_scan,
3910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                      dst_extra_alpha, src_extra_alpha, m_pCacheScanline, m_pIccTransform);
3911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
3912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 1:
3914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Argb_Blend_NoClip(dest_scan, src_scan, width, m_BlendType, src_Bpp,
3915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                    dst_extra_alpha);
3916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 1+64:
3918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Argb_Blend_NoClip_Transform(dest_scan, src_scan, width, m_BlendType, src_Bpp,
3919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        dst_extra_alpha, m_pCacheScanline, m_pIccTransform);
3920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 1+8:
3922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Argb_Blend_Clip(dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan,
3923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                  dst_extra_alpha);
3924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 1+8+64:
3926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Argb_Blend_Clip_Transform(dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan,
3927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        dst_extra_alpha, m_pCacheScanline, m_pIccTransform);
3928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 1+4:
3930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Argb_NoBlend_NoClip(dest_scan, src_scan, width, src_Bpp,
3931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                      dst_extra_alpha);
3932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 1+4+64:
3934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Argb_NoBlend_NoClip_Transform(dest_scan, src_scan, width, src_Bpp,
3935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        dst_extra_alpha, m_pCacheScanline, m_pIccTransform);
3936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 1+4+8:
3938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Argb_NoBlend_Clip(dest_scan, src_scan, width, src_Bpp, clip_scan,
3939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                    dst_extra_alpha);
3940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 1+4+8+64:
3942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Argb_NoBlend_Clip_Transform(dest_scan, src_scan, width, src_Bpp, clip_scan,
3943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        dst_extra_alpha, m_pCacheScanline, m_pIccTransform);
3944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 2:
3946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 2+8:
3947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Argb2Rgb_Blend(dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan,
3948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                             src_extra_alpha);
3949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 2+64:
3951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 2+8+64:
3952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Argb2Rgb_Blend_Transform(dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan,
3953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                       src_extra_alpha, m_pCacheScanline, m_pIccTransform);
3954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 2+4:
3956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 2+4+8:
3957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Argb2Rgb_NoBlend(dest_scan, src_scan, width, dest_Bpp, clip_scan,
3958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                               src_extra_alpha);
3959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 2+4+64:
3961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 2+4+8+64:
3962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Argb2Rgb_NoBlend_Transform(dest_scan, src_scan, width, dest_Bpp, clip_scan,
3963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        src_extra_alpha, m_pCacheScanline, m_pIccTransform);
3964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 1+2:
3966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Rgb_Blend_NoClip(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp);
3967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 1+2+64:
3969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Rgb_Blend_NoClip_Transform(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp,
3970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        m_pCacheScanline, m_pIccTransform);
3971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 1+2+8:
3973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Rgb_Blend_Clip(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, clip_scan);
3974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 1+2+8+64:
3976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Rgb_Blend_Clip_Transform(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, clip_scan,
3977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        m_pCacheScanline, m_pIccTransform);
3978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 1+2+4:
3980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Rgb_NoBlend_NoClip(dest_scan, src_scan, width, dest_Bpp, src_Bpp);
3981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 1+2+4+64:
3983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Rgb_NoBlend_NoClip_Transform(dest_scan, src_scan, width, dest_Bpp, src_Bpp,
3984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        m_pCacheScanline, m_pIccTransform);
3985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 1+2+4+8:
3987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Rgb_NoBlend_Clip(dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan);
3988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 1+2+4+8+64:
3990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_Rgb2Rgb_NoBlend_Clip_Transform(dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan,
3991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        m_pCacheScanline, m_pIccTransform);
3992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
3993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
3994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
3995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
3996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_ScanlineCompositor::CompositePalBitmapLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width, FX_LPCBYTE clip_scan,
3997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE src_extra_alpha, FX_LPBYTE dst_extra_alpha)
3998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
3999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_bRgbByteOrder) {
4000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_SrcFormat == FXDIB_1bppRgb) {
4001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_DestFormat == FXDIB_8bppRgb) {
4002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return;
4003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else if(m_DestFormat == FXDIB_Argb) {
4004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder(dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan);
4005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
4006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, src_left, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan);
4007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
4008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
4009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_DestFormat == FXDIB_8bppRgb) {
4010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return;
4011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else if (m_DestFormat == FXDIB_Argb) {
4012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(dest_scan, src_scan, width, m_pSrcPalette, clip_scan);
4013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
4014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan);
4015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
4016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
4018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_DestFormat == FXDIB_8bppMask) {
4020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _CompositeRow_Rgb2Mask(dest_scan, src_scan, width, clip_scan);
4021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
4022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if ((m_DestFormat & 0xff) == 8) {
4023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_Transparency & 8) {
4024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_DestFormat & 0x0200) {
4025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_1bppPal2Graya(dest_scan, src_scan, src_left, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan, dst_extra_alpha);
4026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
4027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_1bppPal2Gray(dest_scan, src_scan, src_left, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan);
4028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
4029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
4030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_DestFormat & 0x0200)
4031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_8bppPal2Graya(dest_scan, src_scan, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan,
4032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                            dst_extra_alpha, src_extra_alpha);
4033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            else
4034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_8bppPal2Gray(dest_scan, src_scan, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan,
4035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                           src_extra_alpha);
4036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
4038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        switch (m_Transparency) {
4039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 1+2:
4040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_8bppRgb2Argb_NoBlend(dest_scan, src_scan, width, m_pSrcPalette, clip_scan,
4041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                   src_extra_alpha);
4042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
4043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 1+2+8:
4044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_1bppRgb2Argb_NoBlend(dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan);
4045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
4046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 0:
4047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_8bppRgb2Rgb_NoBlend(dest_scan, src_scan, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan,
4048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                  src_extra_alpha);
4049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
4050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 0+8:
4051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_1bppRgb2Rgb_NoBlend(dest_scan, src_scan, src_left, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan);
4052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
4053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 0+2:
4054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_8bppRgb2Rgb_NoBlend(dest_scan, src_scan, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan,
4055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                  src_extra_alpha);
4056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
4057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 0+2+8:
4058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CompositeRow_1bppRgb2Rgba_NoBlend(dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan,
4059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                   dst_extra_alpha);
4060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
4061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
4062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
4065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_ScanlineCompositor::CompositeByteMaskLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, FX_LPCBYTE clip_scan,
4066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dst_extra_alpha)
4067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
4068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_DestFormat == FXDIB_8bppMask) {
4069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _CompositeRow_ByteMask2Mask(dest_scan, src_scan, m_MaskAlpha, width, clip_scan);
4070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if ((m_DestFormat & 0xff) == 8) {
4071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_DestFormat & 0x0200) {
4072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _CompositeRow_ByteMask2Graya(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, width, clip_scan, dst_extra_alpha);
4073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
4074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _CompositeRow_ByteMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, width, clip_scan);
4075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_bRgbByteOrder) {
4077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_DestFormat == FXDIB_Argb)
4078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _CompositeRow_ByteMask2Argb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    width, m_BlendType, clip_scan);
4080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        else
4081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _CompositeRow_ByteMask2Rgb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                    width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
4083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
4084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_DestFormat == FXDIB_Argb)
4085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _CompositeRow_ByteMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    width, m_BlendType, clip_scan);
4087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else if (m_DestFormat == FXDIB_Rgb || m_DestFormat == FXDIB_Rgb32)
4088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _CompositeRow_ByteMask2Rgb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
4090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else if (m_DestFormat == FXDIB_Rgba)
4091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _CompositeRow_ByteMask2Rgba(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    width, m_BlendType, clip_scan, dst_extra_alpha);
4093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
4094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_ScanlineCompositor::CompositeBitMaskLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width, FX_LPCBYTE clip_scan,
4095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dst_extra_alpha)
4096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
4097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_DestFormat == FXDIB_8bppMask) {
4098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _CompositeRow_BitMask2Mask(dest_scan, src_scan, m_MaskAlpha, src_left, width, clip_scan);
4099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if ((m_DestFormat & 0xff) == 8) {
4100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_DestFormat & 0x0200)
4101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _CompositeRow_BitMask2Graya(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, src_left, width, clip_scan,
4102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        dst_extra_alpha);
4103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        else {
4104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _CompositeRow_BitMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, src_left, width, clip_scan);
4105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_bRgbByteOrder) {
4107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_DestFormat == FXDIB_Argb)
4108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _CompositeRow_BitMask2Argb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                    src_left, width, m_BlendType, clip_scan);
4110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        else
4111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _CompositeRow_BitMask2Rgb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                   src_left, width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
4113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
4114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_DestFormat == FXDIB_Argb)
4115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _CompositeRow_BitMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   src_left, width, m_BlendType, clip_scan);
4117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else if (m_DestFormat == FXDIB_Rgb || m_DestFormat == FXDIB_Rgb32)
4118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _CompositeRow_BitMask2Rgb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                  src_left, width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
4120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
4121ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_DIBitmap::CompositeBitmap(int dest_left, int dest_top, int width, int height,
4122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      const CFX_DIBSource* pSrcBitmap, int src_left, int src_top,
4123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      int blend_type, const CFX_ClipRgn* pClipRgn, FX_BOOL bRgbByteOrder, void* pIccTransform)
4124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
4125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pBuffer == NULL) {
4126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
4127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(!pSrcBitmap->IsAlphaMask());
4129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_bpp >= 8);
4130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pSrcBitmap->IsAlphaMask() || m_bpp < 8) {
4131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
4132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    GetOverlapRect(dest_left, dest_top, width, height, pSrcBitmap->GetWidth(), pSrcBitmap->GetHeight(),
4134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                   src_left, src_top, pClipRgn);
4135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (width == 0 || height == 0) {
4136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
4137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const CFX_DIBitmap* pClipMask = NULL;
4139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_RECT clip_box;
4140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) {
4141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ASSERT(pClipRgn->GetType() == CFX_ClipRgn::MaskF);
4142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pClipMask = pClipRgn->GetMask();
4143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        clip_box = pClipRgn->GetBox();
4144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_ScanlineCompositor compositor;
4146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!compositor.Init(GetFormat(), pSrcBitmap->GetFormat(), width, pSrcBitmap->GetPalette(), 0, blend_type,
4147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                         pClipMask != NULL, bRgbByteOrder, 0, pIccTransform)) {
4148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
4149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int dest_Bpp = m_bpp / 8;
4151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int src_Bpp = pSrcBitmap->GetBPP() / 8;
4152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bRgb = FALSE;
4153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bCmyk = FALSE;
4154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_Bpp > 1) {
4155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pSrcBitmap->IsCmykImage()) {
4156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bCmyk = TRUE;
4157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
4158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bRgb = TRUE;
4159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_DIBitmap* pSrcAlphaMask = pSrcBitmap->m_pAlphaMask;
4162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int row = 0; row < height; row ++) {
4163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dest_scan = m_pBuffer + (dest_top + row) * m_Pitch + dest_left * dest_Bpp;
4164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * src_Bpp;
4165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE src_scan_extra_alpha = pSrcAlphaMask ? pSrcAlphaMask->GetScanline(src_top + row) + src_left : NULL;
4166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dst_scan_extra_alpha = m_pAlphaMask ? (FX_LPBYTE)m_pAlphaMask->GetScanline(dest_top + row) + dest_left : NULL;
4167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE clip_scan = NULL;
4168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pClipMask) {
4169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            clip_scan = pClipMask->m_pBuffer + (dest_top + row - clip_box.top) * pClipMask->m_Pitch + (dest_left - clip_box.left);
4170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (bRgb) {
4172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            compositor.CompositeRgbBitmapLine(dest_scan, src_scan, width, clip_scan, src_scan_extra_alpha, dst_scan_extra_alpha);
4173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
4174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            compositor.CompositePalBitmapLine(dest_scan, src_scan, src_left, width, clip_scan, src_scan_extra_alpha, dst_scan_extra_alpha);
4175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
4178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
4179ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_DIBitmap::CompositeMask(int dest_left, int dest_top, int width, int height,
4180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    const CFX_DIBSource* pMask, FX_DWORD color, int src_left, int src_top,
4181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    int blend_type, const CFX_ClipRgn* pClipRgn, FX_BOOL bRgbByteOrder, int alpha_flag, void* pIccTransform)
4182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
4183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pBuffer == NULL) {
4184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
4185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(pMask->IsAlphaMask());
4187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_bpp >= 8);
4188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!pMask->IsAlphaMask() || m_bpp < 8) {
4189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
4190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    GetOverlapRect(dest_left, dest_top, width, height, pMask->GetWidth(), pMask->GetHeight(), src_left, src_top, pClipRgn);
4192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (width == 0 || height == 0) {
4193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
4194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int src_alpha = (FX_BYTE)(alpha_flag >> 8) ? (alpha_flag & 0xff) : FXARGB_A(color);
4196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_alpha == 0) {
4197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
4198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const CFX_DIBitmap* pClipMask = NULL;
4200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_RECT clip_box;
4201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) {
4202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ASSERT(pClipRgn->GetType() == CFX_ClipRgn::MaskF);
4203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pClipMask = pClipRgn->GetMask();
4204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        clip_box = pClipRgn->GetBox();
4205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int src_bpp = pMask->GetBPP();
4207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int Bpp = GetBPP() / 8;
4208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_ScanlineCompositor compositor;
4209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!compositor.Init(GetFormat(), pMask->GetFormat(), width, NULL, color, blend_type, pClipMask != NULL, bRgbByteOrder, alpha_flag, pIccTransform)) {
4210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
4211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int row = 0; row < height; row ++) {
4213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dest_scan = m_pBuffer + (dest_top + row) * m_Pitch + dest_left * Bpp;
4214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE src_scan = pMask->GetScanline(src_top + row);
4215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dst_scan_extra_alpha = m_pAlphaMask ? (FX_LPBYTE)m_pAlphaMask->GetScanline(dest_top + row) + dest_left : NULL;
4216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE clip_scan = NULL;
4217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pClipMask) {
4218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            clip_scan = pClipMask->m_pBuffer + (dest_top + row - clip_box.top) * pClipMask->m_Pitch + (dest_left - clip_box.left);
4219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_bpp == 1) {
4221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            compositor.CompositeBitMaskLine(dest_scan, src_scan, src_left, width, clip_scan, dst_scan_extra_alpha);
4222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
4223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            compositor.CompositeByteMaskLine(dest_scan, src_scan + src_left, width, clip_scan, dst_scan_extra_alpha);
4224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
4227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
4228ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_DIBitmap::CompositeRect(int left, int top, int width, int height, FX_DWORD color, int alpha_flag, void* pIccTransform)
4229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
4230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pBuffer == NULL) {
4231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
4232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int src_alpha = (alpha_flag >> 8) ? (alpha_flag & 0xff) : FXARGB_A(color);
4234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_alpha == 0) {
4235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
4236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_RECT rect(left, top, left + width, top + height);
4238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rect.Intersect(0, 0, m_Width, m_Height);
4239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (rect.IsEmpty()) {
4240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
4241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    width = rect.Width();
4243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD dst_color;
4244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (alpha_flag >> 8) {
4245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dst_color = FXCMYK_TODIB(color);
4246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
4247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dst_color = FXARGB_TODIB(color);
4248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPBYTE color_p = (FX_LPBYTE)&dst_color;
4250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_bpp == 8) {
4251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE gray = 255;
4252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!IsAlphaMask()) {
4253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pIccTransform && CFX_GEModule::Get()->GetCodecModule() && CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
4254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
4255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pIccModule->TranslateScanline(pIccTransform, &gray, color_p, 1);
4256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
4257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (alpha_flag >> 8) {
4258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FX_BYTE r, g, b;
4259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    AdobeCMYK_to_sRGB1(color_p[0], color_p[1], color_p[2], color_p[3],
4260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                       r, g, b);
4261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    gray = FXRGB2GRAY(r, g, b);
4262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
4263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    gray = (FX_BYTE)FXRGB2GRAY((int)color_p[2], color_p[1], color_p[0]);
4264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
4265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
4266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (IsCmykImage()) {
4267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                gray = ~gray;
4268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
4269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int row = rect.top; row < rect.bottom; row ++) {
4271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE dest_scan = m_pBuffer + row * m_Pitch + rect.left;
4272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_alpha == 255) {
4273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FXSYS_memset8(dest_scan, gray, width);
4274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else
4275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int col = 0; col < width; col ++) {
4276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
4277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan ++;
4278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
4279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
4281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_bpp == 1) {
4282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ASSERT(!IsCmykImage() && (FX_BYTE)(alpha_flag >> 8) == 0);
4283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int left_shift = rect.left % 8;
4284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int right_shift = rect.right % 8;
4285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int width = rect.right / 8 - rect.left / 8;
4286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int index = 0;
4287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pPalette == NULL) {
4288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            index = ((FX_BYTE)color == 0xff) ? 1 : 0;
4289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
4290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int i = 0; i < 2; i ++)
4291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (m_pPalette[i] == color) {
4292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    index = i;
4293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
4294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int row = rect.top; row < rect.bottom; row ++) {
4296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE* dest_scan_top = (FX_BYTE*)GetScanline(row) + rect.left / 8;
4297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE* dest_scan_top_r = (FX_BYTE*)GetScanline(row) + rect.right / 8;
4298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE left_flag =  *dest_scan_top & (255 << (8 - left_shift));
4299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE right_flag = *dest_scan_top_r & (255 >> right_shift);
4300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (width) {
4301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FXSYS_memset8(dest_scan_top + 1, index ? 255 : 0, width - 1);
4302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!index) {
4303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan_top &= left_flag;
4304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan_top_r &= right_flag;
4305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
4306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan_top |= ~left_flag;
4307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan_top_r |= ~right_flag;
4308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
4309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
4310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!index) {
4311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan_top &= left_flag | right_flag;
4312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
4313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan_top |= ~(left_flag | right_flag);
4314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
4315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
4316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
4318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_bpp >= 24);
4320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_bpp < 24) {
4321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
4322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pIccTransform && CFX_GEModule::Get()->GetCodecModule()) {
4324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
4325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule->TranslateScanline(pIccTransform, color_p, color_p, 1);
4326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
4327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (alpha_flag >> 8 && !IsCmykImage())
4328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), FXSYS_GetYValue(color), FXSYS_GetKValue(color),
4329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               color_p[2], color_p[1], color_p[0]);
4330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        else if (!(alpha_flag >> 8) && IsCmykImage()) {
4331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
4332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if(!IsCmykImage()) {
4335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        color_p[3] = (FX_BYTE)src_alpha;
4336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int Bpp = m_bpp / 8;
4338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bAlpha = HasAlpha();
4339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bArgb = GetFormat() == FXDIB_Argb ? TRUE : FALSE;
4340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (src_alpha == 255) {
4341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int row = rect.top; row < rect.bottom; row ++) {
4342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE dest_scan = m_pBuffer + row * m_Pitch + rect.left * Bpp;
4343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE dest_scan_alpha = m_pAlphaMask ? (FX_LPBYTE)m_pAlphaMask->GetScanline(row) + rect.left : NULL;
4344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (dest_scan_alpha) {
4345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FXSYS_memset8(dest_scan_alpha, 0xff, width);
4346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
4347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (Bpp == 4) {
4348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_DWORD* scan = (FX_DWORD*)dest_scan;
4349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int col = 0; col < width; col ++) {
4350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *scan ++ = dst_color;
4351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
4352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
4353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int col = 0; col < width; col ++) {
4354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan ++ = color_p[0];
4355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan ++ = color_p[1];
4356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan ++ = color_p[2];
4357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
4358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
4359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
4361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int row = rect.top; row < rect.bottom; row ++) {
4363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dest_scan = m_pBuffer + row * m_Pitch + rect.left * Bpp;
4364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (bAlpha) {
4365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (bArgb) {
4366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int col = 0; col < width; col ++) {
4367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FX_BYTE back_alpha = dest_scan[3];
4368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (back_alpha == 0) {
4369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, color_p[2], color_p[1], color_p[0]));
4370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        dest_scan += 4;
4371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        continue;
4372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
4373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
4374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    int alpha_ratio = src_alpha * 255 / dest_alpha;
4375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[0], alpha_ratio);
4376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan ++;
4377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[1], alpha_ratio);
4378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan ++;
4379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[2], alpha_ratio);
4380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan ++;
4381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan++ = dest_alpha;
4382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
4383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
4384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_LPBYTE dest_scan_alpha = (FX_LPBYTE)m_pAlphaMask->GetScanline(row) + rect.left;
4385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int col = 0; col < width; col ++) {
4386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FX_BYTE back_alpha = *dest_scan_alpha;
4387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (back_alpha == 0) {
4388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan_alpha++ = src_alpha;
4389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        FXSYS_memcpy32(dest_scan, color_p, Bpp);
4390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        dest_scan += Bpp;
4391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        continue;
4392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
4393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
4394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan_alpha ++ = dest_alpha;
4395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    int alpha_ratio = src_alpha * 255 / dest_alpha;
4396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    for(int comps = 0; comps < Bpp; comps ++) {
4397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[comps], alpha_ratio);
4398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        dest_scan ++;
4399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
4400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
4401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
4402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
4403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < width; col ++) {
4404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for(int comps = 0; comps < Bpp; comps ++) {
4405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (comps == 3) {
4406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *dest_scan ++ = 255;
4407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        continue;
4408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
4409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[comps], src_alpha);
4410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan ++;
4411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
4412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
4413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
4416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
4417ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_BitmapComposer::CFX_BitmapComposer()
4418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
4419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pScanlineV = NULL;
4420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pScanlineAlphaV = NULL;
4421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pClipScanV = NULL;
4422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pAddClipScan = NULL;
4423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bRgbByteOrder = FALSE;
4424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_BlendType = FXDIB_BLEND_NORMAL;
4425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
4426ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_BitmapComposer::~CFX_BitmapComposer()
4427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
4428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pScanlineV) {
4429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_pScanlineV);
4430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pScanlineAlphaV) {
4432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_pScanlineAlphaV);
4433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pClipScanV) {
4435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_pClipScanV);
4436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pAddClipScan) {
4438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_pAddClipScan);
4439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
4441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_BitmapComposer::Compose(CFX_DIBitmap* pDest, const CFX_ClipRgn* pClipRgn, int bitmap_alpha,
4442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                 FX_DWORD mask_color, FX_RECT& dest_rect, FX_BOOL bVertical,
4443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                 FX_BOOL bFlipX, FX_BOOL bFlipY, FX_BOOL bRgbByteOrder,
4444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                 int alpha_flag, void* pIccTransform, int blend_type)
4445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
4446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBitmap = pDest;
4447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pClipRgn = pClipRgn;
4448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DestLeft = dest_rect.left;
4449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DestTop = dest_rect.top;
4450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DestWidth = dest_rect.Width();
4451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DestHeight = dest_rect.Height();
4452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_BitmapAlpha = bitmap_alpha;
4453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_MaskColor = mask_color;
4454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pClipMask = NULL;
4455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) {
4456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pClipMask = pClipRgn->GetMask();
4457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bVertical = bVertical;
4459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bFlipX = bFlipX;
4460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bFlipY = bFlipY;
4461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_AlphaFlag = alpha_flag;
4462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pIccTransform = pIccTransform;
4463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bRgbByteOrder = bRgbByteOrder;
4464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_BlendType = blend_type;
4465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
4466ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_BitmapComposer::SetInfo(int width, int height, FXDIB_Format src_format, FX_DWORD* pSrcPalette)
4467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
4468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_SrcFormat = src_format;
4469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_Compositor.Init(m_pBitmap->GetFormat(), src_format, width, pSrcPalette, m_MaskColor, FXDIB_BLEND_NORMAL,
4470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                           m_pClipMask != NULL || (m_BitmapAlpha < 255), m_bRgbByteOrder, m_AlphaFlag, m_pIccTransform)) {
4471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
4472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_bVertical) {
4474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pScanlineV = FX_Alloc(FX_BYTE, m_pBitmap->GetBPP() / 8 * width + 4);
4475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!m_pScanlineV) {
4476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
4477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pClipScanV = FX_Alloc(FX_BYTE, m_pBitmap->GetHeight());
4479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!m_pClipScanV) {
4480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
4481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pBitmap->m_pAlphaMask) {
4483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pScanlineAlphaV = FX_Alloc(FX_BYTE, width + 4);
4484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!m_pScanlineAlphaV) {
4485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return FALSE;
4486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
4487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_BitmapAlpha < 255) {
4490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pAddClipScan = FX_Alloc(FX_BYTE, m_bVertical ? m_pBitmap->GetHeight() : m_pBitmap->GetWidth());
4491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!m_pAddClipScan) {
4492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
4493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
4496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
4497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_BitmapComposer::DoCompose(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int dest_width, FX_LPCBYTE clip_scan,
4498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   FX_LPCBYTE src_extra_alpha, FX_LPBYTE dst_extra_alpha)
4499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
4500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_BitmapAlpha < 255) {
4501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (clip_scan) {
4502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int i = 0; i < dest_width; i ++) {
4503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_pAddClipScan[i] = clip_scan[i] * m_BitmapAlpha / 255;
4504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
4505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
4506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FXSYS_memset8(m_pAddClipScan, m_BitmapAlpha, dest_width);
4507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        clip_scan = m_pAddClipScan;
4509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_SrcFormat == FXDIB_8bppMask) {
4511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Compositor.CompositeByteMaskLine(dest_scan, src_scan, dest_width, clip_scan, dst_extra_alpha);
4512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if ((m_SrcFormat & 0xff) == 8) {
4513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Compositor.CompositePalBitmapLine(dest_scan, src_scan, 0, dest_width, clip_scan, src_extra_alpha, dst_extra_alpha);
4514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
4515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Compositor.CompositeRgbBitmapLine(dest_scan, src_scan, dest_width, clip_scan, src_extra_alpha, dst_extra_alpha);
4516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
4518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_BitmapComposer::ComposeScanline(int line, FX_LPCBYTE scanline, FX_LPCBYTE scan_extra_alpha)
4519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
4520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_bVertical) {
4521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ComposeScanlineV(line, scanline, scan_extra_alpha);
4522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
4523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPCBYTE clip_scan = NULL;
4525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pClipMask)
4526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        clip_scan = m_pClipMask->GetBuffer() + (m_DestTop + line - m_pClipRgn->GetBox().top) *
4527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    m_pClipMask->GetPitch() + (m_DestLeft - m_pClipRgn->GetBox().left);
4528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPBYTE dest_scan = (FX_LPBYTE)m_pBitmap->GetScanline(line + m_DestTop) +
4529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                          m_DestLeft * m_pBitmap->GetBPP() / 8;
4530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPBYTE dest_alpha_scan = m_pBitmap->m_pAlphaMask ?
4531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                (FX_LPBYTE)m_pBitmap->m_pAlphaMask->GetScanline(line + m_DestTop) + m_DestLeft : NULL;
4532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    DoCompose(dest_scan, scanline, m_DestWidth, clip_scan, scan_extra_alpha, dest_alpha_scan);
4533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
4534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_BitmapComposer::ComposeScanlineV(int line, FX_LPCBYTE scanline, FX_LPCBYTE scan_extra_alpha)
4535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
4536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
4537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int Bpp = m_pBitmap->GetBPP() / 8;
4538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int dest_pitch = m_pBitmap->GetPitch();
4539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int dest_alpha_pitch = m_pBitmap->m_pAlphaMask ? m_pBitmap->m_pAlphaMask->GetPitch() : 0;
4540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int dest_x = m_DestLeft + (m_bFlipX ? (m_DestWidth - line - 1) : line);
4541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPBYTE dest_buf = m_pBitmap->GetBuffer() + dest_x * Bpp + m_DestTop * dest_pitch;
4542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPBYTE dest_alpha_buf = m_pBitmap->m_pAlphaMask ?
4543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               m_pBitmap->m_pAlphaMask->GetBuffer() + dest_x + m_DestTop * dest_alpha_pitch : NULL;
4544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_bFlipY) {
4545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_buf += dest_pitch * (m_DestHeight - 1);
4546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_alpha_buf += dest_alpha_pitch * (m_DestHeight - 1);
4547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int y_step = dest_pitch;
4549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int y_alpha_step = dest_alpha_pitch;
4550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_bFlipY) {
4551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        y_step = -y_step;
4552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        y_alpha_step = -y_alpha_step;
4553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPBYTE src_scan = m_pScanlineV;
4555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPBYTE dest_scan = dest_buf;
4556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < m_DestHeight; i ++) {
4557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int j = 0; j < Bpp; j ++) {
4558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *src_scan++ = dest_scan[j];
4559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += y_step;
4561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPBYTE src_alpha_scan = m_pScanlineAlphaV;
4563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPBYTE dest_alpha_scan = dest_alpha_buf;
4564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (dest_alpha_scan) {
4565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (i = 0; i < m_DestHeight; i ++) {
4566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *src_alpha_scan++ = *dest_alpha_scan;
4567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_alpha_scan += y_alpha_step;
4568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPBYTE clip_scan = NULL;
4571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pClipMask) {
4572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        clip_scan = m_pClipScanV;
4573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int clip_pitch = m_pClipMask->GetPitch();
4574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE src_clip = m_pClipMask->GetBuffer() + (m_DestTop - m_pClipRgn->GetBox().top) *
4575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              clip_pitch + (dest_x - m_pClipRgn->GetBox().left);
4576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_bFlipY) {
4577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_clip += clip_pitch * (m_DestHeight - 1);
4578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            clip_pitch = -clip_pitch;
4579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (i = 0; i < m_DestHeight; i ++) {
4581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            clip_scan[i] = *src_clip;
4582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_clip += clip_pitch;
4583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    DoCompose(m_pScanlineV, scanline, m_DestHeight, clip_scan, scan_extra_alpha, m_pScanlineAlphaV);
4586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    src_scan = m_pScanlineV;
4587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    dest_scan = dest_buf;
4588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < m_DestHeight; i ++) {
4589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int j = 0; j < Bpp; j ++) {
4590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[j] = *src_scan++;
4591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest_scan += y_step;
4593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    src_alpha_scan = m_pScanlineAlphaV;
4595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    dest_alpha_scan = dest_alpha_buf;
4596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (dest_alpha_scan) {
4597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (i = 0; i < m_DestHeight; i ++) {
4598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_alpha_scan = *src_alpha_scan++;
4599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_alpha_scan += y_alpha_step;
4600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
4601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
4602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
4603