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

Я пишу крошечную библиотеку для взаимодействия с абстракцией фреймбуфера Linux. Все мои видеокарты используют один и тот же пиксельный формат (один октет на канал, четыре канала, порядок BGRA), поэтому пока библиотека просто принимает этот формат. Однако API кадрового буфера предоставляет данные в формате пикселей, которые я должен использовать, если хочу, чтобы библиотека работала на любом кадровом буфере Linux. Вам не нужно знать, как работает фреймбуфер, чтобы ответить на этот вопрос (я надеюсь), просто какая-то мелочь, с которой я не разбираюсь. Вот информация о формате пикселей, представленная в моих заголовках:

/* Interpretation of offset for color fields: All offsets are from the right,
 * inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you
 * can use the offset as right argument to <<). A pixel afterwards is a bit
 * stream and is written to video memory as that unmodified.
 *
 * For pseudocolor: offset and length should be the same for all color
 * components. Offset specifies the position of the least significant bit
 * of the pallette index in a pixel value. Length indicates the number
 * of available palette entries (i.e. # of entries = 1 << length).
 */
struct fb_bitfield {
        __u32 offset;                   /* beginning of bitfield        */
        __u32 length;                   /* length of bitfield           */
        __u32 msb_right;                /* != 0 : Most significant bit is */ 
                                        /* right */
};

/* snip */

struct fb_var_screeninfo {
    /* snip */

        __u32 bits_per_pixel;           /* guess what                   */
        __u32 grayscale;                /* 0 = color, 1 = grayscale,    */
                                        /* >1 = FOURCC                  */
        struct fb_bitfield red;         /* bitfield in fb mem if true color, */
        struct fb_bitfield green;       /* else only length is significant */
        struct fb_bitfield blue;
        struct fb_bitfield transp;      /* transparency                 */      

        __u32 nonstd;                   /* != 0 Non standard pixel format */

    /* snip */
};

Мне нужно записать пиксель, отформатированный с вышеуказанной информацией, в массив символов из четырех символов (R, G, B и A). Неправильные попытки сделать это выглядят так:

long pxl = 0;
/* downsample each channel to the length (assuming its less than 8 bits) */
/* with a right-shift, then left shift it over into place */
/* haven't done anything with fb_bitfield.msb_right */
pxl |= (r >> (8 - vinfo.red.length)) << vinfo.red.offset;
pxl |= (g >> (8 - vinfo.green.length)) << vinfo.green.offset;
pxl |= (b >> (8 - vinfo.blue.length)) << vinfo.blue.offset;
pxl |= (a >> (8 - vinfo.transp.length)) << vinfo.transp.offset;
fb[xy2off(x, y)] = /* umm... */;
/* little endian, big endian? Can I just assign here? */

xy2off преобразует координаты в индекс. fb является указателем на кадровый буфер (отображение памяти).

Может кто-нибудь указать мне правильное направление для преобразования и назначения этих пикселей?

1 ответ

Решение

Уважаемые, вероятно, несуществующие люди, которые ищут ответ на этот вопрос: вот мой хакерский код, который, похоже, сейчас работает:

пустой пиксель (int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
    Int I;
    длинный pxl = 0;
    pxl |= (r >> (8 - vinfo.red.length)) << vinfo.red.offset;
    pxl |= (g >> (8 - vinfo.green.length)) << vinfo.green.offset;
    pxl |= (b >> (8 - vinfo.blue.length)) << vinfo.blue.offset;
    pxl |= (a >> (8 - vinfo.transp.length)) << vinfo.transp.offset;
    для (i = 0; i 

Отсутствует обработка порядка байтов, работа с msb_right или какая-либо оптимизация.

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