Libav
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 Libav.
6  *
7  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "avcodec.h"
23 #include "bytestream.h"
24 #include "bmp.h"
25 #include "internal.h"
26 #include "msrledec.h"
27 
28 static int bmp_decode_frame(AVCodecContext *avctx,
29  void *data, int *got_frame,
30  AVPacket *avpkt)
31 {
32  const uint8_t *buf = avpkt->data;
33  int buf_size = avpkt->size;
34  AVFrame *p = data;
35  unsigned int fsize, hsize;
36  int width, height;
37  unsigned int depth;
39  unsigned int ihsize;
40  int i, j, n, linesize, ret;
41  uint32_t rgb[3];
42  uint8_t *ptr;
43  int dsize;
44  const uint8_t *buf0 = buf;
45  GetByteContext gb;
46 
47  if (buf_size < 14) {
48  av_log(avctx, AV_LOG_ERROR, "buf size too small (%d)\n", buf_size);
49  return AVERROR_INVALIDDATA;
50  }
51 
52  if (bytestream_get_byte(&buf) != 'B' ||
53  bytestream_get_byte(&buf) != 'M') {
54  av_log(avctx, AV_LOG_ERROR, "bad magic number\n");
55  return AVERROR_INVALIDDATA;
56  }
57 
58  fsize = bytestream_get_le32(&buf);
59  if (buf_size < fsize) {
60  av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d), trying to decode anyway\n",
61  buf_size, fsize);
62  fsize = buf_size;
63  }
64 
65  buf += 2; /* reserved1 */
66  buf += 2; /* reserved2 */
67 
68  hsize = bytestream_get_le32(&buf); /* header size */
69  ihsize = bytestream_get_le32(&buf); /* more header size */
70  if (ihsize + 14 > hsize) {
71  av_log(avctx, AV_LOG_ERROR, "invalid header size %d\n", hsize);
72  return AVERROR_INVALIDDATA;
73  }
74 
75  /* sometimes file size is set to some headers size, set a real size in that case */
76  if (fsize == 14 || fsize == ihsize + 14)
77  fsize = buf_size - 2;
78 
79  if (fsize <= hsize) {
80  av_log(avctx, AV_LOG_ERROR, "declared file size is less than header size (%d < %d)\n",
81  fsize, hsize);
82  return AVERROR_INVALIDDATA;
83  }
84 
85  switch (ihsize) {
86  case 40: // windib v3
87  case 64: // OS/2 v2
88  case 108: // windib v4
89  case 124: // windib v5
90  width = bytestream_get_le32(&buf);
91  height = bytestream_get_le32(&buf);
92  break;
93  case 12: // OS/2 v1
94  width = bytestream_get_le16(&buf);
95  height = bytestream_get_le16(&buf);
96  break;
97  default:
98  av_log(avctx, AV_LOG_ERROR, "unsupported BMP file, patch welcome\n");
99  return AVERROR_PATCHWELCOME;
100  }
101 
102  /* planes */
103  if (bytestream_get_le16(&buf) != 1) {
104  av_log(avctx, AV_LOG_ERROR, "invalid BMP header\n");
105  return AVERROR_INVALIDDATA;
106  }
107 
108  depth = bytestream_get_le16(&buf);
109 
110  if (ihsize == 40)
111  comp = bytestream_get_le32(&buf);
112  else
113  comp = BMP_RGB;
114 
115  if (comp != BMP_RGB && comp != BMP_BITFIELDS && comp != BMP_RLE4 &&
116  comp != BMP_RLE8) {
117  av_log(avctx, AV_LOG_ERROR, "BMP coding %d not supported\n", comp);
118  return AVERROR_INVALIDDATA;
119  }
120 
121  if (comp == BMP_BITFIELDS) {
122  buf += 20;
123  rgb[0] = bytestream_get_le32(&buf);
124  rgb[1] = bytestream_get_le32(&buf);
125  rgb[2] = bytestream_get_le32(&buf);
126  }
127 
128  avctx->width = width;
129  avctx->height = height > 0 ? height : -height;
130 
131  avctx->pix_fmt = AV_PIX_FMT_NONE;
132 
133  switch (depth) {
134  case 32:
135  if (comp == BMP_BITFIELDS) {
136  rgb[0] = (rgb[0] >> 15) & 3;
137  rgb[1] = (rgb[1] >> 15) & 3;
138  rgb[2] = (rgb[2] >> 15) & 3;
139 
140  if (rgb[0] + rgb[1] + rgb[2] != 3 ||
141  rgb[0] == rgb[1] || rgb[0] == rgb[2] || rgb[1] == rgb[2]) {
142  break;
143  }
144  } else {
145  rgb[0] = 2;
146  rgb[1] = 1;
147  rgb[2] = 0;
148  }
149 
150  avctx->pix_fmt = AV_PIX_FMT_BGR24;
151  break;
152  case 24:
153  avctx->pix_fmt = AV_PIX_FMT_BGR24;
154  break;
155  case 16:
156  if (comp == BMP_RGB)
157  avctx->pix_fmt = AV_PIX_FMT_RGB555;
158  else if (comp == BMP_BITFIELDS) {
159  if (rgb[0] == 0xF800 && rgb[1] == 0x07E0 && rgb[2] == 0x001F)
160  avctx->pix_fmt = AV_PIX_FMT_RGB565;
161  else if (rgb[0] == 0x7C00 && rgb[1] == 0x03E0 && rgb[2] == 0x001F)
162  avctx->pix_fmt = AV_PIX_FMT_RGB555;
163  else if (rgb[0] == 0x0F00 && rgb[1] == 0x00F0 && rgb[2] == 0x000F)
164  avctx->pix_fmt = AV_PIX_FMT_RGB444;
165  else {
166  av_log(avctx, AV_LOG_ERROR, "Unknown bitfields %0X %0X %0X\n", rgb[0], rgb[1], rgb[2]);
167  return AVERROR(EINVAL);
168  }
169  }
170  break;
171  case 8:
172  if (hsize - ihsize - 14 > 0)
173  avctx->pix_fmt = AV_PIX_FMT_PAL8;
174  else
175  avctx->pix_fmt = AV_PIX_FMT_GRAY8;
176  break;
177  case 1:
178  case 4:
179  if (hsize - ihsize - 14 > 0) {
180  avctx->pix_fmt = AV_PIX_FMT_PAL8;
181  } else {
182  av_log(avctx, AV_LOG_ERROR, "Unknown palette for %d-colour BMP\n", 1<<depth);
183  return AVERROR_INVALIDDATA;
184  }
185  break;
186  default:
187  av_log(avctx, AV_LOG_ERROR, "depth %d not supported\n", depth);
188  return AVERROR_INVALIDDATA;
189  }
190 
191  if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
192  av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n");
193  return AVERROR_INVALIDDATA;
194  }
195 
196  if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
197  av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
198  return ret;
199  }
201  p->key_frame = 1;
202 
203  buf = buf0 + hsize;
204  dsize = buf_size - hsize;
205 
206  /* Line size in file multiple of 4 */
207  n = ((avctx->width * depth) / 8 + 3) & ~3;
208 
209  if (n * avctx->height > dsize && comp != BMP_RLE4 && comp != BMP_RLE8) {
210  av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n",
211  dsize, n * avctx->height);
212  return AVERROR_INVALIDDATA;
213  }
214 
215  // RLE may skip decoding some picture areas, so blank picture before decoding
216  if (comp == BMP_RLE4 || comp == BMP_RLE8)
217  memset(p->data[0], 0, avctx->height * p->linesize[0]);
218 
219  if (height > 0) {
220  ptr = p->data[0] + (avctx->height - 1) * p->linesize[0];
221  linesize = -p->linesize[0];
222  } else {
223  ptr = p->data[0];
224  linesize = p->linesize[0];
225  }
226 
227  if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
228  int colors = 1 << depth;
229 
230  memset(p->data[1], 0, 1024);
231 
232  if (ihsize >= 36) {
233  int t;
234  buf = buf0 + 46;
235  t = bytestream_get_le32(&buf);
236  if (t < 0 || t > (1 << depth)) {
237  av_log(avctx, AV_LOG_ERROR, "Incorrect number of colors - %X for bitdepth %d\n", t, depth);
238  } else if (t) {
239  colors = t;
240  }
241  }
242  buf = buf0 + 14 + ihsize; //palette location
243  // OS/2 bitmap, 3 bytes per palette entry
244  if ((hsize-ihsize-14) < (colors << 2)) {
245  for (i = 0; i < colors; i++)
246  ((uint32_t*)p->data[1])[i] = bytestream_get_le24(&buf);
247  } else {
248  for (i = 0; i < colors; i++)
249  ((uint32_t*)p->data[1])[i] = bytestream_get_le32(&buf);
250  }
251  buf = buf0 + hsize;
252  }
253  if (comp == BMP_RLE4 || comp == BMP_RLE8) {
254  if (height < 0) {
255  p->data[0] += p->linesize[0] * (avctx->height - 1);
256  p->linesize[0] = -p->linesize[0];
257  }
258  bytestream2_init(&gb, buf, dsize);
259  ff_msrle_decode(avctx, (AVPicture*)p, depth, &gb);
260  if (height < 0) {
261  p->data[0] += p->linesize[0] * (avctx->height - 1);
262  p->linesize[0] = -p->linesize[0];
263  }
264  } else {
265  switch (depth) {
266  case 1:
267  for (i = 0; i < avctx->height; i++) {
268  int j;
269  for (j = 0; j < n; j++) {
270  ptr[j*8+0] = buf[j] >> 7;
271  ptr[j*8+1] = (buf[j] >> 6) & 1;
272  ptr[j*8+2] = (buf[j] >> 5) & 1;
273  ptr[j*8+3] = (buf[j] >> 4) & 1;
274  ptr[j*8+4] = (buf[j] >> 3) & 1;
275  ptr[j*8+5] = (buf[j] >> 2) & 1;
276  ptr[j*8+6] = (buf[j] >> 1) & 1;
277  ptr[j*8+7] = buf[j] & 1;
278  }
279  buf += n;
280  ptr += linesize;
281  }
282  break;
283  case 8:
284  case 24:
285  for (i = 0; i < avctx->height; i++) {
286  memcpy(ptr, buf, n);
287  buf += n;
288  ptr += linesize;
289  }
290  break;
291  case 4:
292  for (i = 0; i < avctx->height; i++) {
293  int j;
294  for (j = 0; j < n; j++) {
295  ptr[j*2+0] = (buf[j] >> 4) & 0xF;
296  ptr[j*2+1] = buf[j] & 0xF;
297  }
298  buf += n;
299  ptr += linesize;
300  }
301  break;
302  case 16:
303  for (i = 0; i < avctx->height; i++) {
304  const uint16_t *src = (const uint16_t *) buf;
305  uint16_t *dst = (uint16_t *) ptr;
306 
307  for (j = 0; j < avctx->width; j++)
308  *dst++ = av_le2ne16(*src++);
309 
310  buf += n;
311  ptr += linesize;
312  }
313  break;
314  case 32:
315  for (i = 0; i < avctx->height; i++) {
316  const uint8_t *src = buf;
317  uint8_t *dst = ptr;
318 
319  for (j = 0; j < avctx->width; j++) {
320  dst[0] = src[rgb[2]];
321  dst[1] = src[rgb[1]];
322  dst[2] = src[rgb[0]];
323  dst += 3;
324  src += 4;
325  }
326 
327  buf += n;
328  ptr += linesize;
329  }
330  break;
331  default:
332  av_log(avctx, AV_LOG_ERROR, "BMP decoder is broken\n");
333  return AVERROR_INVALIDDATA;
334  }
335  }
336 
337  *got_frame = 1;
338 
339  return buf_size;
340 }
341 
343  .name = "bmp",
344  .long_name = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"),
345  .type = AVMEDIA_TYPE_VIDEO,
346  .id = AV_CODEC_ID_BMP,
347  .decode = bmp_decode_frame,
348  .capabilities = CODEC_CAP_DR1,
349 };
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:54
This structure describes decoded (raw) audio or video data.
Definition: frame.h:107
int size
Definition: avcodec.h:974
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1247
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:130
#define AV_PIX_FMT_RGB444
Definition: pixfmt.h:215
four components are given, that's all.
Definition: avcodec.h:2950
AVCodec.
Definition: avcodec.h:2755
uint8_t
8 bit with PIX_FMT_RGB32 palette
Definition: pixfmt.h:76
Definition: bmp.h:29
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:711
const char data[16]
Definition: mxf.c:66
uint8_t * data
Definition: avcodec.h:973
static float t
Definition: output.c:52
static int bmp_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: bmp.c:28
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:123
#define AVERROR(e)
Definition: error.h:43
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:142
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:148
const char * name
Name of the codec implementation.
Definition: avcodec.h:2762
Definition: bmp.h:30
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:168
int width
picture width / height.
Definition: avcodec.h:1217
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:68
#define AVERROR_PATCHWELCOME
Not yet implemented in Libav, patches welcome.
Definition: error.h:57
static int width
Definition: utils.c:156
Libavcodec external API header.
#define av_le2ne16(x)
Definition: bswap.h:97
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:125
main external API structure.
Definition: avcodec.h:1054
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: utils.c:575
Definition: bmp.h:28
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:113
int height
Definition: gxfenc.c:72
Y , 8bpp.
Definition: pixfmt.h:73
common internal api header.
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:214
BiCompression
Definition: bmp.h:27
int ff_msrle_decode(AVCodecContext *avctx, AVPicture *pic, int depth, GetByteContext *gb)
Decode stream in MS RLE format into frame.
Definition: msrledec.c:246
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:163
#define AV_PIX_FMT_RGB565
Definition: pixfmt.h:213
AVCodec ff_bmp_decoder
Definition: bmp.c:342
static void comp(unsigned char *dst, int dst_stride, unsigned char *src, int src_stride, int add)
Definition: eamad.c:77
This structure stores compressed data.
Definition: avcodec.h:950