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 switch (avctx
->pix_fmt
) {
35 case AV_PIX_FMT_BGR24
:
36 avctx
->bits_per_coded_sample
= 24;
38 case AV_PIX_FMT_RGB555
:
39 case AV_PIX_FMT_RGB565
:
40 case AV_PIX_FMT_RGB444
:
41 avctx
->bits_per_coded_sample
= 16;
45 case AV_PIX_FMT_RGB4_BYTE
:
46 case AV_PIX_FMT_BGR4_BYTE
:
47 case AV_PIX_FMT_GRAY8
:
49 avctx
->bits_per_coded_sample
= 8;
51 case AV_PIX_FMT_MONOBLACK
:
52 avctx
->bits_per_coded_sample
= 1;
55 av_log(avctx
, AV_LOG_INFO
, "unsupported pixel format\n");
62 static int bmp_encode_frame(AVCodecContext
*avctx
, AVPacket
*pkt
,
63 const AVFrame
*pict
, int *got_packet
)
65 const AVFrame
* const p
= pict
;
66 int n_bytes_image
, n_bytes_per_row
, n_bytes
, i
, n
, hsize
, ret
;
67 const uint32_t *pal
= NULL
;
68 int pad_bytes_per_row
, pal_entries
= 0, compression
= BMP_RGB
;
69 int bit_count
= avctx
->bits_per_coded_sample
;
72 #if FF_API_CODED_FRAME
73 FF_DISABLE_DEPRECATION_WARNINGS
74 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_I
;
75 avctx
->coded_frame
->key_frame
= 1;
76 FF_ENABLE_DEPRECATION_WARNINGS
78 switch (avctx
->pix_fmt
) {
79 case AV_PIX_FMT_RGB444
:
80 compression
= BMP_BITFIELDS
;
81 pal
= rgb444_masks
; // abuse pal to hold color masks
84 case AV_PIX_FMT_RGB565
:
85 compression
= BMP_BITFIELDS
;
86 pal
= rgb565_masks
; // abuse pal to hold color masks
91 case AV_PIX_FMT_RGB4_BYTE
:
92 case AV_PIX_FMT_BGR4_BYTE
:
93 case AV_PIX_FMT_GRAY8
:
94 avpriv_set_systematic_pal2((uint32_t*)p
->data
[1], avctx
->pix_fmt
);
96 pal
= (uint32_t *)p
->data
[1];
98 case AV_PIX_FMT_MONOBLACK
:
102 if (pal
&& !pal_entries
) pal_entries
= 1 << bit_count
;
103 n_bytes_per_row
= ((int64_t)avctx
->width
* (int64_t)bit_count
+ 7LL) >> 3LL;
104 pad_bytes_per_row
= (4 - n_bytes_per_row
) & 3;
105 n_bytes_image
= avctx
->height
* (n_bytes_per_row
+ pad_bytes_per_row
);
107 // STRUCTURE.field refer to the MSVC documentation for BITMAPFILEHEADER
108 // and related pages.
109 #define SIZE_BITMAPFILEHEADER 14
110 #define SIZE_BITMAPINFOHEADER 40
111 hsize
= SIZE_BITMAPFILEHEADER
+ SIZE_BITMAPINFOHEADER
+ (pal_entries
<< 2);
112 n_bytes
= n_bytes_image
+ hsize
;
113 if ((ret
= ff_alloc_packet(pkt
, n_bytes
)) < 0) {
114 av_log(avctx
, AV_LOG_ERROR
, "Error getting output packet.\n");
118 bytestream_put_byte(&buf
, 'B'); // BITMAPFILEHEADER.bfType
119 bytestream_put_byte(&buf
, 'M'); // do.
120 bytestream_put_le32(&buf
, n_bytes
); // BITMAPFILEHEADER.bfSize
121 bytestream_put_le16(&buf
, 0); // BITMAPFILEHEADER.bfReserved1
122 bytestream_put_le16(&buf
, 0); // BITMAPFILEHEADER.bfReserved2
123 bytestream_put_le32(&buf
, hsize
); // BITMAPFILEHEADER.bfOffBits
124 bytestream_put_le32(&buf
, SIZE_BITMAPINFOHEADER
); // BITMAPINFOHEADER.biSize
125 bytestream_put_le32(&buf
, avctx
->width
); // BITMAPINFOHEADER.biWidth
126 bytestream_put_le32(&buf
, avctx
->height
); // BITMAPINFOHEADER.biHeight
127 bytestream_put_le16(&buf
, 1); // BITMAPINFOHEADER.biPlanes
128 bytestream_put_le16(&buf
, bit_count
); // BITMAPINFOHEADER.biBitCount
129 bytestream_put_le32(&buf
, compression
); // BITMAPINFOHEADER.biCompression
130 bytestream_put_le32(&buf
, n_bytes_image
); // BITMAPINFOHEADER.biSizeImage
131 bytestream_put_le32(&buf
, 0); // BITMAPINFOHEADER.biXPelsPerMeter
132 bytestream_put_le32(&buf
, 0); // BITMAPINFOHEADER.biYPelsPerMeter
133 bytestream_put_le32(&buf
, 0); // BITMAPINFOHEADER.biClrUsed
134 bytestream_put_le32(&buf
, 0); // BITMAPINFOHEADER.biClrImportant
135 for (i
= 0; i
< pal_entries
; i
++)
136 bytestream_put_le32(&buf
, pal
[i
] & 0xFFFFFF);
137 // BMP files are bottom-to-top so we start from the end...
138 ptr
= p
->data
[0] + (avctx
->height
- 1) * p
->linesize
[0];
139 buf
= pkt
->data
+ hsize
;
140 for(i
= 0; i
< avctx
->height
; i
++) {
141 if (bit_count
== 16) {
142 const uint16_t *src
= (const uint16_t *) ptr
;
143 uint16_t *dst
= (uint16_t *) buf
;
144 for(n
= 0; n
< avctx
->width
; n
++)
145 AV_WL16(dst
+ n
, src
[n
]);
147 memcpy(buf
, ptr
, n_bytes_per_row
);
149 buf
+= n_bytes_per_row
;
150 memset(buf
, 0, pad_bytes_per_row
);
151 buf
+= pad_bytes_per_row
;
152 ptr
-= p
->linesize
[0]; // ... and go back
155 pkt
->flags
|= AV_PKT_FLAG_KEY
;
160 AVCodec ff_bmp_encoder
= {
162 .long_name
= NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"),
163 .type
= AVMEDIA_TYPE_VIDEO
,
164 .id
= AV_CODEC_ID_BMP
,
165 .init
= bmp_encode_init
,
166 .encode2
= bmp_encode_frame
,
167 .pix_fmts
= (const enum AVPixelFormat
[]){
169 AV_PIX_FMT_RGB555
, AV_PIX_FMT_RGB444
, AV_PIX_FMT_RGB565
,
170 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
,
171 AV_PIX_FMT_MONOBLACK
,