FFmpeg
bmpenc.c
Go to the documentation of this file.
1 /*
2  * BMP image format encoder
3  * Copyright (c) 2006, 2007 Michel Bardiaux
4  * Copyright (c) 2009 Daniel Verkamp <daniel at drv.nu>
5  *
6  * This file is part of FFmpeg.
7  *
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.
12  *
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.
17  *
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
21  */
22 
23 #include "config.h"
24 
25 #include "libavutil/imgutils.h"
26 #include "libavutil/avassert.h"
27 #include "avcodec.h"
28 #include "bytestream.h"
29 #include "bmp.h"
30 #include "encode.h"
31 #include "internal.h"
32 
33 static const uint32_t monoblack_pal[] = { 0x000000, 0xFFFFFF };
34 static const uint32_t rgb565_masks[] = { 0xF800, 0x07E0, 0x001F };
35 static const uint32_t rgb444_masks[] = { 0x0F00, 0x00F0, 0x000F };
36 
38  switch (avctx->pix_fmt) {
39  case AV_PIX_FMT_BGRA:
40  avctx->bits_per_coded_sample = 32;
41  break;
42  case AV_PIX_FMT_BGR24:
43  avctx->bits_per_coded_sample = 24;
44  break;
45  case AV_PIX_FMT_RGB555:
46  case AV_PIX_FMT_RGB565:
47  case AV_PIX_FMT_RGB444:
48  avctx->bits_per_coded_sample = 16;
49  break;
50  case AV_PIX_FMT_RGB8:
51  case AV_PIX_FMT_BGR8:
54  case AV_PIX_FMT_GRAY8:
55  case AV_PIX_FMT_PAL8:
56  avctx->bits_per_coded_sample = 8;
57  break;
59  avctx->bits_per_coded_sample = 1;
60  break;
61  default:
62  av_log(avctx, AV_LOG_INFO, "unsupported pixel format\n");
63  return AVERROR(EINVAL);
64  }
65 
66  return 0;
67 }
68 
70  const AVFrame *pict, int *got_packet)
71 {
72  const AVFrame * const p = pict;
73  int n_bytes_image, n_bytes_per_row, n_bytes, i, n, hsize, ret;
74  const uint32_t *pal = NULL;
75  uint32_t palette256[256];
76  int pad_bytes_per_row, pal_entries = 0, compression = BMP_RGB;
77  int bit_count = avctx->bits_per_coded_sample;
78  uint8_t *ptr, *buf;
79 
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
84  pal_entries = 3;
85  break;
86  case AV_PIX_FMT_RGB565:
87  compression = BMP_BITFIELDS;
88  pal = rgb565_masks; // abuse pal to hold color masks
89  pal_entries = 3;
90  break;
91  case AV_PIX_FMT_RGB8:
92  case AV_PIX_FMT_BGR8:
95  case AV_PIX_FMT_GRAY8:
96  av_assert1(bit_count == 8);
97  avpriv_set_systematic_pal2(palette256, avctx->pix_fmt);
98  pal = palette256;
99  break;
100  case AV_PIX_FMT_PAL8:
101  pal = (uint32_t *)p->data[1];
102  break;
104  pal = monoblack_pal;
105  break;
106  }
107  if (pal && !pal_entries) pal_entries = 1 << bit_count;
108  n_bytes_per_row = ((int64_t)avctx->width * (int64_t)bit_count + 7LL) >> 3LL;
109  pad_bytes_per_row = (4 - n_bytes_per_row) & 3;
110  n_bytes_image = avctx->height * (n_bytes_per_row + pad_bytes_per_row);
111 
112  // STRUCTURE.field refer to the MSVC documentation for BITMAPFILEHEADER
113  // and related pages.
114 #define SIZE_BITMAPFILEHEADER 14
115 #define SIZE_BITMAPINFOHEADER 40
116  hsize = SIZE_BITMAPFILEHEADER + SIZE_BITMAPINFOHEADER + (pal_entries << 2);
117  n_bytes = n_bytes_image + hsize;
118  if ((ret = ff_get_encode_buffer(avctx, pkt, n_bytes, 0)) < 0)
119  return ret;
120  buf = pkt->data;
121  bytestream_put_byte(&buf, 'B'); // BITMAPFILEHEADER.bfType
122  bytestream_put_byte(&buf, 'M'); // do.
123  bytestream_put_le32(&buf, n_bytes); // BITMAPFILEHEADER.bfSize
124  bytestream_put_le16(&buf, 0); // BITMAPFILEHEADER.bfReserved1
125  bytestream_put_le16(&buf, 0); // BITMAPFILEHEADER.bfReserved2
126  bytestream_put_le32(&buf, hsize); // BITMAPFILEHEADER.bfOffBits
127  bytestream_put_le32(&buf, SIZE_BITMAPINFOHEADER); // BITMAPINFOHEADER.biSize
128  bytestream_put_le32(&buf, avctx->width); // BITMAPINFOHEADER.biWidth
129  bytestream_put_le32(&buf, avctx->height); // BITMAPINFOHEADER.biHeight
130  bytestream_put_le16(&buf, 1); // BITMAPINFOHEADER.biPlanes
131  bytestream_put_le16(&buf, bit_count); // BITMAPINFOHEADER.biBitCount
132  bytestream_put_le32(&buf, compression); // BITMAPINFOHEADER.biCompression
133  bytestream_put_le32(&buf, n_bytes_image); // BITMAPINFOHEADER.biSizeImage
134  bytestream_put_le32(&buf, 0); // BITMAPINFOHEADER.biXPelsPerMeter
135  bytestream_put_le32(&buf, 0); // BITMAPINFOHEADER.biYPelsPerMeter
136  bytestream_put_le32(&buf, 0); // BITMAPINFOHEADER.biClrUsed
137  bytestream_put_le32(&buf, 0); // BITMAPINFOHEADER.biClrImportant
138  for (i = 0; i < pal_entries; i++)
139  bytestream_put_le32(&buf, pal[i] & 0xFFFFFF);
140  // BMP files are bottom-to-top so we start from the end...
141  ptr = p->data[0] + (avctx->height - 1) * p->linesize[0];
142  buf = pkt->data + hsize;
143  for(i = 0; i < avctx->height; i++) {
144  if (HAVE_BIGENDIAN && bit_count == 16) {
145  const uint16_t *src = (const uint16_t *) ptr;
146  for(n = 0; n < avctx->width; n++)
147  AV_WL16(buf + 2 * n, src[n]);
148  } else {
149  memcpy(buf, ptr, n_bytes_per_row);
150  }
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
155  }
156 
158  *got_packet = 1;
159  return 0;
160 }
161 
163  .name = "bmp",
164  .long_name = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"),
165  .type = AVMEDIA_TYPE_VIDEO,
166  .id = AV_CODEC_ID_BMP,
167  .capabilities = AV_CODEC_CAP_DR1,
168  .init = bmp_encode_init,
169  .encode2 = bmp_encode_frame,
170  .pix_fmts = (const enum AVPixelFormat[]){
176  },
177  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
178 };
rgb444_masks
static const uint32_t rgb444_masks[]
Definition: bmpenc.c:35
AVCodec
AVCodec.
Definition: codec.h:197
FF_CODEC_CAP_INIT_THREADSAFE
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: internal.h:41
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:303
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:365
encode.h
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
AV_PIX_FMT_BGRA
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:95
BMP_RGB
@ BMP_RGB
Definition: bmp.h:28
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:396
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:317
SIZE_BITMAPINFOHEADER
#define SIZE_BITMAPINFOHEADER
AV_PIX_FMT_BGR8
@ AV_PIX_FMT_BGR8
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
Definition: pixfmt.h:83
avassert.h
pkt
AVPacket * pkt
Definition: movenc.c:59
av_cold
#define av_cold
Definition: attributes.h:90
AV_CODEC_ID_BMP
@ AV_CODEC_ID_BMP
Definition: codec_id.h:127
ff_bmp_encoder
const AVCodec ff_bmp_encoder
Definition: bmpenc.c:162
avpriv_set_systematic_pal2
int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt)
Definition: imgutils.c:175
bmp.h
NULL
#define NULL
Definition: coverity.c:32
AV_PIX_FMT_MONOBLACK
@ AV_PIX_FMT_MONOBLACK
Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb.
Definition: pixfmt.h:76
src
#define src
Definition: vp8dsp.c:255
AV_PIX_FMT_RGB8
@ AV_PIX_FMT_RGB8
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
Definition: pixfmt.h:86
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
AV_PIX_FMT_BGR4_BYTE
@ AV_PIX_FMT_BGR4_BYTE
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
Definition: pixfmt.h:85
bmp_encode_init
static av_cold int bmp_encode_init(AVCodecContext *avctx)
Definition: bmpenc.c:37
monoblack_pal
static const uint32_t monoblack_pal[]
Definition: bmpenc.c:33
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
BMP_BITFIELDS
@ BMP_BITFIELDS
Definition: bmp.h:31
AV_WL16
#define AV_WL16(p, v)
Definition: intreadwrite.h:412
height
#define height
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:371
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:192
AVCodecContext::bits_per_coded_sample
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:1524
bmp_encode_frame
static int bmp_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet)
Definition: bmpenc.c:69
i
int i
Definition: input.c:407
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:53
AV_PIX_FMT_RGB555
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:377
SIZE_BITMAPFILEHEADER
#define SIZE_BITMAPFILEHEADER
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:204
AV_PIX_FMT_RGB4_BYTE
@ AV_PIX_FMT_RGB4_BYTE
packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
Definition: pixfmt.h:88
AVCodecContext::height
int height
Definition: avcodec.h:674
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:711
AV_PIX_FMT_RGB565
#define AV_PIX_FMT_RGB565
Definition: pixfmt.h:376
avcodec.h
AV_PIX_FMT_PAL8
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:77
ret
ret
Definition: filter_design.txt:187
AVCodecContext
main external API structure.
Definition: avcodec.h:501
ff_get_encode_buffer
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
Definition: encode.c:81
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AVPacket
This structure stores compressed data.
Definition: packet.h:342
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:674
bytestream.h
imgutils.h
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:334
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
rgb565_masks
static const uint32_t rgb565_masks[]
Definition: bmpenc.c:34
AV_PIX_FMT_RGB444
#define AV_PIX_FMT_RGB444
Definition: pixfmt.h:378