[FFmpeg-devel] [PATCH] Add 1bpp, 8bpp, 15bpp, and 16bpp support to BMP encoder

Daniel Verkamp daniel
Wed Feb 18 17:01:29 CET 2009


On Wed, Feb 18, 2009 at 3:32 AM, Benoit Fouet <benoit.fouet at free.fr> wrote:
> Hi,
>
> On 02/18/2009 12:24 AM, Daniel Verkamp wrote:
>> On Tue, Feb 17, 2009 at 4:24 PM, Daniel Verkamp <daniel at drv.nu> wrote:
>>> Hi,
>>>
>>> $subject
>>>
>>> Thanks,
>>> -- Daniel Verkamp
>>>
>>
>> New patch - removed trailing whitespace.
>
>> From 33558a7b67052bbe7008562abde5c445f7761149 Mon Sep 17 00:00:00 2001
>> From: Daniel Verkamp <daniel at drv.nu>
>> Date: Tue, 17 Feb 2009 16:21:58 -0600
>> Subject: [PATCH] Add 1bpp, 8bpp, 15bpp, and 16bpp support to BMP encoder
>>
>> ---
>>  libavcodec/bmpenc.c |   74
> ++++++++++++++++++++++++++++++++++++++++++--------
>>  1 files changed, 62 insertions(+), 12 deletions(-)
>>
>> diff --git a/libavcodec/bmpenc.c b/libavcodec/bmpenc.c
>> index a54355c..6431b02 100644
>> --- a/libavcodec/bmpenc.c
>> +++ b/libavcodec/bmpenc.c
>> @@ -23,6 +24,9 @@
>>  #include "bytestream.h"
>>  #include "bmp.h"
>>
>> +static const uint32_t monoblack_pal[] = { 0x000000, 0xFFFFFF };
>> +static const uint32_t rgb565_masks[]  = { 0xF800, 0x07E0, 0x001F };
>> +
>>  static av_cold int bmp_encode_init(AVCodecContext *avctx){
>>      BMPContext *s = avctx->priv_data;
>>
>> @@ -36,20 +40,53 @@ static int bmp_encode_frame(AVCodecContext *avctx,
> unsigned char *buf, int buf_s
>>      BMPContext *s = avctx->priv_data;
>>      AVFrame *pict = data;
>>      AVFrame * const p= (AVFrame*)&s->picture;
>> -    int n_bytes_image, n_bytes_per_row, n_bytes, i, n, hsize;
>> +    int n_bytes_image, n_bytes_per_row, n_bytes, i, j, hsize;
>
> the cosmetic part (renaming n => j) should not be part of that patch
>

Well, it's not really a rename, as the original n was used for
something else, but I can use n instead of j if desired.

>> @@ -65,22 +102,30 @@ static int bmp_encode_frame(AVCodecContext
> *avctx, unsigned char *buf, int buf_s
>>      bytestream_put_le32(&buf, avctx->width);          //
> BITMAPINFOHEADER.biWidth
>>      bytestream_put_le32(&buf, avctx->height);         //
> BITMAPINFOHEADER.biHeight
>>      bytestream_put_le16(&buf, 1);                     //
> BITMAPINFOHEADER.biPlanes
>> -    bytestream_put_le16(&buf, 24);                    //
> BITMAPINFOHEADER.biBitCount
>> -    bytestream_put_le32(&buf, BMP_RGB);               //
> BITMAPINFOHEADER.biCompression
>> +    bytestream_put_le16(&buf, bit_count);             //
> BITMAPINFOHEADER.biBitCount
>> +    bytestream_put_le32(&buf, compression);           //
> BITMAPINFOHEADER.biCompression
>>      bytestream_put_le32(&buf, n_bytes_image);         //
> BITMAPINFOHEADER.biSizeImage
>>      bytestream_put_le32(&buf, 0);                     //
> BITMAPINFOHEADER.biXPelsPerMeter
>>      bytestream_put_le32(&buf, 0);                     //
> BITMAPINFOHEADER.biYPelsPerMeter
>>      bytestream_put_le32(&buf, 0);                     //
> BITMAPINFOHEADER.biClrUsed
>>      bytestream_put_le32(&buf, 0);                     //
> BITMAPINFOHEADER.biClrImportant
>> +    for (i = 0; i < pal_entries; i++)
>> +        bytestream_put_le32(&buf, pal[i]);
>>      // BMP files are bottom-to-top so we start from the end...
>>      ptr = p->data[0] + (avctx->height - 1) * p->linesize[0];
>>      buf = buf0 + hsize;
>>      for(i = 0; i < avctx->height; i++) {
>> -        n = 3*avctx->width;
>> -        memcpy(buf, ptr, n);
>> -        buf += n;
>> -        memset(buf, 0, n_bytes_per_row-n);
>> -        buf += n_bytes_per_row-n;
>> +        if (bit_count == 16) {
>> +            const uint16_t *src = (const uint16_t *) ptr;
>> +            uint16_t *dst = (uint16_t *) buf;
>> +            for(j = 0; j < avctx->width; j++)
>> +                AV_WL16(dst + j, src[j]);
>> +        } else {
>> +            memcpy(buf, ptr, n_bytes_per_row);
>> +        }
>
> can't the first one be done with a memcpy too ?

I don't think so, as PIX_FMT_RGB555/565 are documented as being in
native byte ordering, but I could be wrong...  I don't have any
big-endian machines to test on.

>
>> +        buf += n_bytes_per_row;
>> +        memset(buf, 0, pad_bytes_per_row);
>> +        buf += pad_bytes_per_row;
>>          ptr -= p->linesize[0]; // ... and go back
>>      }
>>      return n_bytes;
>
> Ben
>

Thanks,
-- Daniel Verkamp




More information about the ffmpeg-devel mailing list