18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define CONCAT_I(a, b) a ## b 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define CONCAT(a, b) CONCAT_I(a, b) 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define pixel_t CONCAT(uint, CONCAT(BPP, _t)) 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef GENERIC 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NAME CONCAT(generic_, BPP) 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NAME BPP 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void CONCAT(send_hextile_tile_, NAME)(VncState *vs, 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int x, int y, int w, int h, 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void *last_bg_, 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void *last_fg_, 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int *has_bg, int *has_fg) 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint8_t *row = vs->server.ds->data + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds); 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pixel_t *irow = (pixel_t *)row; 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int j, i; 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pixel_t *last_bg = (pixel_t *)last_bg_; 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pixel_t *last_fg = (pixel_t *)last_fg_; 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pixel_t bg = 0; 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pixel_t fg = 0; 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n_colors = 0; 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int bg_count = 0; 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fg_count = 0; 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int flags = 0; 275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint8_t data[(vs->clientds.pf.bytes_per_pixel + 2) * 16 * 16]; 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n_data = 0; 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n_subtiles = 0; 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (j = 0; j < h; j++) { 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; i < w; i++) { 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (n_colors) { 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bg = irow[i]; 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n_colors = 1; 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (irow[i] != bg) { 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fg = irow[i]; 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n_colors = 2; 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (irow[i] != bg && irow[i] != fg) { 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n_colors = 3; 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (irow[i] == bg) 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bg_count++; 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (irow[i] == fg) 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fg_count++; 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (n_colors > 2) 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner irow += ds_get_linesize(vs->ds) / sizeof(pixel_t); 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (n_colors > 1 && fg_count > bg_count) { 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pixel_t tmp = fg; 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fg = bg; 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bg = tmp; 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!*has_bg || *last_bg != bg) { 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flags |= 0x02; 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *has_bg = 1; 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *last_bg = bg; 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 752910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (n_colors < 3 && (!*has_fg || *last_fg != fg)) { 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flags |= 0x04; 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *has_fg = 1; 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *last_fg = fg; 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (n_colors) { 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n_data = 0; 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flags |= 0x08; 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project irow = (pixel_t *)row; 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (j = 0; j < h; j++) { 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int min_x = -1; 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; i < w; i++) { 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (irow[i] == fg) { 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (min_x == -1) 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project min_x = i; 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (min_x != -1) { 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1); 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n_data += 2; 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n_subtiles++; 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project min_x = -1; 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (min_x != -1) { 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1); 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n_data += 2; 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n_subtiles++; 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner irow += ds_get_linesize(vs->ds) / sizeof(pixel_t); 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flags |= 0x18; 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project irow = (pixel_t *)row; 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!*has_bg || *last_bg != bg) 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flags |= 0x02; 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (j = 0; j < h; j++) { 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int has_color = 0; 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int min_x = -1; 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pixel_t color = 0; /* shut up gcc */ 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; i < w; i++) { 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!has_color) { 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (irow[i] == bg) 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project color = irow[i]; 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project min_x = i; 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project has_color = 1; 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (irow[i] != color) { 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project has_color = 0; 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef GENERIC 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project vnc_convert_pixel(vs, data + n_data, color); 1355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n_data += vs->clientds.pf.bytes_per_pixel; 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(data + n_data, &color, sizeof(color)); 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n_data += sizeof(pixel_t); 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1); 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n_data += 2; 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n_subtiles++; 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project min_x = -1; 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (irow[i] != bg) { 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project color = irow[i]; 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project min_x = i; 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project has_color = 1; 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (has_color) { 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef GENERIC 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project vnc_convert_pixel(vs, data + n_data, color); 1555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n_data += vs->clientds.pf.bytes_per_pixel; 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(data + n_data, &color, sizeof(color)); 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n_data += sizeof(pixel_t); 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1); 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n_data += 2; 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n_subtiles++; 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner irow += ds_get_linesize(vs->ds) / sizeof(pixel_t); 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* A SubrectsColoured subtile invalidates the foreground color */ 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *has_fg = 0; 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (n_data > (w * h * sizeof(pixel_t))) { 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n_colors = 4; 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flags = 0x01; 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *has_bg = 0; 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* we really don't have to invalidate either the bg or fg 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project but we've lost the old values. oh well. */ 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (n_colors > 3) { 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flags = 0x01; 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *has_fg = 0; 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *has_bg = 0; 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n_colors = 4; 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project vnc_write_u8(vs, flags); 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (n_colors < 4) { 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (flags & 0x02) 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project vs->write_pixels(vs, last_bg, sizeof(pixel_t)); 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (flags & 0x04) 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project vs->write_pixels(vs, last_fg, sizeof(pixel_t)); 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (n_subtiles) { 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project vnc_write_u8(vs, n_subtiles); 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project vnc_write(vs, data, n_data); 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (j = 0; j < h; j++) { 2005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner vs->write_pixels(vs, row, w * ds_get_bytes_per_pixel(vs->ds)); 2015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner row += ds_get_linesize(vs->ds); 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NAME 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef pixel_t 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef CONCAT_I 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef CONCAT 210