File:  [Qemu by Fabrice Bellard] / qemu / vnchextile.h
Revision 1.1: download - view: text, annotated - select for diffs
Tue Apr 24 16:40:52 2018 UTC (18 months, 2 weeks ago) by root
CVS tags: MAIN, HEAD
Initial revision

    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: 
    5: static void CONCAT(send_hextile_tile_, BPP)(VncState *vs,
    6: 					    int x, int y, int w, int h,
    7: 					    pixel_t *last_bg, pixel_t *last_fg,
    8: 					    int *has_bg, int *has_fg)
    9: {
   10:     char *row = (vs->ds->data + y * vs->ds->linesize + x * vs->depth);
   11:     pixel_t *irow = (pixel_t *)row;
   12:     int j, i;
   13:     pixel_t bg = 0;
   14:     pixel_t fg = 0;
   15:     int n_colors = 0;
   16:     int bg_count = 0;
   17:     int fg_count = 0;
   18:     int flags = 0;
   19:     uint8_t data[(sizeof(pixel_t) + 2) * 16 * 16];
   20:     int n_data = 0;
   21:     int n_subtiles = 0;
   22: 
   23:     for (j = 0; j < h; j++) {
   24: 	for (i = 0; i < w; i++) {
   25: 	    switch (n_colors) {
   26: 	    case 0:
   27: 		bg = irow[i];
   28: 		n_colors = 1;
   29: 		break;
   30: 	    case 1:
   31: 		if (irow[i] != bg) {
   32: 		    fg = irow[i];
   33: 		    n_colors = 2;
   34: 		}
   35: 		break;
   36: 	    case 2:
   37: 		if (irow[i] != bg && irow[i] != fg) {
   38: 		    n_colors = 3;
   39: 		} else {
   40: 		    if (irow[i] == bg)
   41: 			bg_count++;
   42: 		    else if (irow[i] == fg)
   43: 			fg_count++;
   44: 		}
   45: 		break;
   46: 	    default:
   47: 		break;
   48: 	    }
   49: 	}
   50: 	if (n_colors > 2)
   51: 	    break;
   52: 	irow += vs->ds->linesize / sizeof(pixel_t);
   53:     }
   54: 
   55:     if (n_colors > 1 && fg_count > bg_count) {
   56: 	pixel_t tmp = fg;
   57: 	fg = bg;
   58: 	bg = tmp;
   59:     }
   60: 
   61:     if (!*has_bg || *last_bg != bg) {
   62: 	flags |= 0x02;
   63: 	*has_bg = 1;
   64: 	*last_bg = bg;
   65:     }
   66: 
   67:     if (!*has_fg || *last_fg != fg) {
   68: 	flags |= 0x04;
   69: 	*has_fg = 1;
   70: 	*last_fg = fg;
   71:     }
   72: 
   73:     switch (n_colors) {
   74:     case 1:
   75: 	n_data = 0;
   76: 	break;
   77:     case 2:
   78: 	flags |= 0x08;
   79: 
   80: 	irow = (pixel_t *)row;
   81: 	
   82: 	for (j = 0; j < h; j++) {
   83: 	    int min_x = -1;
   84: 	    for (i = 0; i < w; i++) {
   85: 		if (irow[i] == fg) {
   86: 		    if (min_x == -1)
   87: 			min_x = i;
   88: 		} else if (min_x != -1) {
   89: 		    hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
   90: 		    n_data += 2;
   91: 		    n_subtiles++;
   92: 		    min_x = -1;
   93: 		}
   94: 	    }
   95: 	    if (min_x != -1) {
   96: 		hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
   97: 		n_data += 2;
   98: 		n_subtiles++;
   99: 	    }
  100: 	    irow += vs->ds->linesize / sizeof(pixel_t);
  101: 	}
  102: 	break;
  103:     case 3:
  104: 	flags |= 0x18;
  105: 
  106: 	irow = (pixel_t *)row;
  107: 
  108: 	if (!*has_bg || *last_bg != bg)
  109: 	    flags |= 0x02;
  110: 
  111: 	for (j = 0; j < h; j++) {
  112: 	    int has_color = 0;
  113: 	    int min_x = -1;
  114: 	    pixel_t color;
  115: 
  116: 	    for (i = 0; i < w; i++) {
  117: 		if (!has_color) {
  118: 		    if (irow[i] == bg)
  119: 			continue;
  120: 		    color = irow[i];
  121: 		    min_x = i;
  122: 		    has_color = 1;
  123: 		} else if (irow[i] != color) {
  124: 		    has_color = 0;
  125: 
  126: 		    memcpy(data + n_data, &color, sizeof(color));
  127: 		    hextile_enc_cord(data + n_data + sizeof(pixel_t), min_x, j, i - min_x, 1);
  128: 		    n_data += 2 + sizeof(pixel_t);
  129: 		    n_subtiles++;
  130: 
  131: 		    min_x = -1;
  132: 		    if (irow[i] != bg) {
  133: 			color = irow[i];
  134: 			min_x = i;
  135: 			has_color = 1;
  136: 		    }
  137: 		}
  138: 	    }
  139: 	    if (has_color) {
  140: 		memcpy(data + n_data, &color, sizeof(color));
  141: 		hextile_enc_cord(data + n_data + sizeof(pixel_t), min_x, j, i - min_x, 1);
  142: 		n_data += 2 + sizeof(pixel_t);
  143: 		n_subtiles++;
  144: 	    }
  145: 	    irow += vs->ds->linesize / sizeof(pixel_t);
  146: 	}
  147: 
  148: 	/* A SubrectsColoured subtile invalidates the foreground color */
  149: 	*has_fg = 0;
  150: 	if (n_data > (w * h * sizeof(pixel_t))) {
  151: 	    n_colors = 4;
  152: 	    flags = 0x01;
  153: 	    *has_bg = 0;
  154: 
  155: 	    /* we really don't have to invalidate either the bg or fg
  156: 	       but we've lost the old values.  oh well. */
  157: 	}
  158:     default:
  159: 	break;
  160:     }
  161: 
  162:     if (n_colors > 3) {
  163: 	flags = 0x01;
  164: 	*has_fg = 0;
  165: 	*has_bg = 0;
  166: 	n_colors = 4;
  167:     }
  168: 
  169:     vnc_write_u8(vs, flags);
  170:     if (n_colors < 4) {
  171: 	if (flags & 0x02)
  172: 	    vnc_write(vs, last_bg, sizeof(pixel_t));
  173: 	if (flags & 0x04)
  174: 	    vnc_write(vs, last_fg, sizeof(pixel_t));
  175: 	if (n_subtiles) {
  176: 	    vnc_write_u8(vs, n_subtiles);
  177: 	    vnc_write(vs, data, n_data);
  178: 	}
  179:     } else {
  180: 	for (j = 0; j < h; j++) {
  181: 	    vnc_write(vs, row, w * vs->depth);
  182: 	    row += vs->ds->linesize;
  183: 	}
  184:     }
  185: }
  186: 
  187: #undef pixel_t
  188: #undef CONCAT_I
  189: #undef CONCAT

unix.superglobalmegacorp.com