blob: 35dcc57271bcd27a0abcf3f9c3b2ca9575934db5 [file] [log] [blame]
bellard24236862006-04-30 21:28:36 +00001#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))
bellard35127792006-05-14 18:11:49 +00004#ifdef GENERIC
5#define NAME generic
6#else
7#define NAME BPP
8#endif
bellard24236862006-04-30 21:28:36 +00009
bellard35127792006-05-14 18:11:49 +000010static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
11 int x, int y, int w, int h,
ths5fafdf22007-09-16 21:08:06 +000012 uint32_t *last_bg32,
bellard35127792006-05-14 18:11:49 +000013 uint32_t *last_fg32,
14 int *has_bg, int *has_fg)
bellard24236862006-04-30 21:28:36 +000015{
16 char *row = (vs->ds->data + y * vs->ds->linesize + x * vs->depth);
17 pixel_t *irow = (pixel_t *)row;
18 int j, i;
bellard35127792006-05-14 18:11:49 +000019 pixel_t *last_bg = (pixel_t *)last_bg32;
20 pixel_t *last_fg = (pixel_t *)last_fg32;
bellard24236862006-04-30 21:28:36 +000021 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;
ths5fafdf22007-09-16 21:08:06 +000089
bellard24236862006-04-30 21:28:36 +000090 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;
ths92190c62006-12-21 16:50:09 +0000122 pixel_t color = 0; /* shut up gcc */
bellard24236862006-04-30 21:28:36 +0000123
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;
bellard35127792006-05-14 18:11:49 +0000133#ifdef GENERIC
134 vnc_convert_pixel(vs, data + n_data, color);
135 n_data += vs->pix_bpp;
136#else
bellard24236862006-04-30 21:28:36 +0000137 memcpy(data + n_data, &color, sizeof(color));
bellard35127792006-05-14 18:11:49 +0000138 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;
bellard24236862006-04-30 21:28:36 +0000142 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) {
bellard35127792006-05-14 18:11:49 +0000153#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;
bellard24236862006-04-30 21:28:36 +0000162 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)
bellard35127792006-05-14 18:11:49 +0000191 vs->write_pixels(vs, last_bg, sizeof(pixel_t));
bellard24236862006-04-30 21:28:36 +0000192 if (flags & 0x04)
bellard35127792006-05-14 18:11:49 +0000193 vs->write_pixels(vs, last_fg, sizeof(pixel_t));
bellard24236862006-04-30 21:28:36 +0000194 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++) {
bellard35127792006-05-14 18:11:49 +0000200 vs->write_pixels(vs, row, w * vs->depth);
bellard24236862006-04-30 21:28:36 +0000201 row += vs->ds->linesize;
202 }
203 }
204}
205
bellard35127792006-05-14 18:11:49 +0000206#undef NAME
bellard24236862006-04-30 21:28:36 +0000207#undef pixel_t
208#undef CONCAT_I
209#undef CONCAT