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

Benoit Fouet benoit.fouet
Wed Feb 18 10:32:46 CET 2009


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

> @@ -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 ?

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





More information about the ffmpeg-devel mailing list