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)
148  avctx->pix_fmt = alpha ? AV_PIX_FMT_ABGR : AV_PIX_FMT_0BGR;
149  else if (rgb[0] == 0x00FF0000 && rgb[1] == 0x0000FF00 && rgb[2] == 0x000000FF)
150  avctx->pix_fmt = alpha ? AV_PIX_FMT_BGRA : AV_PIX_FMT_BGR0;
151  else if (rgb[0] == 0x0000FF00 && rgb[1] == 0x00FF0000 && rgb[2] == 0xFF000000)
152  avctx->pix_fmt = alpha ? AV_PIX_FMT_ARGB : AV_PIX_FMT_0RGB;
153  else if (rgb[0] == 0x000000FF && rgb[1] == 0x0000FF00 && rgb[2] == 0x00FF0000)
154  avctx->pix_fmt = alpha ? AV_PIX_FMT_RGBA : AV_PIX_FMT_RGB0;
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 };
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
This structure describes decoded (raw) audio or video data.
Definition: frame.h:268
int ff_msrle_decode(AVCodecContext *avctx, AVFrame *pic, int depth, GetByteContext *gb)
Decode stream in MS RLE format into frame.
Definition: msrledec.c:249
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
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:104
int size
Definition: avcodec.h:1478
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1775
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:133
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
Definition: pixfmt.h:239
#define AV_PIX_FMT_RGB444
Definition: pixfmt.h:376
#define src
Definition: vp8dsp.c:254
AVCodec.
Definition: avcodec.h:3477
uint8_t
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition: pixfmt.h:238
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:77
Definition: bmp.h:29
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:94
#define height
uint8_t * data
Definition: avcodec.h:1477
#define av_log(a,...)
#define U(x)
Definition: vp56_arith.h:37
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:260
static int bmp_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: bmp.c:30
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#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
const char * name
Name of the codec implementation.
Definition: avcodec.h:3484
Definition: bmp.h:30
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:92
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:93
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:351
#define FFMIN(a, b)
Definition: common.h:96
#define width
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
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
Definition: eamad.c:83
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:341
Libavcodec external API header.
#define av_le2ne16(x)
Definition: bswap.h:95
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:299
static const int16_t alpha[]
Definition: ilbcdata.h:55
main external API structure.
Definition: avcodec.h:1565
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1964
void * buf
Definition: avisynth_c.h:766
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
Definition: pixfmt.h:240
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
Definition: bmp.h:28
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:282
Y , 8bpp.
Definition: pixfmt.h:74
common internal api header.
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:375
BiCompression
Definition: bmp.h:27
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:346
#define AV_PIX_FMT_RGB565
Definition: pixfmt.h:374
AVCodec ff_bmp_decoder
Definition: bmp.c:368
static int64_t fsize(FILE *f)
Definition: audiomatch.c:28
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
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
Definition: pixfmt.h:237
This structure stores compressed data.
Definition: avcodec.h:1454
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:981