|
|
1.1 root 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: /* A SubrectsColoured subtile invalidates the foreground color */
169: *has_fg = 0;
170: if (n_data > (w * h * sizeof(pixel_t))) {
171: n_colors = 4;
172: flags = 0x01;
173: *has_bg = 0;
174:
175: /* we really don't have to invalidate either the bg or fg
176: but we've lost the old values. oh well. */
177: }
1.1.1.2 ! root 178: break;
1.1 root 179: default:
180: break;
181: }
182:
183: if (n_colors > 3) {
184: flags = 0x01;
185: *has_fg = 0;
186: *has_bg = 0;
187: n_colors = 4;
188: }
189:
190: vnc_write_u8(vs, flags);
191: if (n_colors < 4) {
192: if (flags & 0x02)
193: vs->write_pixels(vs, &vd->server->pf, last_bg, sizeof(pixel_t));
194: if (flags & 0x04)
195: vs->write_pixels(vs, &vd->server->pf, last_fg, sizeof(pixel_t));
196: if (n_subtiles) {
197: vnc_write_u8(vs, n_subtiles);
198: vnc_write(vs, data, n_data);
199: }
200: } else {
201: for (j = 0; j < h; j++) {
202: vs->write_pixels(vs, &vd->server->pf, row,
203: w * ds_get_bytes_per_pixel(vs->ds));
204: row += ds_get_linesize(vs->ds);
205: }
206: }
207: }
208:
209: #undef NAME
210: #undef pixel_t
211: #undef CONCAT_I
212: #undef CONCAT
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.