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