简体   繁体   中英

How to convert from AV_PIX_FMT_BGRA to PIX_FMT_PAL8?

I'm having a hard time converting my images from AV_PIX_FMT_BGRA to PIX_FMT_PAL8 . Unfortunately sws_getCachedContext doesn't support the conversion to PIX_FMT_PAL8 .

What I'm trying to do is convert my images into a GIF video with higher quality output. It seems that PIX_FMT_PAL8 could potentially provide the higher quality output I'm looking for.

According to this documentation I need to palettize the pixel data, but I have no clue how to do that.

When the pixel format is palettized RGB ( PIX_FMT_PAL8 ), the palettized image data is stored in AVFrame.data[0] . The palette is transported in AVFrame.data[1] , is 1024 bytes long (256 4-byte entries) and is formatted the same as in PIX_FMT_RGB32 described above (ie, it is also endian-specific). Note also that the individual RGB palette components stored in AVFrame.data[1] should be in the range 0..255. This is important as many custom PAL8 video codecs that were designed to run on the IBM VGA graphics adapter use 6-bit palette components.

Any help or direction would be appreciated.

The code below is adapted from my own export-to-ARGB/RGB(A) code. I haven't tested it, but the main idea should be clear enough.

The code below was modified for making the colour conversion more readable, there's probably a faster way to do this.

uint32_t* pal8_to_bgra(AVPicture* pict, int width, int height)
{
    size_t size = width * height * 4; /* times 4 because 4 bytes per pixel */
    uint32_t colours[255];
    uint32_t *buff = NULL;

    buff = malloc(size);
    if (buff == NULL) {
        fprintf(stderr,
                "Error allocating memory for subtitle bitmap.\n");
        return NULL;
    }

    for (int i = 0; i < 256; ++i) {
        /* Colour conversion. */
        int idx = i * 4; /* again, 4 bytes per pixel */
        uint8_t r = pict->data[1][idx],
                g = pict->data[1][idx + 1],
                b = pict->data[1][idx + 2],
                a = pict->data[1][idx + 3];
        colours[i] = (b << 24) | (g << 16) | (r << 8) | a;
    }

    for (int y = 0; y < rect->h; ++y) {
        for (int x = 0; x < rect->w; ++x) {
            /* 1 byte per pixel */
            int coordinate = x + y * pict->linesize[0];
            /* 32bpp color table */
            int idx = pict->data[0][coordinate];
            buff[x + (y * rect->w)] = colours[idx];
        }
    }

    return buff;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM