Statistics
| Branch: | Revision:

root / ui / vnchextile.h @ 3e230dd2

History | View | Annotate | Download (4.7 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
#ifdef GENERIC
5
#define NAME CONCAT(generic_, BPP)
6
#else
7
#define NAME BPP
8
#endif
9

    
10
static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
11
                                             int x, int y, int w, int h,
12
                                             void *last_bg_,
13
                                             void *last_fg_,
14
                                             int *has_bg, int *has_fg)
15
{
16
    VncDisplay *vd = vs->vd;
17
    uint8_t *row = vd->server->data + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds);
18
    pixel_t *irow = (pixel_t *)row;
19
    int j, i;
20
    pixel_t *last_bg = (pixel_t *)last_bg_;
21
    pixel_t *last_fg = (pixel_t *)last_fg_;
22
    pixel_t bg = 0;
23
    pixel_t fg = 0;
24
    int n_colors = 0;
25
    int bg_count = 0;
26
    int fg_count = 0;
27
    int flags = 0;
28
    uint8_t data[(vs->clientds.pf.bytes_per_pixel + 2) * 16 * 16];
29
    int n_data = 0;
30
    int n_subtiles = 0;
31

    
32
    for (j = 0; j < h; j++) {
33
        for (i = 0; i < w; i++) {
34
            switch (n_colors) {
35
            case 0:
36
                bg = irow[i];
37
                n_colors = 1;
38
                break;
39
            case 1:
40
                if (irow[i] != bg) {
41
                    fg = irow[i];
42
                    n_colors = 2;
43
                }
44
                break;
45
            case 2:
46
                if (irow[i] != bg && irow[i] != fg) {
47
                    n_colors = 3;
48
                } else {
49
                    if (irow[i] == bg)
50
                        bg_count++;
51
                    else if (irow[i] == fg)
52
                        fg_count++;
53
                }
54
                break;
55
            default:
56
                break;
57
            }
58
        }
59
        if (n_colors > 2)
60
            break;
61
        irow += ds_get_linesize(vs->ds) / sizeof(pixel_t);
62
    }
63

    
64
    if (n_colors > 1 && fg_count > bg_count) {
65
        pixel_t tmp = fg;
66
        fg = bg;
67
        bg = tmp;
68
    }
69

    
70
    if (!*has_bg || *last_bg != bg) {
71
        flags |= 0x02;
72
        *has_bg = 1;
73
        *last_bg = bg;
74
    }
75

    
76
    if (n_colors < 3 && (!*has_fg || *last_fg != fg)) {
77
        flags |= 0x04;
78
        *has_fg = 1;
79
        *last_fg = fg;
80
    }
81

    
82
    switch (n_colors) {
83
    case 1:
84
        n_data = 0;
85
        break;
86
    case 2:
87
        flags |= 0x08;
88

    
89
        irow = (pixel_t *)row;
90

    
91
        for (j = 0; j < h; j++) {
92
            int min_x = -1;
93
            for (i = 0; i < w; i++) {
94
                if (irow[i] == fg) {
95
                    if (min_x == -1)
96
                        min_x = i;
97
                } else if (min_x != -1) {
98
                    hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
99
                    n_data += 2;
100
                    n_subtiles++;
101
                    min_x = -1;
102
                }
103
            }
104
            if (min_x != -1) {
105
                hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
106
                n_data += 2;
107
                n_subtiles++;
108
            }
109
            irow += ds_get_linesize(vs->ds) / sizeof(pixel_t);
110
        }
111
        break;
112
    case 3:
113
        flags |= 0x18;
114

    
115
        irow = (pixel_t *)row;
116

    
117
        if (!*has_bg || *last_bg != bg)
118
            flags |= 0x02;
119

    
120
        for (j = 0; j < h; j++) {
121
            int has_color = 0;
122
            int min_x = -1;
123
            pixel_t color = 0; /* shut up gcc */
124

    
125
            for (i = 0; i < w; i++) {
126
                if (!has_color) {
127
                    if (irow[i] == bg)
128
                        continue;
129
                    color = irow[i];
130
                    min_x = i;
131
                    has_color = 1;
132
                } else if (irow[i] != color) {
133
                    has_color = 0;
134
#ifdef GENERIC
135
                    vnc_convert_pixel(vs, data + n_data, color);
136
                    n_data += vs->clientds.pf.bytes_per_pixel;
137
#else
138
                    memcpy(data + n_data, &color, sizeof(color));
139
                    n_data += sizeof(pixel_t);
140
#endif
141
                    hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
142
                    n_data += 2;
143
                    n_subtiles++;
144

    
145
                    min_x = -1;
146
                    if (irow[i] != bg) {
147
                        color = irow[i];
148
                        min_x = i;
149
                        has_color = 1;
150
                    }
151
                }
152
            }
153
            if (has_color) {
154
#ifdef GENERIC
155
                vnc_convert_pixel(vs, data + n_data, color);
156
                n_data += vs->clientds.pf.bytes_per_pixel;
157
#else
158
                memcpy(data + n_data, &color, sizeof(color));
159
                n_data += sizeof(pixel_t);
160
#endif
161
                hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
162
                n_data += 2;
163
                n_subtiles++;
164
            }
165
            irow += ds_get_linesize(vs->ds) / sizeof(pixel_t);
166
        }
167

    
168
        /* A SubrectsColoured subtile invalidates the foreground color */
169
        *has_fg = 0;
170
        if (n_data > (w * h * sizeof(pixel_t))) {
171
            n_colors = 4;
172
            flags = 0x01;
173
            *has_bg = 0;
174

    
175
            /* we really don't have to invalidate either the bg or fg
176
               but we've lost the old values.  oh well. */
177
        }
178
    default:
179
        break;
180
    }
181

    
182
    if (n_colors > 3) {
183
        flags = 0x01;
184
        *has_fg = 0;
185
        *has_bg = 0;
186
        n_colors = 4;
187
    }
188

    
189
    vnc_write_u8(vs, flags);
190
    if (n_colors < 4) {
191
        if (flags & 0x02)
192
            vs->write_pixels(vs, &vd->server->pf, last_bg, sizeof(pixel_t));
193
        if (flags & 0x04)
194
            vs->write_pixels(vs, &vd->server->pf, last_fg, sizeof(pixel_t));
195
        if (n_subtiles) {
196
            vnc_write_u8(vs, n_subtiles);
197
            vnc_write(vs, data, n_data);
198
        }
199
    } else {
200
        for (j = 0; j < h; j++) {
201
            vs->write_pixels(vs, &vd->server->pf, row,
202
                             w * ds_get_bytes_per_pixel(vs->ds));
203
            row += ds_get_linesize(vs->ds);
204
        }
205
    }
206
}
207

    
208
#undef NAME
209
#undef pixel_t
210
#undef CONCAT_I
211
#undef CONCAT