Неправильная цветовая кодировка на сервере удаленного фреймбуфера
Я работаю над простой реализацией сервера 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
В запросе, который я не видел, код игнорировал его, и, очевидно, сервер должен выполнить запрос, изменив его формат вывода.
Исправление состояло в том, чтобы просто дать клиенту то, что он хотел с самого начала, жестко закодировав значения, которые запрашивал клиент. В этот момент клиент никогда не отправляет этот запрос снова, потому что он доволен тем, что сервер теперь использует с самого начала.