Statistics
| Branch: | Revision:

root / vnchextile.h @ 24236869

History | View | Annotate | Download (3.8 kB)

1
#define CONCAT_I(a, b) a ## b
2
#define CONCAT(a, b) CONCAT_I(a, b)
3
#define pixel_t CONCAT(uint, CONCAT(BPP, _t))
4

    
5
static void CONCAT(send_hextile_tile_, BPP)(VncState *vs,
6
                                            int x, int y, int w, int h,
7
                                            pixel_t *last_bg, pixel_t *last_fg,
8
                                            int *has_bg, int *has_fg)
9
{
10
    char *row = (vs->ds->data + y * vs->ds->linesize + x * vs->depth);
11
    pixel_t *irow = (pixel_t *)row;
12
    int j, i;
13
    pixel_t bg = 0;
14
    pixel_t fg = 0;
15
    int n_colors = 0;
16
    int bg_count = 0;
17
    int fg_count = 0;
18
    int flags = 0;
19
    uint8_t data[(sizeof(pixel_t) + 2) * 16 * 16];
20
    int n_data = 0;
21
    int n_subtiles = 0;
22

    
23
    for (j = 0; j < h; j++) {
24
        for (i = 0; i < w; i++) {
25
            switch (n_colors) {
26
            case 0:
27
                bg = irow[i];
28
                n_colors = 1;
29
                break;
30
            case 1:
31
                if (irow[i] != bg) {
32
                    fg = irow[i];
33
                    n_colors = 2;
34
                }
35
                break;
36
            case 2:
37
                if (irow[i] != bg && irow[i] != fg) {
38
                    n_colors = 3;
39
                } else {
40
                    if (irow[i] == bg)
41
                        bg_count++;
42
                    else if (irow[i] == fg)
43
                        fg_count++;
44
                }
45
                break;
46
            default:
47
                break;
48
            }
49
        }
50
        if (n_colors > 2)
51
            break;
52
        irow += vs->ds->linesize / sizeof(pixel_t);
53
    }
54

    
55
    if (n_colors > 1 && fg_count > bg_count) {
56
        pixel_t tmp = fg;
57
        fg = bg;
58
        bg = tmp;
59
    }
60

    
61
    if (!*has_bg || *last_bg != bg) {
62
        flags |= 0x02;
63
        *has_bg = 1;
64
        *last_bg = bg;
65
    }
66

    
67
    if (!*has_fg || *last_fg != fg) {
68
        flags |= 0x04;
69
        *has_fg = 1;
70
        *last_fg = fg;
71
    }
72

    
73
    switch (n_colors) {
74
    case 1:
75
        n_data = 0;
76
        break;
77
    case 2:
78
        flags |= 0x08;
79

    
80
        irow = (pixel_t *)row;
81
        
82
        for (j = 0; j < h; j++) {
83
            int min_x = -1;
84
            for (i = 0; i < w; i++) {
85
                if (irow[i] == fg) {
86
                    if (min_x == -1)
87
                        min_x = i;
88
                } else if (min_x != -1) {
89
                    hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
90
                    n_data += 2;
91
                    n_subtiles++;
92
                    min_x = -1;
93
                }
94
            }
95
            if (min_x != -1) {
96
                hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
97
                n_data += 2;
98
                n_subtiles++;
99
            }
100
            irow += vs->ds->linesize / sizeof(pixel_t);
101
        }
102
        break;
103
    case 3:
104
        flags |= 0x18;
105

    
106
        irow = (pixel_t *)row;
107

    
108
        if (!*has_bg || *last_bg != bg)
109
            flags |= 0x02;
110

    
111
        for (j = 0; j < h; j++) {
112
            int has_color = 0;
113
            int min_x = -1;
114
            pixel_t color;
115

    
116
            for (i = 0; i < w; i++) {
117
                if (!has_color) {
118
                    if (irow[i] == bg)
119
                        continue;
120
                    color = irow[i];
121
                    min_x = i;
122
                    has_color = 1;
123
                } else if (irow[i] != color) {
124
                    has_color = 0;
125

    
126
                    memcpy(data + n_data, &color, sizeof(color));
127
                    hextile_enc_cord(data + n_data + sizeof(pixel_t), min_x, j, i - min_x, 1);
128
                    n_data += 2 + sizeof(pixel_t);
129
                    n_subtiles++;
130

    
131
                    min_x = -1;
132
                    if (irow[i] != bg) {
133
                        color = irow[i];
134
                        min_x = i;
135
                        has_color = 1;
136
                    }
137
                }
138
            }
139
            if (has_color) {
140
                memcpy(data + n_data, &color, sizeof(color));
141
                hextile_enc_cord(data + n_data + sizeof(pixel_t), min_x, j, i - min_x, 1);
142
                n_data += 2 + sizeof(pixel_t);
143
                n_subtiles++;
144
            }
145
            irow += vs->ds->linesize / sizeof(pixel_t);
146
        }
147

    
148
        /* A SubrectsColoured subtile invalidates the foreground color */
149
        *has_fg = 0;
150
        if (n_data > (w * h * sizeof(pixel_t))) {
151
            n_colors = 4;
152
            flags = 0x01;
153
            *has_bg = 0;
154

    
155
            /* we really don't have to invalidate either the bg or fg
156
               but we've lost the old values.  oh well. */
157
        }
158
    default:
159
        break;
160
    }
161

    
162
    if (n_colors > 3) {
163
        flags = 0x01;
164
        *has_fg = 0;
165
        *has_bg = 0;
166
        n_colors = 4;
167
    }
168

    
169
    vnc_write_u8(vs, flags);
170
    if (n_colors < 4) {
171
        if (flags & 0x02)
172
            vnc_write(vs, last_bg, sizeof(pixel_t));
173
        if (flags & 0x04)
174
            vnc_write(vs, last_fg, sizeof(pixel_t));
175
        if (n_subtiles) {
176
            vnc_write_u8(vs, n_subtiles);
177
            vnc_write(vs, data, n_data);
178
        }
179
    } else {
180
        for (j = 0; j < h; j++) {
181
            vnc_write(vs, row, w * vs->depth);
182
            row += vs->ds->linesize;
183
        }
184
    }
185
}
186

    
187
#undef pixel_t
188
#undef CONCAT_I
189
#undef CONCAT