Неправильная цветовая кодировка на сервере удаленного фреймбуфера

Я работаю над простой реализацией сервера RFB с использованием пиксельной кодировки "RAW". Я использую TightVNC в качестве настольного клиента. У меня есть код, работающий до точки, где клиент может запросить весь "рабочий стол", который составляет 640x480 пикселей. Мой тестовый шаблон правильно рисует в отношении формы, но цвета неправильные.

Я пытаюсь использовать 8 бит на пиксель: три красных, три зеленых и два синих в кодировке RRRGGGBB в каждом байте.

Мой пакет ServerInit содержит эту спецификацию кодирования пикселей...

//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

Вся структура определяется так:

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;

Теперь, если я заполню свой рабочий стол 0xe0 (двоичный 111 000 00) тогда я ожидаю, что это будет интерпретировано как чисто ярко-красный. Но он выглядит как светло-голубой цвет (как будто 8 отдельных битов были интерпретированы задом наперед!). Форма моего тестового шаблона правильная, так как я рисую несколько белых пикселей в верхнем углу (белый - бинарный 111 111 11 очевидно).

Я этого не понимаю. Я считаю, что я следовал алгоритму и кодированию, как описано в спецификации RFB... http://vncdotool.readthedocs.org/en/latest/rfbproto.html

Что я делаю неправильно?

1 ответ

Wireshark на помощь! Решил это.

Оказывается, клиент отправлял SetPixelFormat В запросе, который я не видел, код игнорировал его, и, очевидно, сервер должен выполнить запрос, изменив его формат вывода.

Исправление состояло в том, чтобы просто дать клиенту то, что он хотел с самого начала, жестко закодировав значения, которые запрашивал клиент. В этот момент клиент никогда не отправляет этот запрос снова, потому что он доволен тем, что сервер теперь использует с самого начала.

Другие вопросы по тегам