user5069935
user5069935

Reputation:

Incorrect color encoding in Remote Framebuffer server

I am working on a simple implementation of a RFB server using "RAW" pixel encoding. I am using TightVNC as my desktop client. I have the code working up to the point where the client is able to request the entire "desktop" which is 640x480 pixels. My test pattern is drawing correctly with regard to shape but the colors are wrong.

I'm trying to use 8 bits per pixel: three red, three green and two blue encoded as RRRGGGBB in each byte.

My ServerInit packet contains this pixel encoding specification...

//all of these 13 fields are unsigned chars...

si.pf.bits_per_pixel = 8;
si.pf.depth = 8;
si.pf.big_endian_flag = 0;
si.pf.true_colour_flag = 1;

si.pf.red_max_hi = 0;
si.pf.red_max_lo = 7;    // 3 bits
si.pf.green_max_hi = 0;
si.pf.green_max_lo = 7;  // 3 bits
si.pf.blue_max_hi = 0;
si.pf.blue_max_lo = 3;   // 2 bits

si.pf.red_shift = 5;     // >>>>>RRR
si.pf.green_shift = 2;   // >>RRRGGG
si.pf.blue_shift = 0;    // RRRGGGBB

//remaining fields are omitted

The entire structure is defined thus:

typedef struct
{
  uchar bits_per_pixel;
  uchar depth;
  uchar big_endian_flag;
  uchar true_colour_flag;

  uchar red_max_hi;
  uchar red_max_lo;
  uchar green_max_hi;
  uchar green_max_lo;
  uchar blue_max_hi;
  uchar blue_max_lo;

  uchar red_shift;
  uchar green_shift;
  uchar blue_shift;

  uchar padding0;
  uchar padding1;
  uchar padding2;
}tPixelFormat;

Now if I fill my desktop image with 0xe0 (binary 111 000 00) then I expect this to be interpreted as pure bright red. But it is appearing as a light blue color (as if the 8 individual bits were interpreted backwards!). The shape of my test pattern is correct as I am drawing a few white pixels in the top corner (white is binary 111 111 11 obviously).

I do not understand this. I believe I have followed the algorithm and encoding as it is described in the RFB specification... http://vncdotool.readthedocs.org/en/latest/rfbproto.html#serverinit

What am I doing wrong?

Upvotes: 0

Views: 199

Answers (1)

user5069935
user5069935

Reputation:

Wireshark to the rescue! Solved it.

It turns out that the client was sending a SetPixelFormat request that I hadn't seen, the code was ignoring it and apparently the server is mandated to honour the request by changing it's output format.

The fix was to simply give the client what it wanted right from the start by hardcoding the values that the client was asking for. At which point the client never sends that request again because it's happy with what the server is now dishing out from the beginning.

Upvotes: 1

Related Questions