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 
161  pkt->flags |= AV_PKT_FLAG_KEY;
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 };
AVCodec ff_bmp_encoder
Definition: bmpenc.c:166
#define NULL
Definition: coverity.c:32
This structure describes decoded (raw) audio or video data.
Definition: frame.h:268
misc image utilities
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1775
static AVPacket pkt
#define AV_PIX_FMT_RGB444
Definition: pixfmt.h:376
#define src
Definition: vp8dsp.c:254
#define SIZE_BITMAPINFOHEADER
AVCodec.
Definition: avcodec.h:3477
static const uint32_t rgb565_masks[]
Definition: bmpenc.c:31
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
Definition: pixfmt.h:85
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:32
uint8_t
#define av_cold
Definition: attributes.h:82
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:77
int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt)
Definition: imgutils.c:152
#define height
uint8_t * data
Definition: avcodec.h:1477
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:2785
#define av_log(a,...)
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1509
#define SIZE_BITMAPFILEHEADER
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:260
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:95
simple assert() macros that are a bit more flexible than ISO C assert().
static const uint32_t monoblack_pal[]
Definition: bmpenc.c:30
const char * name
Name of the codec implementation.
Definition: avcodec.h:3484
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1483
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:351
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:53
packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
Definition: pixfmt.h:88
int width
picture width / height.
Definition: avcodec.h:1738
int n
Definition: avisynth_c.h:760
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
Definition: pixfmt.h:83
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:299
static int bmp_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet)
Definition: bmpenc.c:66
main external API structure.
Definition: avcodec.h:1565
static av_cold int bmp_encode_init(AVCodecContext *avctx)
Definition: bmpenc.c:34
void * buf
Definition: avisynth_c.h:766
Definition: bmp.h:28
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:282
Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb...
Definition: pixfmt.h:76
Y , 8bpp.
Definition: pixfmt.h:74
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:84
common internal api header.
#define AV_WL16(p, v)
Definition: intreadwrite.h:412
attribute_deprecated AVFrame * coded_frame
the picture in the bitstream
Definition: avcodec.h:2811
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
Definition: pixfmt.h:86
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:375
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:85
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:346
#define AV_PIX_FMT_RGB565
Definition: pixfmt.h:374
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
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
This structure stores compressed data.
Definition: avcodec.h:1454
static const uint32_t rgb444_masks[]
Definition: bmpenc.c:32