Re: [gtk-vnc-devel] Fix pixel shift for BGR format servers
- From: Anthony Liguori <anthony codemonkey ws>
- To: "Daniel P. Berrange" <berrange redhat com>
- Cc: gtk-vnc-devel <gtk-vnc-devel lists sourceforge net>
- Subject: Re: [gtk-vnc-devel] Fix pixel shift for BGR format servers
- Date: Tue, 10 Jul 2007 16:31:31 -0500
Daniel P. Berrange wrote:
The code which currently calculates the pixel shift for converting data
from remote to local encoding is assuming the server is in RGB format
pixels. If I run a server in BGR format, then the colours are rather
messed up. I've attached a patch which tries to correct it - although its
not perfect because now, the code assume either RGB, or BGR - is it possible
for a server to use GRB, or GBR ?!?! If not then this may be sufficient.
I'm also not entirely convinced this is correct wrt to local server
format, eg if your local desktop ran in BGR instead of RGB. I don't have
any system I can make run in BGR locally though, so can't test.
BTW, for testing I was running a server with
vncserver -geometry 1024x800 -depth 16 -pixelformat bgr565
And another with
vncserver -geometry 1024x800 -depth 16 -pixelformat rgb565
With this patch, both now work.
VNC servers and clients are notoriously bad at respecting
SetPixelFormat(). While I don't think we properly support the
big_endian_flag, I do think we're doing right thing with the
mask/shifts. Are you sure that RealVNC isn't screwing up here? Your
patch looks a big magical to me.
Is the current code really assuming RGB? It just does whatever the
current shift/masks support.
Regards,
Anthony Liguori
Dan.
------------------------------------------------------------------------
diff -r 8d2ec85be8c3 src/gvnc.c
--- a/src/gvnc.c Tue Jul 10 13:34:34 2007 -0400
+++ b/src/gvnc.c Tue Jul 10 17:10:57 2007 -0400
@@ -127,7 +127,7 @@ enum {
};
-#define DEBUG 0
+#define DEBUG 1
#if DEBUG
#define GVNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
@@ -543,7 +543,7 @@ static void gvnc_read_pixel_format(struc
fmt->big_endian_flag = gvnc_read_u8(gvnc);
fmt->true_color_flag = gvnc_read_u8(gvnc);
- GVNC_DEBUG("Pixel format BPP: %d, Depth: %d, Endian: %d, True color: %d\n",
+ GVNC_DEBUG("Read Pixel format BPP: %d, Depth: %d, Endian: %d, True color: %d\n",
fmt->bits_per_pixel, fmt->depth, fmt->big_endian_flag, fmt->true_color_flag);
fmt->red_max = gvnc_read_u16(gvnc);
@@ -554,6 +554,11 @@ static void gvnc_read_pixel_format(struc
fmt->green_shift = gvnc_read_u8(gvnc);
fmt->blue_shift = gvnc_read_u8(gvnc);
+ GVNC_DEBUG("Pixel max: R: %d, G: %d, B:%d\n",
+ fmt->red_max, fmt->green_max, fmt->blue_max);
+ GVNC_DEBUG("Pixel shift: R: %d, G: %d, B:%d\n",
+ fmt->red_shift, fmt->green_shift, fmt->blue_shift);
+
gvnc_read(gvnc, pad, 3);
}
@@ -571,6 +576,9 @@ gboolean gvnc_set_pixel_format(struct gv
gvnc_write_u8(gvnc, 0);
gvnc_write(gvnc, pad, 3);
+
+ GVNC_DEBUG("Write Pixel format BPP: %d, Depth: %d, Endian: %d, True color: %d\n",
+ fmt->bits_per_pixel, fmt->depth, fmt->big_endian_flag, fmt->true_color_flag);
gvnc_write_u8(gvnc, fmt->bits_per_pixel);
gvnc_write_u8(gvnc, fmt->depth);
@@ -584,6 +592,11 @@ gboolean gvnc_set_pixel_format(struct gv
gvnc_write_u8(gvnc, fmt->red_shift);
gvnc_write_u8(gvnc, fmt->green_shift);
gvnc_write_u8(gvnc, fmt->blue_shift);
+
+ GVNC_DEBUG("Pixel max: R: %d, G: %d, B:%d\n",
+ fmt->red_max, fmt->green_max, fmt->blue_max);
+ GVNC_DEBUG("Pixel shift: R: %d, G: %d, B:%d\n",
+ fmt->red_shift, fmt->green_shift, fmt->blue_shift);
gvnc_write(gvnc, pad, 3);
gvnc_flush(gvnc);
@@ -1534,16 +1547,26 @@ gboolean gvnc_set_local(struct gvnc *gvn
if (depth == 32)
depth = 24;
- gvnc->rp = (gvnc->local.depth - gvnc->local.red_shift);
- gvnc->rp -= (depth - gvnc->fmt.red_shift);
- gvnc->gp = (gvnc->local.red_shift - gvnc->local.green_shift);
- gvnc->gp -= (gvnc->fmt.red_shift - gvnc->fmt.green_shift);
- gvnc->bp = (gvnc->local.green_shift - gvnc->local.blue_shift);
- gvnc->bp -= (gvnc->fmt.green_shift - gvnc->fmt.blue_shift);
-
- gvnc->rp = gvnc->local.red_shift + gvnc->rp;
- gvnc->gp = gvnc->local.green_shift + gvnc->gp;
- gvnc->bp = gvnc->local.blue_shift + gvnc->bp;
+ GVNC_DEBUG("Depth local %d remote %d\n", gvnc->local.depth, depth);
+ if (gvnc->fmt.red_shift > gvnc->fmt.blue_shift) {
+ gvnc->rp = gvnc->local.depth;
+ gvnc->rp -= (depth - gvnc->fmt.red_shift);
+
+ gvnc->gp = gvnc->local.red_shift;
+ gvnc->gp -= (gvnc->fmt.red_shift - gvnc->fmt.green_shift);
+
+ gvnc->bp = gvnc->local.green_shift;
+ gvnc->bp -= (gvnc->fmt.green_shift - gvnc->fmt.blue_shift);
+ } else {
+ gvnc->rp = gvnc->local.depth;
+ gvnc->rp -= (gvnc->fmt.green_shift - gvnc->fmt.red_shift);
+
+ gvnc->gp = gvnc->local.red_shift;
+ gvnc->gp -= (gvnc->fmt.blue_shift - gvnc->fmt.green_shift);
+
+ gvnc->bp = gvnc->local.green_shift;
+ gvnc->bp -= (depth - gvnc->fmt.blue_shift);
+ }
gvnc->rm = gvnc->local.red_mask & gvnc->fmt.red_max;
gvnc->gm = gvnc->local.green_mask & gvnc->fmt.green_max;
------------------------------------------------------------------------
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
------------------------------------------------------------------------
_______________________________________________
Gtk-vnc-devel mailing list
Gtk-vnc-devel lists sourceforge net
https://lists.sourceforge.net/lists/listinfo/gtk-vnc-devel
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]