Browse code

BMP encoder by Michel Bardiaux, mbardiaux mediaxim be

Originally committed as revision 7824 to svn://svn.ffmpeg.org/ffmpeg/trunk

Diego Biurrun authored on 2007/02/06 00:05:29
Showing 5 changed files
... ...
@@ -69,6 +69,7 @@ version <next>
69 69
 - Musepack decoder
70 70
 - Flash Screen Video encoder
71 71
 - Theora encoding via libtheora
72
+- BMP encoder
72 73
 
73 74
 version 0.4.9-pre1:
74 75
 
... ...
@@ -55,6 +55,7 @@ OBJS-$(CONFIG_ASV2_DECODER)            += asv1.o
55 55
 OBJS-$(CONFIG_ASV2_ENCODER)            += asv1.o
56 56
 OBJS-$(CONFIG_AVS_DECODER)             += avs.o
57 57
 OBJS-$(CONFIG_BMP_DECODER)             += bmp.o
58
+OBJS-$(CONFIG_BMP_ENCODER)             += bmpenc.o
58 59
 OBJS-$(CONFIG_CAVS_DECODER)            += cavs.o cavsdsp.o
59 60
 OBJS-$(CONFIG_CINEPAK_DECODER)         += cinepak.o
60 61
 OBJS-$(CONFIG_CLJR_DECODER)            += cljr.o
... ...
@@ -54,7 +54,7 @@ void avcodec_register_all(void)
54 54
     REGISTER_ENCDEC (ASV1, asv1);
55 55
     REGISTER_ENCDEC (ASV2, asv2);
56 56
     REGISTER_DECODER(AVS, avs);
57
-    REGISTER_DECODER(BMP, bmp);
57
+    REGISTER_ENCDEC (BMP, bmp);
58 58
     REGISTER_DECODER(CAVS, cavs);
59 59
     REGISTER_DECODER(CINEPAK, cinepak);
60 60
     REGISTER_DECODER(CLJR, cljr);
... ...
@@ -37,8 +37,8 @@ extern "C" {
37 37
 #define AV_STRINGIFY(s)         AV_TOSTRING(s)
38 38
 #define AV_TOSTRING(s) #s
39 39
 
40
-#define LIBAVCODEC_VERSION_INT  ((51<<16)+(30<<8)+0)
41
-#define LIBAVCODEC_VERSION      51.30.0
40
+#define LIBAVCODEC_VERSION_INT  ((51<<16)+(31<<8)+0)
41
+#define LIBAVCODEC_VERSION      51.31.0
42 42
 #define LIBAVCODEC_BUILD        LIBAVCODEC_VERSION_INT
43 43
 
44 44
 #define LIBAVCODEC_IDENT        "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION)
... ...
@@ -2148,6 +2148,7 @@ extern AVCodec amr_nb_encoder;
2148 2148
 extern AVCodec amr_wb_encoder;
2149 2149
 extern AVCodec asv1_encoder;
2150 2150
 extern AVCodec asv2_encoder;
2151
+extern AVCodec bmp_encoder;
2151 2152
 extern AVCodec dvvideo_encoder;
2152 2153
 extern AVCodec faac_encoder;
2153 2154
 extern AVCodec ffv1_encoder;
2154 2155
new file mode 100644
... ...
@@ -0,0 +1,98 @@
0
+/*
1
+ * BMP image format encoder
2
+ * Copyright (c) 2006, 2007 Michel Bardiaux
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+#include "avcodec.h"
22
+#include "bytestream.h"
23
+#include "bmp.h"
24
+
25
+static int bmp_encode_init(AVCodecContext *avctx){
26
+    BMPContext *s = avctx->priv_data;
27
+
28
+    avcodec_get_frame_defaults((AVFrame*)&s->picture);
29
+    avctx->coded_frame = (AVFrame*)&s->picture;
30
+
31
+    return 0;
32
+}
33
+
34
+static int bmp_encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
35
+    BMPContext *s = avctx->priv_data;
36
+    AVFrame *pict = data;
37
+    AVFrame * const p= (AVFrame*)&s->picture;
38
+    int n_bytes_image, n_bytes_per_row, n_bytes, i, n, hsize;
39
+    uint8_t *ptr;
40
+    unsigned char* buf0 = buf;
41
+    *p = *pict;
42
+    p->pict_type= FF_I_TYPE;
43
+    p->key_frame= 1;
44
+    n_bytes_per_row = (avctx->width*3 + 3) & ~3;
45
+    n_bytes_image = avctx->height*n_bytes_per_row;
46
+
47
+    // STRUCTURE.field refer to the MSVC documentation for BITMAPFILEHEADER
48
+    // and related pages.
49
+#define SIZE_BITMAPFILEHEADER 14
50
+#define SIZE_BITMAPINFOHEADER 40
51
+    hsize = SIZE_BITMAPFILEHEADER + SIZE_BITMAPINFOHEADER;
52
+    n_bytes = n_bytes_image + hsize;
53
+    if(n_bytes>buf_size) {
54
+        av_log(avctx, AV_LOG_ERROR, "buf size too small (need %d, got %d)\n", n_bytes, buf_size);
55
+        return -1;
56
+    }
57
+    bytestream_put_byte(&buf, 'B');                   // BITMAPFILEHEADER.bfType
58
+    bytestream_put_byte(&buf, 'M');                   // do.
59
+    bytestream_put_le32(&buf, n_bytes);               // BITMAPFILEHEADER.bfSize
60
+    bytestream_put_le16(&buf, 0);                     // BITMAPFILEHEADER.bfReserved1
61
+    bytestream_put_le16(&buf, 0);                     // BITMAPFILEHEADER.bfReserved2
62
+    bytestream_put_le32(&buf, hsize);                 // BITMAPFILEHEADER.bfOffBits
63
+    bytestream_put_le32(&buf, SIZE_BITMAPINFOHEADER); // BITMAPINFOHEADER.biSize
64
+    bytestream_put_le32(&buf, avctx->width);          // BITMAPINFOHEADER.biWidth
65
+    bytestream_put_le32(&buf, avctx->height);         // BITMAPINFOHEADER.biHeight
66
+    bytestream_put_le16(&buf, 1);                     // BITMAPINFOHEADER.biPlanes
67
+    bytestream_put_le16(&buf, 24);                    // BITMAPINFOHEADER.biBitCount
68
+    bytestream_put_le32(&buf, BMP_RGB);               // BITMAPINFOHEADER.biCompression
69
+    bytestream_put_le32(&buf, n_bytes_image);         // BITMAPINFOHEADER.biSizeImage
70
+    bytestream_put_le32(&buf, 0);                     // BITMAPINFOHEADER.biXPelsPerMeter
71
+    bytestream_put_le32(&buf, 0);                     // BITMAPINFOHEADER.biYPelsPerMeter
72
+    bytestream_put_le32(&buf, 0);                     // BITMAPINFOHEADER.biClrUsed
73
+    bytestream_put_le32(&buf, 0);                     // BITMAPINFOHEADER.biClrImportant
74
+    // BMP files are bottom-to-top so we start from the end...
75
+    ptr = p->data[0] + (avctx->height - 1) * p->linesize[0];
76
+    buf = buf0 + hsize;
77
+    for(i = 0; i < avctx->height; i++) {
78
+        n = 3*avctx->width;
79
+        memcpy(buf, ptr, n);
80
+        buf += n;
81
+        memset(buf, 0, n_bytes_per_row-n);
82
+        buf += n_bytes_per_row-n;
83
+        ptr -= p->linesize[0]; // ... and go back
84
+    }
85
+    return n_bytes;
86
+}
87
+
88
+AVCodec bmp_encoder = {
89
+    "bmp",
90
+    CODEC_TYPE_VIDEO,
91
+    CODEC_ID_BMP,
92
+    sizeof(BMPContext),
93
+    bmp_encode_init,
94
+    bmp_encode_frame,
95
+    NULL, //encode_end,
96
+    .pix_fmts= (enum PixelFormat[]){PIX_FMT_BGR24, -1},
97
+};