Statistics
| Branch: | Revision:

root / ui / vnc-enc-hextile-template.h @ d4970b07

History | View | Annotate | Download (4.7 kB)

1 24236869 bellard
#define CONCAT_I(a, b) a ## b
2 24236869 bellard
#define CONCAT(a, b) CONCAT_I(a, b)
3 24236869 bellard
#define pixel_t CONCAT(uint, CONCAT(BPP, _t))
4 3512779a bellard
#ifdef GENERIC
5 7eac3a87 aliguori
#define NAME CONCAT(generic_, BPP)
6 3512779a bellard
#else
7 3512779a bellard
#define NAME BPP
8 3512779a bellard
#endif
9 3512779a bellard
10 3512779a bellard
static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
11 3512779a bellard
                                             int x, int y, int w, int h,
12 7eac3a87 aliguori
                                             void *last_bg_,
13 7eac3a87 aliguori
                                             void *last_fg_,
14 3512779a bellard
                                             int *has_bg, int *has_fg)
15 24236869 bellard
{
16 1fc62412 Stefano Stabellini
    VncDisplay *vd = vs->vd;
17 1fc62412 Stefano Stabellini
    uint8_t *row = vd->server->data + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds);
18 24236869 bellard
    pixel_t *irow = (pixel_t *)row;
19 24236869 bellard
    int j, i;
20 7eac3a87 aliguori
    pixel_t *last_bg = (pixel_t *)last_bg_;
21 7eac3a87 aliguori
    pixel_t *last_fg = (pixel_t *)last_fg_;
22 24236869 bellard
    pixel_t bg = 0;
23 24236869 bellard
    pixel_t fg = 0;
24 24236869 bellard
    int n_colors = 0;
25 24236869 bellard
    int bg_count = 0;
26 24236869 bellard
    int fg_count = 0;
27 24236869 bellard
    int flags = 0;
28 6cec5487 aliguori
    uint8_t data[(vs->clientds.pf.bytes_per_pixel + 2) * 16 * 16];
29 24236869 bellard
    int n_data = 0;
30 24236869 bellard
    int n_subtiles = 0;
31 24236869 bellard
32 24236869 bellard
    for (j = 0; j < h; j++) {
33 24236869 bellard
        for (i = 0; i < w; i++) {
34 24236869 bellard
            switch (n_colors) {
35 24236869 bellard
            case 0:
36 24236869 bellard
                bg = irow[i];
37 24236869 bellard
                n_colors = 1;
38 24236869 bellard
                break;
39 24236869 bellard
            case 1:
40 24236869 bellard
                if (irow[i] != bg) {
41 24236869 bellard
                    fg = irow[i];
42 24236869 bellard
                    n_colors = 2;
43 24236869 bellard
                }
44 24236869 bellard
                break;
45 24236869 bellard
            case 2:
46 24236869 bellard
                if (irow[i] != bg && irow[i] != fg) {
47 24236869 bellard
                    n_colors = 3;
48 24236869 bellard
                } else {
49 24236869 bellard
                    if (irow[i] == bg)
50 24236869 bellard
                        bg_count++;
51 24236869 bellard
                    else if (irow[i] == fg)
52 24236869 bellard
                        fg_count++;
53 24236869 bellard
                }
54 24236869 bellard
                break;
55 24236869 bellard
            default:
56 24236869 bellard
                break;
57 24236869 bellard
            }
58 24236869 bellard
        }
59 24236869 bellard
        if (n_colors > 2)
60 24236869 bellard
            break;
61 0e1f5a0c aliguori
        irow += ds_get_linesize(vs->ds) / sizeof(pixel_t);
62 24236869 bellard
    }
63 24236869 bellard
64 24236869 bellard
    if (n_colors > 1 && fg_count > bg_count) {
65 24236869 bellard
        pixel_t tmp = fg;
66 24236869 bellard
        fg = bg;
67 24236869 bellard
        bg = tmp;
68 24236869 bellard
    }
69 24236869 bellard
70 24236869 bellard
    if (!*has_bg || *last_bg != bg) {
71 24236869 bellard
        flags |= 0x02;
72 24236869 bellard
        *has_bg = 1;
73 24236869 bellard
        *last_bg = bg;
74 24236869 bellard
    }
75 24236869 bellard
76 02c2b87f Anthony Liguori
    if (n_colors < 3 && (!*has_fg || *last_fg != fg)) {
77 24236869 bellard
        flags |= 0x04;
78 24236869 bellard
        *has_fg = 1;
79 24236869 bellard
        *last_fg = fg;
80 24236869 bellard
    }
81 24236869 bellard
82 24236869 bellard
    switch (n_colors) {
83 24236869 bellard
    case 1:
84 24236869 bellard
        n_data = 0;
85 24236869 bellard
        break;
86 24236869 bellard
    case 2:
87 24236869 bellard
        flags |= 0x08;
88 24236869 bellard
89 24236869 bellard
        irow = (pixel_t *)row;
90 5fafdf24 ths
91 24236869 bellard
        for (j = 0; j < h; j++) {
92 24236869 bellard
            int min_x = -1;
93 24236869 bellard
            for (i = 0; i < w; i++) {
94 24236869 bellard
                if (irow[i] == fg) {
95 24236869 bellard
                    if (min_x == -1)
96 24236869 bellard
                        min_x = i;
97 24236869 bellard
                } else if (min_x != -1) {
98 24236869 bellard
                    hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
99 24236869 bellard
                    n_data += 2;
100 24236869 bellard
                    n_subtiles++;
101 24236869 bellard
                    min_x = -1;
102 24236869 bellard
                }
103 24236869 bellard
            }
104 24236869 bellard
            if (min_x != -1) {
105 24236869 bellard
                hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
106 24236869 bellard
                n_data += 2;
107 24236869 bellard
                n_subtiles++;
108 24236869 bellard
            }
109 0e1f5a0c aliguori
            irow += ds_get_linesize(vs->ds) / sizeof(pixel_t);
110 24236869 bellard
        }
111 24236869 bellard
        break;
112 24236869 bellard
    case 3:
113 24236869 bellard
        flags |= 0x18;
114 24236869 bellard
115 24236869 bellard
        irow = (pixel_t *)row;
116 24236869 bellard
117 24236869 bellard
        if (!*has_bg || *last_bg != bg)
118 24236869 bellard
            flags |= 0x02;
119 24236869 bellard
120 24236869 bellard
        for (j = 0; j < h; j++) {
121 24236869 bellard
            int has_color = 0;
122 24236869 bellard
            int min_x = -1;
123 92190c64 ths
            pixel_t color = 0; /* shut up gcc */
124 24236869 bellard
125 24236869 bellard
            for (i = 0; i < w; i++) {
126 24236869 bellard
                if (!has_color) {
127 24236869 bellard
                    if (irow[i] == bg)
128 24236869 bellard
                        continue;
129 24236869 bellard
                    color = irow[i];
130 24236869 bellard
                    min_x = i;
131 24236869 bellard
                    has_color = 1;
132 24236869 bellard
                } else if (irow[i] != color) {
133 24236869 bellard
                    has_color = 0;
134 3512779a bellard
#ifdef GENERIC
135 3512779a bellard
                    vnc_convert_pixel(vs, data + n_data, color);
136 6cec5487 aliguori
                    n_data += vs->clientds.pf.bytes_per_pixel;
137 3512779a bellard
#else
138 24236869 bellard
                    memcpy(data + n_data, &color, sizeof(color));
139 3512779a bellard
                    n_data += sizeof(pixel_t);
140 3512779a bellard
#endif
141 3512779a bellard
                    hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
142 3512779a bellard
                    n_data += 2;
143 24236869 bellard
                    n_subtiles++;
144 24236869 bellard
145 24236869 bellard
                    min_x = -1;
146 24236869 bellard
                    if (irow[i] != bg) {
147 24236869 bellard
                        color = irow[i];
148 24236869 bellard
                        min_x = i;
149 24236869 bellard
                        has_color = 1;
150 24236869 bellard
                    }
151 24236869 bellard
                }
152 24236869 bellard
            }
153 24236869 bellard
            if (has_color) {
154 3512779a bellard
#ifdef GENERIC
155 3512779a bellard
                vnc_convert_pixel(vs, data + n_data, color);
156 6cec5487 aliguori
                n_data += vs->clientds.pf.bytes_per_pixel;
157 3512779a bellard
#else
158 3512779a bellard
                memcpy(data + n_data, &color, sizeof(color));
159 3512779a bellard
                n_data += sizeof(pixel_t);
160 3512779a bellard
#endif
161 3512779a bellard
                hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
162 3512779a bellard
                n_data += 2;
163 24236869 bellard
                n_subtiles++;
164 24236869 bellard
            }
165 0e1f5a0c aliguori
            irow += ds_get_linesize(vs->ds) / sizeof(pixel_t);
166 24236869 bellard
        }
167 24236869 bellard
168 18cb1d85 Anthony Liguori
        /* A SubrectsColoured subtile invalidates the foreground color */
169 18cb1d85 Anthony Liguori
        *has_fg = 0;
170 24236869 bellard
        if (n_data > (w * h * sizeof(pixel_t))) {
171 24236869 bellard
            n_colors = 4;
172 24236869 bellard
            flags = 0x01;
173 24236869 bellard
            *has_bg = 0;
174 24236869 bellard
175 24236869 bellard
            /* we really don't have to invalidate either the bg or fg
176 24236869 bellard
               but we've lost the old values.  oh well. */
177 24236869 bellard
        }
178 24236869 bellard
    default:
179 24236869 bellard
        break;
180 24236869 bellard
    }
181 24236869 bellard
182 24236869 bellard
    if (n_colors > 3) {
183 24236869 bellard
        flags = 0x01;
184 24236869 bellard
        *has_fg = 0;
185 24236869 bellard
        *has_bg = 0;
186 24236869 bellard
        n_colors = 4;
187 24236869 bellard
    }
188 24236869 bellard
189 24236869 bellard
    vnc_write_u8(vs, flags);
190 24236869 bellard
    if (n_colors < 4) {
191 24236869 bellard
        if (flags & 0x02)
192 d467b679 Gerd Hoffmann
            vs->write_pixels(vs, &vd->server->pf, last_bg, sizeof(pixel_t));
193 24236869 bellard
        if (flags & 0x04)
194 d467b679 Gerd Hoffmann
            vs->write_pixels(vs, &vd->server->pf, last_fg, sizeof(pixel_t));
195 24236869 bellard
        if (n_subtiles) {
196 24236869 bellard
            vnc_write_u8(vs, n_subtiles);
197 24236869 bellard
            vnc_write(vs, data, n_data);
198 24236869 bellard
        }
199 24236869 bellard
    } else {
200 24236869 bellard
        for (j = 0; j < h; j++) {
201 d467b679 Gerd Hoffmann
            vs->write_pixels(vs, &vd->server->pf, row,
202 d467b679 Gerd Hoffmann
                             w * ds_get_bytes_per_pixel(vs->ds));
203 0e1f5a0c aliguori
            row += ds_get_linesize(vs->ds);
204 24236869 bellard
        }
205 24236869 bellard
    }
206 24236869 bellard
}
207 24236869 bellard
208 3512779a bellard
#undef NAME
209 24236869 bellard
#undef pixel_t
210 24236869 bellard
#undef CONCAT_I
211 24236869 bellard
#undef CONCAT