cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

vnc-enc-hextile-template.h (5916B)


      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
     10static 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 = vnc_server_fb_ptr(vd, x, y);
     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->client_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 += vnc_server_fb_stride(vd) / 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 += vnc_server_fb_stride(vd) / 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->client_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->client_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 += vnc_server_fb_stride(vd) / 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        break;
    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, last_bg, sizeof(pixel_t));
    194        if (flags & 0x04)
    195            vs->write_pixels(vs, 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, row, w * 4);
    203            row += vnc_server_fb_stride(vd);
    204        }
    205    }
    206}
    207
    208#undef NAME
    209#undef pixel_t
    210#undef CONCAT_I
    211#undef CONCAT