Statistics
| Branch: | Revision:

root / vnchextile.h @ 6baebed7

History | View | Annotate | Download (4.5 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
    uint8_t *row = vs->server.ds->data + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds);
17
    pixel_t *irow = (pixel_t *)row;
18
    int j, i;
19
    pixel_t *last_bg = (pixel_t *)last_bg_;
20
    pixel_t *last_fg = (pixel_t *)last_fg_;
21
    pixel_t bg = 0;
22
    pixel_t fg = 0;
23
    int n_colors = 0;
24
    int bg_count = 0;
25
    int fg_count = 0;
26
    int flags = 0;
27
    uint8_t data[(vs->clientds.pf.bytes_per_pixel + 2) * 16 * 16];
28
    int n_data = 0;
29
    int n_subtiles = 0;
30

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

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

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

    
75
    if (!*has_fg || *last_fg != fg) {
76
        flags |= 0x04;
77
        *has_fg = 1;
78
        *last_fg = fg;
79
    }
80

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

    
88
        irow = (pixel_t *)row;
89

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

    
114
        irow = (pixel_t *)row;
115

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

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

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

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

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

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

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

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

    
206
#undef NAME
207
#undef pixel_t
208
#undef CONCAT_I
209
#undef CONCAT