00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "avcodec.h"
00023 #include "bytestream.h"
00024 #include "bmp.h"
00025
00026 static av_cold int bmp_encode_init(AVCodecContext *avctx){
00027 BMPContext *s = avctx->priv_data;
00028
00029 avcodec_get_frame_defaults((AVFrame*)&s->picture);
00030 avctx->coded_frame = (AVFrame*)&s->picture;
00031
00032 return 0;
00033 }
00034
00035 static int bmp_encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
00036 BMPContext *s = avctx->priv_data;
00037 AVFrame *pict = data;
00038 AVFrame * const p= (AVFrame*)&s->picture;
00039 int n_bytes_image, n_bytes_per_row, n_bytes, i, n, hsize;
00040 uint8_t *ptr;
00041 unsigned char* buf0 = buf;
00042 *p = *pict;
00043 p->pict_type= FF_I_TYPE;
00044 p->key_frame= 1;
00045 n_bytes_per_row = (avctx->width*3 + 3) & ~3;
00046 n_bytes_image = avctx->height*n_bytes_per_row;
00047
00048
00049
00050 #define SIZE_BITMAPFILEHEADER 14
00051 #define SIZE_BITMAPINFOHEADER 40
00052 hsize = SIZE_BITMAPFILEHEADER + SIZE_BITMAPINFOHEADER;
00053 n_bytes = n_bytes_image + hsize;
00054 if(n_bytes>buf_size) {
00055 av_log(avctx, AV_LOG_ERROR, "buf size too small (need %d, got %d)\n", n_bytes, buf_size);
00056 return -1;
00057 }
00058 bytestream_put_byte(&buf, 'B');
00059 bytestream_put_byte(&buf, 'M');
00060 bytestream_put_le32(&buf, n_bytes);
00061 bytestream_put_le16(&buf, 0);
00062 bytestream_put_le16(&buf, 0);
00063 bytestream_put_le32(&buf, hsize);
00064 bytestream_put_le32(&buf, SIZE_BITMAPINFOHEADER);
00065 bytestream_put_le32(&buf, avctx->width);
00066 bytestream_put_le32(&buf, avctx->height);
00067 bytestream_put_le16(&buf, 1);
00068 bytestream_put_le16(&buf, 24);
00069 bytestream_put_le32(&buf, BMP_RGB);
00070 bytestream_put_le32(&buf, n_bytes_image);
00071 bytestream_put_le32(&buf, 0);
00072 bytestream_put_le32(&buf, 0);
00073 bytestream_put_le32(&buf, 0);
00074 bytestream_put_le32(&buf, 0);
00075
00076 ptr = p->data[0] + (avctx->height - 1) * p->linesize[0];
00077 buf = buf0 + hsize;
00078 for(i = 0; i < avctx->height; i++) {
00079 n = 3*avctx->width;
00080 memcpy(buf, ptr, n);
00081 buf += n;
00082 memset(buf, 0, n_bytes_per_row-n);
00083 buf += n_bytes_per_row-n;
00084 ptr -= p->linesize[0];
00085 }
00086 return n_bytes;
00087 }
00088
00089 AVCodec bmp_encoder = {
00090 "bmp",
00091 CODEC_TYPE_VIDEO,
00092 CODEC_ID_BMP,
00093 sizeof(BMPContext),
00094 bmp_encode_init,
00095 bmp_encode_frame,
00096 NULL,
00097 .pix_fmts= (enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_NONE},
00098 .long_name = NULL_IF_CONFIG_SMALL("BMP image"),
00099 };