root / vnchextile.h @ 6b5435d7
History | View | Annotate | Download (4.4 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 generic
|
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 |
uint32_t *last_bg32, |
13 |
uint32_t *last_fg32, |
14 |
int *has_bg, int *has_fg) |
15 |
{ |
16 |
uint8_t *row = (vs->ds->data + y * vs->ds->linesize + x * vs->depth); |
17 |
pixel_t *irow = (pixel_t *)row; |
18 |
int j, i;
|
19 |
pixel_t *last_bg = (pixel_t *)last_bg32; |
20 |
pixel_t *last_fg = (pixel_t *)last_fg32; |
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[(sizeof(pixel_t) + 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 += vs->ds->linesize / 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 += vs->ds->linesize / 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->pix_bpp; |
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->pix_bpp; |
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 += vs->ds->linesize / 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 * vs->depth); |
201 |
row += vs->ds->linesize; |
202 |
} |
203 |
} |
204 |
} |
205 |
|
206 |
#undef NAME
|
207 |
#undef pixel_t
|
208 |
#undef CONCAT_I
|
209 |
#undef CONCAT
|