FFmpeg
bmp.c
Go to the documentation of this file.
1 /*
2  * BMP image format decoder
3  * Copyright (c) 2005 Mans Rullgard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include <inttypes.h>
23 
24 #include "avcodec.h"
25 #include "bytestream.h"
26 #include "bmp.h"
27 #include "internal.h"
28 #include "msrledec.h"
29 
30 static int bmp_decode_frame(AVCodecContext *avctx,
31  void *data, int *got_frame,
32  AVPacket *avpkt)
33 {
34  const uint8_t *buf = avpkt->data;
35  int buf_size = avpkt->size;
36  AVFrame *p = data;
37  unsigned int fsize, hsize;
38  int width, height;
39  unsigned int depth;
41  unsigned int ihsize;
42  int i, j, n, linesize, ret;
43  uint32_t rgb[3] = {0};
44  uint32_t alpha = 0;
45  uint8_t *ptr;
46  int dsize;
47  const uint8_t *buf0 = buf;
48  GetByteContext gb;
49 
50  if (buf_size < 14) {
51  av_log(avctx, AV_LOG_ERROR, "buf size too small (%d)\n", buf_size);
52  return AVERROR_INVALIDDATA;
53  }
54 
55  if (bytestream_get_byte(&buf) != 'B' ||
56  bytestream_get_byte(&buf) != 'M') {
57  av_log(avctx, AV_LOG_ERROR, "bad magic number\n");
58  return AVERROR_INVALIDDATA;
59  }
60 
61  fsize = bytestream_get_le32(&buf);
62  if (buf_size < fsize) {
63  av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %u), trying to decode anyway\n",
64  buf_size, fsize);
65  fsize = buf_size;
66  }
67 
68  buf += 2; /* reserved1 */
69  buf += 2; /* reserved2 */
70 
71  hsize = bytestream_get_le32(&buf); /* header size */
72  ihsize = bytestream_get_le32(&buf); /* more header size */
73  if (ihsize + 14LL > hsize) {
74  av_log(avctx, AV_LOG_ERROR, "invalid header size %u\n", hsize);
75  return AVERROR_INVALIDDATA;
76  }
77 
78  /* sometimes file size is set to some headers size, set a real size in that case */
79  if (fsize == 14 || fsize == ihsize + 14)
80  fsize = buf_size - 2;
81 
82  if (fsize <= hsize) {
83  av_log(avctx, AV_LOG_ERROR,
84  "Declared file size is less than header size (%u < %u)\n",
85  fsize, hsize);
86  return AVERROR_INVALIDDATA;
87  }
88 
89  switch (ihsize) {
90  case 40: // windib
91  case 56: // windib v3
92  case 64: // OS/2 v2
93  case 108: // windib v4
94  case 124: // windib v5
95  width = bytestream_get_le32(&buf);
96  height = bytestream_get_le32(&buf);
97  break;
98  case 12: // OS/2 v1
99  width = bytestream_get_le16(&buf);
100  height = bytestream_get_le16(&buf);
101  break;
102  default:
103  avpriv_report_missing_feature(avctx, "Information header size %u",
104  ihsize);
105  return AVERROR_PATCHWELCOME;
106  }
107 
108  /* planes */
109  if (bytestream_get_le16(&buf) != 1) {
110  av_log(avctx, AV_LOG_ERROR, "invalid BMP header\n");
111  return AVERROR_INVALIDDATA;
112  }
113 
114  depth = bytestream_get_le16(&buf);
115 
116  if (ihsize >= 40)
117  comp = bytestream_get_le32(&buf);
118  else
119  comp = BMP_RGB;
120 
121  if (comp != BMP_RGB && comp != BMP_BITFIELDS && comp != BMP_RLE4 &&
122  comp != BMP_RLE8) {
123  av_log(avctx, AV_LOG_ERROR, "BMP coding %d not supported\n", comp);
124  return AVERROR_INVALIDDATA;
125  }
126 
127  if (comp == BMP_BITFIELDS) {
128  buf += 20;
129  rgb[0] = bytestream_get_le32(&buf);
130  rgb[1] = bytestream_get_le32(&buf);
131  rgb[2] = bytestream_get_le32(&buf);
132  if (ihsize > 40)
133  alpha = bytestream_get_le32(&buf);
134  }
135 
136  ret = ff_set_dimensions(avctx, width, height > 0 ? height : -(unsigned)height);
137  if (ret < 0) {
138  av_log(avctx, AV_LOG_ERROR, "Failed to set dimensions %d %d\n", width, height);
139  return AVERROR_INVALIDDATA;
140  }
141 
142  avctx->pix_fmt = AV_PIX_FMT_NONE;
143 
144  switch (depth) {
145  case 32:
146  if (comp == BMP_BITFIELDS) {
147  if (rgb[0] == 0xFF000000 && rgb[1] == 0x00FF0000 && rgb[2] == 0x0000FF00)
149  else if (rgb[0] == 0x00FF0000 && rgb[1] == 0x0000FF00 && rgb[2] == 0x000000FF)
151  else if (rgb[0] == 0x0000FF00 && rgb[1] == 0x00FF0000 && rgb[2] == 0xFF000000)
153  else if (rgb[0] == 0x000000FF && rgb[1] == 0x0000FF00 && rgb[2] == 0x00FF0000)
155  else {
156  av_log(avctx, AV_LOG_ERROR, "Unknown bitfields "
157  "%0"PRIX32" %0"PRIX32" %0"PRIX32"\n", rgb[0], rgb[1], rgb[2]);
158  return AVERROR(EINVAL);
159  }
160  } else {
161  avctx->pix_fmt = AV_PIX_FMT_BGRA;
162  }
163  break;
164  case 24:
165  avctx->pix_fmt = AV_PIX_FMT_BGR24;
166  break;
167  case 16:
168  if (comp == BMP_RGB)
169  avctx->pix_fmt = AV_PIX_FMT_RGB555;
170  else if (comp == BMP_BITFIELDS) {
171  if (rgb[0] == 0xF800 && rgb[1] == 0x07E0 && rgb[2] == 0x001F)
172  avctx->pix_fmt = AV_PIX_FMT_RGB565;
173  else if (rgb[0] == 0x7C00 && rgb[1] == 0x03E0 && rgb[2] == 0x001F)
174  avctx->pix_fmt = AV_PIX_FMT_RGB555;
175  else if (rgb[0] == 0x0F00 && rgb[1] == 0x00F0 && rgb[2] == 0x000F)
176  avctx->pix_fmt = AV_PIX_FMT_RGB444;
177  else {
178  av_log(avctx, AV_LOG_ERROR,
179  "Unknown bitfields %0"PRIX32" %0"PRIX32" %0"PRIX32"\n",
180  rgb[0], rgb[1], rgb[2]);
181  return AVERROR(EINVAL);
182  }
183  }
184  break;
185  case 8:
186  if (hsize - ihsize - 14 > 0)
187  avctx->pix_fmt = AV_PIX_FMT_PAL8;
188  else
189  avctx->pix_fmt = AV_PIX_FMT_GRAY8;
190  break;
191  case 1:
192  case 4:
193  if (hsize - ihsize - 14 > 0) {
194  avctx->pix_fmt = AV_PIX_FMT_PAL8;
195  } else {
196  av_log(avctx, AV_LOG_ERROR, "Unknown palette for %u-colour BMP\n",
197  1 << depth);
198  return AVERROR_INVALIDDATA;
199  }
200  break;
201  default:
202  av_log(avctx, AV_LOG_ERROR, "depth %u not supported\n", depth);
203  return AVERROR_INVALIDDATA;
204  }
205 
206  if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
207  av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n");
208  return AVERROR_INVALIDDATA;
209  }
210 
211  if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
212  return ret;
214  p->key_frame = 1;
215 
216  buf = buf0 + hsize;
217  dsize = buf_size - hsize;
218 
219  /* Line size in file multiple of 4 */
220  n = ((avctx->width * depth + 31) / 8) & ~3;
221 
222  if (n * avctx->height > dsize && comp != BMP_RLE4 && comp != BMP_RLE8) {
223  n = (avctx->width * depth + 7) / 8;
224  if (n * avctx->height > dsize) {
225  av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n",
226  dsize, n * avctx->height);
227  return AVERROR_INVALIDDATA;
228  }
229  av_log(avctx, AV_LOG_ERROR, "data size too small, assuming missing line alignment\n");
230  }
231 
232  // RLE may skip decoding some picture areas, so blank picture before decoding
233  if (comp == BMP_RLE4 || comp == BMP_RLE8)
234  memset(p->data[0], 0, avctx->height * p->linesize[0]);
235 
236  if (height > 0) {
237  ptr = p->data[0] + (avctx->height - 1) * p->linesize[0];
238  linesize = -p->linesize[0];
239  } else {
240  ptr = p->data[0];
241  linesize = p->linesize[0];
242  }
243 
244  if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
245  int colors = 1 << depth;
246 
247  memset(p->data[1], 0, 1024);
248 
249  if (ihsize >= 36) {
250  int t;
251  buf = buf0 + 46;
252  t = bytestream_get_le32(&buf);
253  if (t < 0 || t > (1 << depth)) {
254  av_log(avctx, AV_LOG_ERROR,
255  "Incorrect number of colors - %X for bitdepth %u\n",
256  t, depth);
257  } else if (t) {
258  colors = t;
259  }
260  } else {
261  colors = FFMIN(256, (hsize-ihsize-14) / 3);
262  }
263  buf = buf0 + 14 + ihsize; //palette location
264  // OS/2 bitmap, 3 bytes per palette entry
265  if ((hsize-ihsize-14) < (colors << 2)) {
266  if ((hsize-ihsize-14) < colors * 3) {
267  av_log(avctx, AV_LOG_ERROR, "palette doesn't fit in packet\n");
268  return AVERROR_INVALIDDATA;
269  }
270  for (i = 0; i < colors; i++)
271  ((uint32_t*)p->data[1])[i] = (0xFFU<<24) | bytestream_get_le24(&buf);
272  } else {
273  for (i = 0; i < colors; i++)
274  ((uint32_t*)p->data[1])[i] = 0xFFU << 24 | bytestream_get_le32(&buf);
275  }
276  buf = buf0 + hsize;
277  }
278  if (comp == BMP_RLE4 || comp == BMP_RLE8) {
279  if (comp == BMP_RLE8 && height < 0) {
280  p->data[0] += p->linesize[0] * (avctx->height - 1);
281  p->linesize[0] = -p->linesize[0];
282  }
283  bytestream2_init(&gb, buf, dsize);
284  ff_msrle_decode(avctx, p, depth, &gb);
285  if (height < 0) {
286  p->data[0] += p->linesize[0] * (avctx->height - 1);
287  p->linesize[0] = -p->linesize[0];
288  }
289  } else {
290  switch (depth) {
291  case 1:
292  for (i = 0; i < avctx->height; i++) {
293  int j;
294  for (j = 0; j < avctx->width >> 3; j++) {
295  ptr[j*8+0] = buf[j] >> 7;
296  ptr[j*8+1] = (buf[j] >> 6) & 1;
297  ptr[j*8+2] = (buf[j] >> 5) & 1;
298  ptr[j*8+3] = (buf[j] >> 4) & 1;
299  ptr[j*8+4] = (buf[j] >> 3) & 1;
300  ptr[j*8+5] = (buf[j] >> 2) & 1;
301  ptr[j*8+6] = (buf[j] >> 1) & 1;
302  ptr[j*8+7] = buf[j] & 1;
303  }
304  for (j = 0; j < (avctx->width & 7); j++) {
305  ptr[avctx->width - (avctx->width & 7) + j] = buf[avctx->width >> 3] >> (7 - j) & 1;
306  }
307  buf += n;
308  ptr += linesize;
309  }
310  break;
311  case 8:
312  case 24:
313  case 32:
314  for (i = 0; i < avctx->height; i++) {
315  memcpy(ptr, buf, n);
316  buf += n;
317  ptr += linesize;
318  }
319  break;
320  case 4:
321  for (i = 0; i < avctx->height; i++) {
322  int j;
323  for (j = 0; j < n; j++) {
324  ptr[j*2+0] = (buf[j] >> 4) & 0xF;
325  ptr[j*2+1] = buf[j] & 0xF;
326  }
327  buf += n;
328  ptr += linesize;
329  }
330  break;
331  case 16:
332  for (i = 0; i < avctx->height; i++) {
333  const uint16_t *src = (const uint16_t *) buf;
334  uint16_t *dst = (uint16_t *) ptr;
335 
336  for (j = 0; j < avctx->width; j++)
337  *dst++ = av_le2ne16(*src++);
338 
339  buf += n;
340  ptr += linesize;
341  }
342  break;
343  default:
344  av_log(avctx, AV_LOG_ERROR, "BMP decoder is broken\n");
345  return AVERROR_INVALIDDATA;
346  }
347  }
348  if (avctx->pix_fmt == AV_PIX_FMT_BGRA) {
349  for (i = 0; i < avctx->height; i++) {
350  int j;
351  uint8_t *ptr = p->data[0] + p->linesize[0]*i + 3;
352  for (j = 0; j < avctx->width; j++) {
353  if (ptr[4*j])
354  break;
355  }
356  if (j < avctx->width)
357  break;
358  }
359  if (i == avctx->height)
360  avctx->pix_fmt = p->format = AV_PIX_FMT_BGR0;
361  }
362 
363  *got_frame = 1;
364 
365  return buf_size;
366 }
367 
369  .name = "bmp",
370  .long_name = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"),
371  .type = AVMEDIA_TYPE_VIDEO,
372  .id = AV_CODEC_ID_BMP,
373  .decode = bmp_decode_frame,
374  .capabilities = AV_CODEC_CAP_DR1,
375 };
AVCodec
AVCodec.
Definition: codec.h:202
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
comp
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
Definition: eamad.c:85
GetByteContext
Definition: bytestream.h:33
BMP_RLE4
@ BMP_RLE4
Definition: bmp.h:28
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:310
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:373
data
const char data[16]
Definition: mxf.c:143
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:26
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:329
rgb
Definition: rpzaenc.c:59
U
#define U(x)
Definition: vp56_arith.h:37
AVFrame::key_frame
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:400
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
ff_bmp_decoder
const AVCodec ff_bmp_decoder
Definition: bmp.c:368
width
#define width
AV_CODEC_ID_BMP
@ AV_CODEC_ID_BMP
Definition: codec_id.h:128
fsize
static int64_t fsize(FILE *f)
Definition: audiomatch.c:29
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:93
bmp.h
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
msrledec.h
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
src
#define src
Definition: vp8dsp.c:255
AV_PIX_FMT_BGR0
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
Definition: pixfmt.h:230
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
BiCompression
BiCompression
Definition: bmp.h:25
AV_PIX_FMT_ABGR
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:94
AVFrame::pict_type
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:405
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1651
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
AVPacket::size
int size
Definition: packet.h:374
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:29
avpriv_report_missing_feature
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:395
av_le2ne16
#define av_le2ne16(x)
Definition: bswap.h:95
height
#define height
AV_PIX_FMT_RGB0
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition: pixfmt.h:228
AV_PIX_FMT_ARGB
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:92
bmp_decode_frame
static int bmp_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: bmp.c:30
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
BMP_RLE8
@ BMP_RLE8
Definition: bmp.h:27
AV_PIX_FMT_RGB555
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:379
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:209
AVCodecContext::height
int height
Definition: avcodec.h:556
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:593
AV_PIX_FMT_RGB565
#define AV_PIX_FMT_RGB565
Definition: pixfmt.h:378
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
AV_PIX_FMT_0BGR
@ AV_PIX_FMT_0BGR
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
Definition: pixfmt.h:229
AVCodecContext
main external API structure.
Definition: avcodec.h:383
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
ff_set_dimensions
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
Definition: utils.c:86
ff_msrle_decode
int ff_msrle_decode(AVCodecContext *avctx, AVFrame *pic, int depth, GetByteContext *gb)
Decode stream in MS RLE format into frame.
Definition: msrledec.c:249
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
AVPacket
This structure stores compressed data.
Definition: packet.h:350
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:556
bytestream.h
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:353
AV_PIX_FMT_0RGB
@ AV_PIX_FMT_0RGB
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
Definition: pixfmt.h:227
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
AV_PIX_FMT_RGB444
#define AV_PIX_FMT_RGB444
Definition: pixfmt.h:380