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 "libavutil/imgutils.h"
24 #include "libavutil/avassert.h"
25 #include "avcodec.h"
26 #include "bytestream.h"
27 #include "bmp.h"
28 #include "internal.h"
29 
30 static const uint32_t monoblack_pal[] = { 0x000000, 0xFFFFFF };
31 static const uint32_t rgb565_masks[] = { 0xF800, 0x07E0, 0x001F };
32 static const uint32_t rgb444_masks[] = { 0x0F00, 0x00F0, 0x000F };
33 
35  switch (avctx->pix_fmt) {
36  case AV_PIX_FMT_BGRA:
37  avctx->bits_per_coded_sample = 32;
38  break;
39  case AV_PIX_FMT_BGR24:
40  avctx->bits_per_coded_sample = 24;
41  break;
42  case AV_PIX_FMT_RGB555:
43  case AV_PIX_FMT_RGB565:
44  case AV_PIX_FMT_RGB444:
45  avctx->bits_per_coded_sample = 16;
46  break;
47  case AV_PIX_FMT_RGB8:
48  case AV_PIX_FMT_BGR8:
51  case AV_PIX_FMT_GRAY8:
52  case AV_PIX_FMT_PAL8:
53  avctx->bits_per_coded_sample = 8;
54  break;
56  avctx->bits_per_coded_sample = 1;
57  break;
58  default:
59  av_log(avctx, AV_LOG_INFO, "unsupported pixel format\n");
60  return AVERROR(EINVAL);
61  }
62 
63  return 0;
64 }
65 
67  const AVFrame *pict, int *got_packet)
68 {
69  const AVFrame * const p = pict;
70  int n_bytes_image, n_bytes_per_row, n_bytes, i, n, hsize, ret;
71  const uint32_t *pal = NULL;
72  uint32_t palette256[256];
73  int pad_bytes_per_row, pal_entries = 0, compression = BMP_RGB;
74  int bit_count = avctx->bits_per_coded_sample;
75  uint8_t *ptr, *buf;
76 
77 #if FF_API_CODED_FRAME
80  avctx->coded_frame->key_frame = 1;
82 #endif
83  switch (avctx->pix_fmt) {
84  case AV_PIX_FMT_RGB444:
85  compression = BMP_BITFIELDS;
86  pal = rgb444_masks; // abuse pal to hold color masks
87  pal_entries = 3;
88  break;
89  case AV_PIX_FMT_RGB565:
90  compression = BMP_BITFIELDS;
91  pal = rgb565_masks; // abuse pal to hold color masks
92  pal_entries = 3;
93  break;
94  case AV_PIX_FMT_RGB8:
95  case AV_PIX_FMT_BGR8:
98  case AV_PIX_FMT_GRAY8:
99  av_assert1(bit_count == 8);
100  avpriv_set_systematic_pal2(palette256, avctx->pix_fmt);
101  pal = palette256;
102  break;
103  case AV_PIX_FMT_PAL8:
104  pal = (uint32_t *)p->data[1];
105  break;
107  pal = monoblack_pal;
108  break;
109  }
110  if (pal && !pal_entries) pal_entries = 1 << bit_count;
111  n_bytes_per_row = ((int64_t)avctx->width * (int64_t)bit_count + 7LL) >> 3LL;
112  pad_bytes_per_row = (4 - n_bytes_per_row) & 3;
113  n_bytes_image = avctx->height * (n_bytes_per_row + pad_bytes_per_row);
114 
115  // STRUCTURE.field refer to the MSVC documentation for BITMAPFILEHEADER
116  // and related pages.
117 #define SIZE_BITMAPFILEHEADER 14
118 #define SIZE_BITMAPINFOHEADER 40
119  hsize = SIZE_BITMAPFILEHEADER + SIZE_BITMAPINFOHEADER + (pal_entries << 2);
120  n_bytes = n_bytes_image + hsize;
121  if ((ret = ff_alloc_packet2(avctx, pkt, n_bytes, 0)) < 0)
122  return ret;
123  buf = pkt->data;
124  bytestream_put_byte(&buf, 'B'); // BITMAPFILEHEADER.bfType
125  bytestream_put_byte(&buf, 'M'); // do.
126  bytestream_put_le32(&buf, n_bytes); // BITMAPFILEHEADER.bfSize
127  bytestream_put_le16(&buf, 0); // BITMAPFILEHEADER.bfReserved1
128  bytestream_put_le16(&buf, 0); // BITMAPFILEHEADER.bfReserved2
129  bytestream_put_le32(&buf, hsize); // BITMAPFILEHEADER.bfOffBits
130  bytestream_put_le32(&buf, SIZE_BITMAPINFOHEADER); // BITMAPINFOHEADER.biSize
131  bytestream_put_le32(&buf, avctx->width); // BITMAPINFOHEADER.biWidth
132  bytestream_put_le32(&buf, avctx->height); // BITMAPINFOHEADER.biHeight
133  bytestream_put_le16(&buf, 1); // BITMAPINFOHEADER.biPlanes
134  bytestream_put_le16(&buf, bit_count); // BITMAPINFOHEADER.biBitCount
135  bytestream_put_le32(&buf, compression); // BITMAPINFOHEADER.biCompression
136  bytestream_put_le32(&buf, n_bytes_image); // BITMAPINFOHEADER.biSizeImage
137  bytestream_put_le32(&buf, 0); // BITMAPINFOHEADER.biXPelsPerMeter
138  bytestream_put_le32(&buf, 0); // BITMAPINFOHEADER.biYPelsPerMeter
139  bytestream_put_le32(&buf, 0); // BITMAPINFOHEADER.biClrUsed
140  bytestream_put_le32(&buf, 0); // BITMAPINFOHEADER.biClrImportant
141  for (i = 0; i < pal_entries; i++)
142  bytestream_put_le32(&buf, pal[i] & 0xFFFFFF);
143  // BMP files are bottom-to-top so we start from the end...
144  ptr = p->data[0] + (avctx->height - 1) * p->linesize[0];
145  buf = pkt->data + hsize;
146  for(i = 0; i < avctx->height; i++) {
147  if (bit_count == 16) {
148  const uint16_t *src = (const uint16_t *) ptr;
149  uint16_t *dst = (uint16_t *) buf;
150  for(n = 0; n < avctx->width; n++)
151  AV_WL16(dst + n, src[n]);
152  } else {
153  memcpy(buf, ptr, n_bytes_per_row);
154  }
155  buf += n_bytes_per_row;
156  memset(buf, 0, pad_bytes_per_row);
157  buf += pad_bytes_per_row;
158  ptr -= p->linesize[0]; // ... and go back
159  }
160 
162  *got_packet = 1;
163  return 0;
164 }
165 
167  .name = "bmp",
168  .long_name = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"),
169  .type = AVMEDIA_TYPE_VIDEO,
170  .id = AV_CODEC_ID_BMP,
171  .init = bmp_encode_init,
172  .encode2 = bmp_encode_frame,
173  .pix_fmts = (const enum AVPixelFormat[]){
179  },
180 };
rgb444_masks
static const uint32_t rgb444_masks[]
Definition: bmpenc.c:32
AVCodec
AVCodec.
Definition: codec.h:197
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:84
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:318
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:369
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:410
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:332
AVFrame::key_frame
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:396
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
AVCodec ff_bmp_encoder
Definition: bmpenc.c:166
avpriv_set_systematic_pal2
int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt)
Definition: imgutils.c:176
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
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
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:34
monoblack_pal
static const uint32_t monoblack_pal[]
Definition: bmpenc.c:30
AVFrame::pict_type
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:401
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:375
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:205
AVCodecContext::bits_per_coded_sample
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:1740
bmp_encode_frame
static int bmp_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet)
Definition: bmpenc.c:66
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:387
SIZE_BITMAPFILEHEADER
#define SIZE_BITMAPFILEHEADER
uint8_t
uint8_t
Definition: audio_convert.c:194
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:709
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:746
AV_PIX_FMT_RGB565
#define AV_PIX_FMT_RGB565
Definition: pixfmt.h:386
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::coded_frame
attribute_deprecated AVFrame * coded_frame
the picture in the bitstream
Definition: avcodec.h:1764
AVCodecContext
main external API structure.
Definition: avcodec.h:536
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:83
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AVPacket
This structure stores compressed data.
Definition: packet.h:346
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:709
bytestream.h
imgutils.h
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:349
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
rgb565_masks
static const uint32_t rgb565_masks[]
Definition: bmpenc.c:31
ff_alloc_packet2
int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64_t min_size)
Check AVPacket size and/or allocate data.
Definition: encode.c:33
AV_PIX_FMT_RGB444
#define AV_PIX_FMT_RGB444
Definition: pixfmt.h:388