|
|
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: } ! 178: default: ! 179: break; ! 180: } ! 181: ! 182: if (n_colors > 3) { ! 183: flags = 0x01; ! 184: *has_fg = 0; ! 185: *has_bg = 0; ! 186: n_colors = 4; ! 187: } ! 188: ! 189: vnc_write_u8(vs, flags); ! 190: if (n_colors < 4) { ! 191: if (flags & 0x02) ! 192: vs->write_pixels(vs, &vd->server->pf, last_bg, sizeof(pixel_t)); ! 193: if (flags & 0x04) ! 194: vs->write_pixels(vs, &vd->server->pf, last_fg, sizeof(pixel_t)); ! 195: if (n_subtiles) { ! 196: vnc_write_u8(vs, n_subtiles); ! 197: vnc_write(vs, data, n_data); ! 198: } ! 199: } else { ! 200: for (j = 0; j < h; j++) { ! 201: vs->write_pixels(vs, &vd->server->pf, row, ! 202: w * ds_get_bytes_per_pixel(vs->ds)); ! 203: row += ds_get_linesize(vs->ds); ! 204: } ! 205: } ! 206: } ! 207: ! 208: #undef NAME ! 209: #undef pixel_t ! 210: #undef CONCAT_I ! 211: #undef CONCAT
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.