2 * BMP image format encoder
3 * Copyright (c) 2006, 2007 Michel Bardiaux
4 * Copyright (c) 2009 Daniel Verkamp <daniel at drv.nu>
6 * This file is part of FFmpeg.
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "bytestream.h"
27 static const uint32_t monoblack_pal
[] = { 0x000000, 0xFFFFFF };
28 static const uint32_t rgb565_masks
[] = { 0xF800, 0x07E0, 0x001F };
30 static av_cold
int bmp_encode_init(AVCodecContext
*avctx
){
31 BMPContext
*s
= avctx
->priv_data
;
33 avcodec_get_frame_defaults((AVFrame
*)&s
->picture
);
34 avctx
->coded_frame
= (AVFrame
*)&s
->picture
;
39 static int bmp_encode_frame(AVCodecContext
*avctx
, unsigned char *buf
, int buf_size
, void *data
){
40 BMPContext
*s
= avctx
->priv_data
;
42 AVFrame
* const p
= (AVFrame
*)&s
->picture
;
43 int n_bytes_image
, n_bytes_per_row
, n_bytes
, i
, n
, hsize
;
44 const uint32_t *pal
= NULL
;
45 int pad_bytes_per_row
, bit_count
, pal_entries
= 0, compression
= BMP_RGB
;
47 unsigned char* buf0
= buf
;
49 p
->pict_type
= FF_I_TYPE
;
51 switch (avctx
->pix_fmt
) {
60 compression
= BMP_BITFIELDS
;
61 pal
= rgb565_masks
; // abuse pal to hold color masks
66 case PIX_FMT_RGB4_BYTE
:
67 case PIX_FMT_BGR4_BYTE
:
71 pal
= (uint32_t *)p
->data
[1];
73 case PIX_FMT_MONOBLACK
:
80 if (pal
&& !pal_entries
) pal_entries
= 1 << bit_count
;
81 n_bytes_per_row
= ((int64_t)avctx
->width
* (int64_t)bit_count
+ 7LL) >> 3LL;
82 pad_bytes_per_row
= (4 - n_bytes_per_row
) & 3;
83 n_bytes_image
= avctx
->height
* (n_bytes_per_row
+ pad_bytes_per_row
);
85 // STRUCTURE.field refer to the MSVC documentation for BITMAPFILEHEADER
87 #define SIZE_BITMAPFILEHEADER 14
88 #define SIZE_BITMAPINFOHEADER 40
89 hsize
= SIZE_BITMAPFILEHEADER
+ SIZE_BITMAPINFOHEADER
+ (pal_entries
<< 2);
90 n_bytes
= n_bytes_image
+ hsize
;
91 if(n_bytes
>buf_size
) {
92 av_log(avctx
, AV_LOG_ERROR
, "buf size too small (need %d, got %d)\n", n_bytes
, buf_size
);
95 bytestream_put_byte(&buf
, 'B'); // BITMAPFILEHEADER.bfType
96 bytestream_put_byte(&buf
, 'M'); // do.
97 bytestream_put_le32(&buf
, n_bytes
); // BITMAPFILEHEADER.bfSize
98 bytestream_put_le16(&buf
, 0); // BITMAPFILEHEADER.bfReserved1
99 bytestream_put_le16(&buf
, 0); // BITMAPFILEHEADER.bfReserved2
100 bytestream_put_le32(&buf
, hsize
); // BITMAPFILEHEADER.bfOffBits
101 bytestream_put_le32(&buf
, SIZE_BITMAPINFOHEADER
); // BITMAPINFOHEADER.biSize
102 bytestream_put_le32(&buf
, avctx
->width
); // BITMAPINFOHEADER.biWidth
103 bytestream_put_le32(&buf
, avctx
->height
); // BITMAPINFOHEADER.biHeight
104 bytestream_put_le16(&buf
, 1); // BITMAPINFOHEADER.biPlanes
105 bytestream_put_le16(&buf
, bit_count
); // BITMAPINFOHEADER.biBitCount
106 bytestream_put_le32(&buf
, compression
); // BITMAPINFOHEADER.biCompression
107 bytestream_put_le32(&buf
, n_bytes_image
); // BITMAPINFOHEADER.biSizeImage
108 bytestream_put_le32(&buf
, 0); // BITMAPINFOHEADER.biXPelsPerMeter
109 bytestream_put_le32(&buf
, 0); // BITMAPINFOHEADER.biYPelsPerMeter
110 bytestream_put_le32(&buf
, 0); // BITMAPINFOHEADER.biClrUsed
111 bytestream_put_le32(&buf
, 0); // BITMAPINFOHEADER.biClrImportant
112 for (i
= 0; i
< pal_entries
; i
++)
113 bytestream_put_le32(&buf
, pal
[i
] & 0xFFFFFF);
114 // BMP files are bottom-to-top so we start from the end...
115 ptr
= p
->data
[0] + (avctx
->height
- 1) * p
->linesize
[0];
117 for(i
= 0; i
< avctx
->height
; i
++) {
118 if (bit_count
== 16) {
119 const uint16_t *src
= (const uint16_t *) ptr
;
120 uint16_t *dst
= (uint16_t *) buf
;
121 for(n
= 0; n
< avctx
->width
; n
++)
122 AV_WL16(dst
+ n
, src
[n
]);
124 memcpy(buf
, ptr
, n_bytes_per_row
);
126 buf
+= n_bytes_per_row
;
127 memset(buf
, 0, pad_bytes_per_row
);
128 buf
+= pad_bytes_per_row
;
129 ptr
-= p
->linesize
[0]; // ... and go back
134 AVCodec bmp_encoder
= {
142 .pix_fmts
= (const enum PixelFormat
[]){
144 PIX_FMT_RGB555
, PIX_FMT_RGB565
,
145 PIX_FMT_RGB8
, PIX_FMT_BGR8
, PIX_FMT_RGB4_BYTE
, PIX_FMT_BGR4_BYTE
, PIX_FMT_GRAY8
, PIX_FMT_PAL8
,
148 .long_name
= NULL_IF_CONFIG_SMALL("BMP image"),