Statistics
| Branch: | Revision:

root / vnchextile.h @ 5fafdf24

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