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 Libav.
8 * Libav 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 * Libav 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 Libav; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "libavutil/imgutils.h"
25 #include "bytestream.h"
29 static const uint32_t monoblack_pal
[] = { 0x000000, 0xFFFFFF };
30 static const uint32_t rgb565_masks
[] = { 0xF800, 0x07E0, 0x001F };
31 static const uint32_t rgb444_masks
[] = { 0x0F00, 0x00F0, 0x000F };
33 static av_cold
int bmp_encode_init(AVCodecContext
*avctx
){
34 BMPContext
*s
= avctx
->priv_data
;
36 avcodec_get_frame_defaults(&s
->picture
);
37 avctx
->coded_frame
= &s
->picture
;
39 switch (avctx
->pix_fmt
) {
40 case AV_PIX_FMT_BGR24
:
41 avctx
->bits_per_coded_sample
= 24;
43 case AV_PIX_FMT_RGB555
:
44 case AV_PIX_FMT_RGB565
:
45 case AV_PIX_FMT_RGB444
:
46 avctx
->bits_per_coded_sample
= 16;
50 case AV_PIX_FMT_RGB4_BYTE
:
51 case AV_PIX_FMT_BGR4_BYTE
:
52 case AV_PIX_FMT_GRAY8
:
54 avctx
->bits_per_coded_sample
= 8;
56 case AV_PIX_FMT_MONOBLACK
:
57 avctx
->bits_per_coded_sample
= 1;
60 av_log(avctx
, AV_LOG_INFO
, "unsupported pixel format\n");
67 static int bmp_encode_frame(AVCodecContext
*avctx
, AVPacket
*pkt
,
68 const AVFrame
*pict
, int *got_packet
)
70 BMPContext
*s
= avctx
->priv_data
;
71 AVFrame
* const p
= &s
->picture
;
72 int n_bytes_image
, n_bytes_per_row
, n_bytes
, i
, n
, hsize
, ret
;
73 const uint32_t *pal
= NULL
;
74 int pad_bytes_per_row
, pal_entries
= 0, compression
= BMP_RGB
;
75 int bit_count
= avctx
->bits_per_coded_sample
;
78 p
->pict_type
= AV_PICTURE_TYPE_I
;
80 switch (avctx
->pix_fmt
) {
81 case AV_PIX_FMT_RGB444
:
82 compression
= BMP_BITFIELDS
;
83 pal
= rgb444_masks
; // abuse pal to hold color masks
86 case AV_PIX_FMT_RGB565
:
87 compression
= BMP_BITFIELDS
;
88 pal
= rgb565_masks
; // abuse pal to hold color masks
93 case AV_PIX_FMT_RGB4_BYTE
:
94 case AV_PIX_FMT_BGR4_BYTE
:
95 case AV_PIX_FMT_GRAY8
:
96 avpriv_set_systematic_pal2((uint32_t*)p
->data
[1], avctx
->pix_fmt
);
98 pal
= (uint32_t *)p
->data
[1];
100 case AV_PIX_FMT_MONOBLACK
:
104 if (pal
&& !pal_entries
) pal_entries
= 1 << bit_count
;
105 n_bytes_per_row
= ((int64_t)avctx
->width
* (int64_t)bit_count
+ 7LL) >> 3LL;
106 pad_bytes_per_row
= (4 - n_bytes_per_row
) & 3;
107 n_bytes_image
= avctx
->height
* (n_bytes_per_row
+ pad_bytes_per_row
);
109 // STRUCTURE.field refer to the MSVC documentation for BITMAPFILEHEADER
110 // and related pages.
111 #define SIZE_BITMAPFILEHEADER 14
112 #define SIZE_BITMAPINFOHEADER 40
113 hsize
= SIZE_BITMAPFILEHEADER
+ SIZE_BITMAPINFOHEADER
+ (pal_entries
<< 2);
114 n_bytes
= n_bytes_image
+ hsize
;
115 if ((ret
= ff_alloc_packet(pkt
, n_bytes
)) < 0) {
116 av_log(avctx
, AV_LOG_ERROR
, "Error getting output packet.\n");
120 bytestream_put_byte(&buf
, 'B'); // BITMAPFILEHEADER.bfType
121 bytestream_put_byte(&buf
, 'M'); // do.
122 bytestream_put_le32(&buf
, n_bytes
); // BITMAPFILEHEADER.bfSize
123 bytestream_put_le16(&buf
, 0); // BITMAPFILEHEADER.bfReserved1
124 bytestream_put_le16(&buf
, 0); // BITMAPFILEHEADER.bfReserved2
125 bytestream_put_le32(&buf
, hsize
); // BITMAPFILEHEADER.bfOffBits
126 bytestream_put_le32(&buf
, SIZE_BITMAPINFOHEADER
); // BITMAPINFOHEADER.biSize
127 bytestream_put_le32(&buf
, avctx
->width
); // BITMAPINFOHEADER.biWidth
128 bytestream_put_le32(&buf
, avctx
->height
); // BITMAPINFOHEADER.biHeight
129 bytestream_put_le16(&buf
, 1); // BITMAPINFOHEADER.biPlanes
130 bytestream_put_le16(&buf
, bit_count
); // BITMAPINFOHEADER.biBitCount
131 bytestream_put_le32(&buf
, compression
); // BITMAPINFOHEADER.biCompression
132 bytestream_put_le32(&buf
, n_bytes_image
); // BITMAPINFOHEADER.biSizeImage
133 bytestream_put_le32(&buf
, 0); // BITMAPINFOHEADER.biXPelsPerMeter
134 bytestream_put_le32(&buf
, 0); // BITMAPINFOHEADER.biYPelsPerMeter
135 bytestream_put_le32(&buf
, 0); // BITMAPINFOHEADER.biClrUsed
136 bytestream_put_le32(&buf
, 0); // BITMAPINFOHEADER.biClrImportant
137 for (i
= 0; i
< pal_entries
; i
++)
138 bytestream_put_le32(&buf
, pal
[i
] & 0xFFFFFF);
139 // BMP files are bottom-to-top so we start from the end...
140 ptr
= p
->data
[0] + (avctx
->height
- 1) * p
->linesize
[0];
141 buf
= pkt
->data
+ hsize
;
142 for(i
= 0; i
< avctx
->height
; i
++) {
143 if (bit_count
== 16) {
144 const uint16_t *src
= (const uint16_t *) ptr
;
145 uint16_t *dst
= (uint16_t *) buf
;
146 for(n
= 0; n
< avctx
->width
; n
++)
147 AV_WL16(dst
+ n
, src
[n
]);
149 memcpy(buf
, ptr
, n_bytes_per_row
);
151 buf
+= n_bytes_per_row
;
152 memset(buf
, 0, pad_bytes_per_row
);
153 buf
+= pad_bytes_per_row
;
154 ptr
-= p
->linesize
[0]; // ... and go back
157 pkt
->flags
|= AV_PKT_FLAG_KEY
;
162 AVCodec ff_bmp_encoder
= {
164 .type
= AVMEDIA_TYPE_VIDEO
,
165 .id
= AV_CODEC_ID_BMP
,
166 .priv_data_size
= sizeof(BMPContext
),
167 .init
= bmp_encode_init
,
168 .encode2
= bmp_encode_frame
,
169 .pix_fmts
= (const enum AVPixelFormat
[]){
171 AV_PIX_FMT_RGB555
, AV_PIX_FMT_RGB444
, AV_PIX_FMT_RGB565
,
172 AV_PIX_FMT_RGB8
, AV_PIX_FMT_BGR8
, AV_PIX_FMT_RGB4_BYTE
, AV_PIX_FMT_BGR4_BYTE
, AV_PIX_FMT_GRAY8
, AV_PIX_FMT_PAL8
,
173 AV_PIX_FMT_MONOBLACK
,
176 .long_name
= NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"),