root / vnchextile.h @ dffbe217
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 |
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 |
if (n_data > (w * h * sizeof(pixel_t))) { |
169 |
n_colors = 4;
|
170 |
flags = 0x01;
|
171 |
*has_bg = 0;
|
172 |
|
173 |
/* we really don't have to invalidate either the bg or fg
|
174 |
but we've lost the old values. oh well. */
|
175 |
} |
176 |
default:
|
177 |
break;
|
178 |
} |
179 |
|
180 |
if (n_colors > 3) { |
181 |
flags = 0x01;
|
182 |
*has_fg = 0;
|
183 |
*has_bg = 0;
|
184 |
n_colors = 4;
|
185 |
} |
186 |
|
187 |
vnc_write_u8(vs, flags); |
188 |
if (n_colors < 4) { |
189 |
if (flags & 0x02) |
190 |
vs->write_pixels(vs, last_bg, sizeof(pixel_t));
|
191 |
if (flags & 0x04) |
192 |
vs->write_pixels(vs, last_fg, sizeof(pixel_t));
|
193 |
if (n_subtiles) {
|
194 |
vnc_write_u8(vs, n_subtiles); |
195 |
vnc_write(vs, data, n_data); |
196 |
} |
197 |
} else {
|
198 |
for (j = 0; j < h; j++) { |
199 |
vs->write_pixels(vs, row, w * ds_get_bytes_per_pixel(vs->ds)); |
200 |
row += ds_get_linesize(vs->ds); |
201 |
} |
202 |
} |
203 |
} |
204 |
|
205 |
#undef NAME
|
206 |
#undef pixel_t
|
207 |
#undef CONCAT_I
|
208 |
#undef CONCAT
|