annotate bmp.c @ 12530:63edd10ad4bc libavcodec tip

Try to fix crashes introduced by r25218 r25218 made assumptions about the existence of past reference frames that weren't necessarily true.
author darkshikari
date Tue, 28 Sep 2010 09:06:22 +0000
parents 8b28e74de2c0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
1 /*
4415
f792b146869b Segregate code common to BMP decoder and future encoder
diego
parents: 4394
diff changeset
2 * BMP image format decoder
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
3 * Copyright (c) 2005 Mans Rullgard
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
4 *
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
5 * This file is part of FFmpeg.
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
6 *
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
11 *
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
15 * Lesser General Public License for more details.
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
16 *
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
3036
0b546eab515d Update licensing information: The FSF changed postal address.
diego
parents: 2967
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
20 */
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
21
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
22 #include "avcodec.h"
4439
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
23 #include "bytestream.h"
4415
f792b146869b Segregate code common to BMP decoder and future encoder
diego
parents: 4394
diff changeset
24 #include "bmp.h"
7910
87bbd8322244 Add RLE4 and RLE8 decoding support for BMP
kostya
parents: 7909
diff changeset
25 #include "msrledec.h"
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
26
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6265
diff changeset
27 static av_cold int bmp_decode_init(AVCodecContext *avctx){
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
28 BMPContext *s = avctx->priv_data;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
29
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
30 avcodec_get_frame_defaults((AVFrame*)&s->picture);
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
31 avctx->coded_frame = (AVFrame*)&s->picture;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
32
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
33 return 0;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
34 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
35
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2949
diff changeset
36 static int bmp_decode_frame(AVCodecContext *avctx,
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
37 void *data, int *data_size,
9355
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 9261
diff changeset
38 AVPacket *avpkt)
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
39 {
9355
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 9261
diff changeset
40 const uint8_t *buf = avpkt->data;
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 9261
diff changeset
41 int buf_size = avpkt->size;
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
42 BMPContext *s = avctx->priv_data;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
43 AVFrame *picture = data;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
44 AVFrame *p = &s->picture;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
45 unsigned int fsize, hsize;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
46 int width, height;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
47 unsigned int depth;
4393
michael
parents: 4109
diff changeset
48 BiCompression comp;
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
49 unsigned int ihsize;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
50 int i, j, n, linesize;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
51 uint32_t rgb[3];
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
52 uint8_t *ptr;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
53 int dsize;
6265
michael
parents: 5327
diff changeset
54 const uint8_t *buf0 = buf;
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
55
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
56 if(buf_size < 14){
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
57 av_log(avctx, AV_LOG_ERROR, "buf size too small (%d)\n", buf_size);
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
58 return -1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
59 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
60
4439
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
61 if(bytestream_get_byte(&buf) != 'B' ||
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
62 bytestream_get_byte(&buf) != 'M') {
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
63 av_log(avctx, AV_LOG_ERROR, "bad magic number\n");
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
64 return -1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
65 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
66
4439
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
67 fsize = bytestream_get_le32(&buf);
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
68 if(buf_size < fsize){
8945
3ce78c919959 Make BMP decoder try to decode files with incorrect filesize field value
kostya
parents: 8720
diff changeset
69 av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d), trying to decode anyway\n",
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
70 buf_size, fsize);
8945
3ce78c919959 Make BMP decoder try to decode files with incorrect filesize field value
kostya
parents: 8720
diff changeset
71 fsize = buf_size;
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
72 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
73
4439
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
74 buf += 2; /* reserved1 */
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
75 buf += 2; /* reserved2 */
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
76
4439
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
77 hsize = bytestream_get_le32(&buf); /* header size */
8204
507854688c43 Some BMP files have file size declared in the header equal to headers size
kostya
parents: 8203
diff changeset
78 ihsize = bytestream_get_le32(&buf); /* more header size */
507854688c43 Some BMP files have file size declared in the header equal to headers size
kostya
parents: 8203
diff changeset
79 if(ihsize + 14 > hsize){
507854688c43 Some BMP files have file size declared in the header equal to headers size
kostya
parents: 8203
diff changeset
80 av_log(avctx, AV_LOG_ERROR, "invalid header size %d\n", hsize);
507854688c43 Some BMP files have file size declared in the header equal to headers size
kostya
parents: 8203
diff changeset
81 return -1;
507854688c43 Some BMP files have file size declared in the header equal to headers size
kostya
parents: 8203
diff changeset
82 }
507854688c43 Some BMP files have file size declared in the header equal to headers size
kostya
parents: 8203
diff changeset
83
507854688c43 Some BMP files have file size declared in the header equal to headers size
kostya
parents: 8203
diff changeset
84 /* sometimes file size is set to some headers size, set a real size in that case */
507854688c43 Some BMP files have file size declared in the header equal to headers size
kostya
parents: 8203
diff changeset
85 if(fsize == 14 || fsize == ihsize + 14)
507854688c43 Some BMP files have file size declared in the header equal to headers size
kostya
parents: 8203
diff changeset
86 fsize = buf_size - 2;
507854688c43 Some BMP files have file size declared in the header equal to headers size
kostya
parents: 8203
diff changeset
87
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
88 if(fsize <= hsize){
8203
3b90f93d97a6 Give more meaningful message on BMP header parsing error
kostya
parents: 8202
diff changeset
89 av_log(avctx, AV_LOG_ERROR, "declared file size is less than header size (%d < %d)\n",
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
90 fsize, hsize);
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
91 return -1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
92 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
93
8202
5af44bd71254 Add known BMP header sizes.
kostya
parents: 7911
diff changeset
94 switch(ihsize){
5af44bd71254 Add known BMP header sizes.
kostya
parents: 7911
diff changeset
95 case 40: // windib v3
5af44bd71254 Add known BMP header sizes.
kostya
parents: 7911
diff changeset
96 case 64: // OS/2 v2
5af44bd71254 Add known BMP header sizes.
kostya
parents: 7911
diff changeset
97 case 108: // windib v4
5af44bd71254 Add known BMP header sizes.
kostya
parents: 7911
diff changeset
98 case 124: // windib v5
6595
92eb6af449dc Indentation
benoit
parents: 6594
diff changeset
99 width = bytestream_get_le32(&buf);
92eb6af449dc Indentation
benoit
parents: 6594
diff changeset
100 height = bytestream_get_le32(&buf);
8202
5af44bd71254 Add known BMP header sizes.
kostya
parents: 7911
diff changeset
101 break;
5af44bd71254 Add known BMP header sizes.
kostya
parents: 7911
diff changeset
102 case 12: // OS/2 v1
6594
e094b1b11e1d Support for BMP os2v1.
benoit
parents: 6517
diff changeset
103 width = bytestream_get_le16(&buf);
e094b1b11e1d Support for BMP os2v1.
benoit
parents: 6517
diff changeset
104 height = bytestream_get_le16(&buf);
8202
5af44bd71254 Add known BMP header sizes.
kostya
parents: 7911
diff changeset
105 break;
5af44bd71254 Add known BMP header sizes.
kostya
parents: 7911
diff changeset
106 default:
7887
44da2504ce69 add newline at the end of message
kostya
parents: 7040
diff changeset
107 av_log(avctx, AV_LOG_ERROR, "unsupported BMP file, patch welcome\n");
6594
e094b1b11e1d Support for BMP os2v1.
benoit
parents: 6517
diff changeset
108 return -1;
e094b1b11e1d Support for BMP os2v1.
benoit
parents: 6517
diff changeset
109 }
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
110
4439
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
111 if(bytestream_get_le16(&buf) != 1){ /* planes */
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
112 av_log(avctx, AV_LOG_ERROR, "invalid BMP header\n");
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
113 return -1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
114 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
115
4439
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
116 depth = bytestream_get_le16(&buf);
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
117
6594
e094b1b11e1d Support for BMP os2v1.
benoit
parents: 6517
diff changeset
118 if(ihsize == 40)
4439
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
119 comp = bytestream_get_le32(&buf);
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
120 else
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
121 comp = BMP_RGB;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
122
7910
87bbd8322244 Add RLE4 and RLE8 decoding support for BMP
kostya
parents: 7909
diff changeset
123 if(comp != BMP_RGB && comp != BMP_BITFIELDS && comp != BMP_RLE4 && comp != BMP_RLE8){
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
124 av_log(avctx, AV_LOG_ERROR, "BMP coding %d not supported\n", comp);
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
125 return -1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
126 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
127
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
128 if(comp == BMP_BITFIELDS){
4439
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
129 buf += 20;
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
130 rgb[0] = bytestream_get_le32(&buf);
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
131 rgb[1] = bytestream_get_le32(&buf);
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
132 rgb[2] = bytestream_get_le32(&buf);
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
133 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
134
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
135 avctx->width = width;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
136 avctx->height = height > 0? height: -height;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
137
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
138 avctx->pix_fmt = PIX_FMT_NONE;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
139
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
140 switch(depth){
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
141 case 32:
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
142 if(comp == BMP_BITFIELDS){
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
143 rgb[0] = (rgb[0] >> 15) & 3;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
144 rgb[1] = (rgb[1] >> 15) & 3;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
145 rgb[2] = (rgb[2] >> 15) & 3;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
146
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
147 if(rgb[0] + rgb[1] + rgb[2] != 3 ||
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
148 rgb[0] == rgb[1] || rgb[0] == rgb[2] || rgb[1] == rgb[2]){
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
149 break;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
150 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
151 } else {
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
152 rgb[0] = 2;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
153 rgb[1] = 1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
154 rgb[2] = 0;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
155 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
156
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
157 avctx->pix_fmt = PIX_FMT_BGR24;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
158 break;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
159 case 24:
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
160 avctx->pix_fmt = PIX_FMT_BGR24;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
161 break;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
162 case 16:
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
163 if(comp == BMP_RGB)
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
164 avctx->pix_fmt = PIX_FMT_RGB555;
7909
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
165 if(comp == BMP_BITFIELDS)
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
166 avctx->pix_fmt = rgb[1] == 0x07E0 ? PIX_FMT_RGB565 : PIX_FMT_RGB555;
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
167 break;
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
168 case 8:
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
169 if(hsize - ihsize - 14 > 0)
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
170 avctx->pix_fmt = PIX_FMT_PAL8;
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
171 else
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
172 avctx->pix_fmt = PIX_FMT_GRAY8;
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
173 break;
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
174 case 4:
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
175 if(hsize - ihsize - 14 > 0){
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
176 avctx->pix_fmt = PIX_FMT_PAL8;
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
177 }else{
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
178 av_log(avctx, AV_LOG_ERROR, "Unknown palette for 16-colour BMP\n");
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
179 return -1;
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
180 }
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
181 break;
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
182 case 1:
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
183 avctx->pix_fmt = PIX_FMT_MONOBLACK;
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
184 break;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
185 default:
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
186 av_log(avctx, AV_LOG_ERROR, "depth %d not supported\n", depth);
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
187 return -1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
188 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
189
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
190 if(avctx->pix_fmt == PIX_FMT_NONE){
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
191 av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n");
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
192 return -1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
193 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
194
4432
a848b652f0ac Fix segfault in bmp decoder. Patch by Michel Bardiaux mbardiaux mediaxim dot be.
takis
parents: 4415
diff changeset
195 if(p->data[0])
a848b652f0ac Fix segfault in bmp decoder. Patch by Michel Bardiaux mbardiaux mediaxim dot be.
takis
parents: 4415
diff changeset
196 avctx->release_buffer(avctx, p);
a848b652f0ac Fix segfault in bmp decoder. Patch by Michel Bardiaux mbardiaux mediaxim dot be.
takis
parents: 4415
diff changeset
197
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
198 p->reference = 0;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
199 if(avctx->get_buffer(avctx, p) < 0){
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
200 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
201 return -1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
202 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
203 p->pict_type = FF_I_TYPE;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
204 p->key_frame = 1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
205
4439
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
206 buf = buf0 + hsize;
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
207 dsize = buf_size - hsize;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
208
4109
a90490a13ac4 coded line size is a multiple of 4
mru
parents: 3947
diff changeset
209 /* Line size in file multiple of 4 */
7908
dc825905f93f Calculate line size correctly for bit depths < 8
kostya
parents: 7887
diff changeset
210 n = ((avctx->width * depth) / 8 + 3) & ~3;
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
211
7910
87bbd8322244 Add RLE4 and RLE8 decoding support for BMP
kostya
parents: 7909
diff changeset
212 if(n * avctx->height > dsize && comp != BMP_RLE4 && comp != BMP_RLE8){
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
213 av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n",
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
214 dsize, n * avctx->height);
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
215 return -1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
216 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
217
7910
87bbd8322244 Add RLE4 and RLE8 decoding support for BMP
kostya
parents: 7909
diff changeset
218 // RLE may skip decoding some picture areas, so blank picture before decoding
87bbd8322244 Add RLE4 and RLE8 decoding support for BMP
kostya
parents: 7909
diff changeset
219 if(comp == BMP_RLE4 || comp == BMP_RLE8)
87bbd8322244 Add RLE4 and RLE8 decoding support for BMP
kostya
parents: 7909
diff changeset
220 memset(p->data[0], 0, avctx->height * p->linesize[0]);
87bbd8322244 Add RLE4 and RLE8 decoding support for BMP
kostya
parents: 7909
diff changeset
221
7909
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
222 if(depth == 4 || depth == 8)
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
223 memset(p->data[1], 0, 1024);
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
224
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
225 if(height > 0){
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
226 ptr = p->data[0] + (avctx->height - 1) * p->linesize[0];
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
227 linesize = -p->linesize[0];
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
228 } else {
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
229 ptr = p->data[0];
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
230 linesize = p->linesize[0];
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
231 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
232
7909
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
233 if(avctx->pix_fmt == PIX_FMT_PAL8){
10257
af449680f6ee Take into account real number of colours when reading BMP palette.
kostya
parents: 9798
diff changeset
234 int colors = 1 << depth;
af449680f6ee Take into account real number of colours when reading BMP palette.
kostya
parents: 9798
diff changeset
235 if(ihsize >= 36){
af449680f6ee Take into account real number of colours when reading BMP palette.
kostya
parents: 9798
diff changeset
236 int t;
af449680f6ee Take into account real number of colours when reading BMP palette.
kostya
parents: 9798
diff changeset
237 buf = buf0 + 46;
af449680f6ee Take into account real number of colours when reading BMP palette.
kostya
parents: 9798
diff changeset
238 t = bytestream_get_le32(&buf);
af449680f6ee Take into account real number of colours when reading BMP palette.
kostya
parents: 9798
diff changeset
239 if(t < 0 || t > (1 << depth)){
af449680f6ee Take into account real number of colours when reading BMP palette.
kostya
parents: 9798
diff changeset
240 av_log(avctx, AV_LOG_ERROR, "Incorrect number of colors - %X for bitdepth %d\n", t, depth);
af449680f6ee Take into account real number of colours when reading BMP palette.
kostya
parents: 9798
diff changeset
241 }else if(t){
af449680f6ee Take into account real number of colours when reading BMP palette.
kostya
parents: 9798
diff changeset
242 colors = t;
af449680f6ee Take into account real number of colours when reading BMP palette.
kostya
parents: 9798
diff changeset
243 }
af449680f6ee Take into account real number of colours when reading BMP palette.
kostya
parents: 9798
diff changeset
244 }
7909
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
245 buf = buf0 + 14 + ihsize; //palette location
10257
af449680f6ee Take into account real number of colours when reading BMP palette.
kostya
parents: 9798
diff changeset
246 if((hsize-ihsize-14) < (colors << 2)){ // OS/2 bitmap, 3 bytes per palette entry
af449680f6ee Take into account real number of colours when reading BMP palette.
kostya
parents: 9798
diff changeset
247 for(i = 0; i < colors; i++)
7909
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
248 ((uint32_t*)p->data[1])[i] = bytestream_get_le24(&buf);
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
249 }else{
10257
af449680f6ee Take into account real number of colours when reading BMP palette.
kostya
parents: 9798
diff changeset
250 for(i = 0; i < colors; i++)
7909
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
251 ((uint32_t*)p->data[1])[i] = bytestream_get_le32(&buf);
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
252 }
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
253 buf = buf0 + hsize;
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
254 }
7910
87bbd8322244 Add RLE4 and RLE8 decoding support for BMP
kostya
parents: 7909
diff changeset
255 if(comp == BMP_RLE4 || comp == BMP_RLE8){
10335
3b0a2384ff9f Make BMP decoder produce flipped picture with RLE compression.
kostya
parents: 10257
diff changeset
256 if(height < 0){
3b0a2384ff9f Make BMP decoder produce flipped picture with RLE compression.
kostya
parents: 10257
diff changeset
257 p->data[0] += p->linesize[0] * (avctx->height - 1);
3b0a2384ff9f Make BMP decoder produce flipped picture with RLE compression.
kostya
parents: 10257
diff changeset
258 p->linesize[0] = -p->linesize[0];
3b0a2384ff9f Make BMP decoder produce flipped picture with RLE compression.
kostya
parents: 10257
diff changeset
259 }
8720
052c676c433b Silence useless compiler warning when passing AVFrame* instead of AVPicture*
kostya
parents: 8204
diff changeset
260 ff_msrle_decode(avctx, (AVPicture*)p, depth, buf, dsize);
10335
3b0a2384ff9f Make BMP decoder produce flipped picture with RLE compression.
kostya
parents: 10257
diff changeset
261 if(height < 0){
3b0a2384ff9f Make BMP decoder produce flipped picture with RLE compression.
kostya
parents: 10257
diff changeset
262 p->data[0] += p->linesize[0] * (avctx->height - 1);
3b0a2384ff9f Make BMP decoder produce flipped picture with RLE compression.
kostya
parents: 10257
diff changeset
263 p->linesize[0] = -p->linesize[0];
3b0a2384ff9f Make BMP decoder produce flipped picture with RLE compression.
kostya
parents: 10257
diff changeset
264 }
7910
87bbd8322244 Add RLE4 and RLE8 decoding support for BMP
kostya
parents: 7909
diff changeset
265 }else{
7911
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
266 switch(depth){
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
267 case 1:
9261
931bb51f060e Merge some cases for reading raw data with different bit depths in BMP
kostya
parents: 8945
diff changeset
268 case 8:
931bb51f060e Merge some cases for reading raw data with different bit depths in BMP
kostya
parents: 8945
diff changeset
269 case 24:
7911
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
270 for(i = 0; i < avctx->height; i++){
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
271 memcpy(ptr, buf, n);
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
272 buf += n;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
273 ptr += linesize;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
274 }
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
275 break;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
276 case 4:
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
277 for(i = 0; i < avctx->height; i++){
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
278 int j;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
279 for(j = 0; j < n; j++){
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
280 ptr[j*2+0] = (buf[j] >> 4) & 0xF;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
281 ptr[j*2+1] = buf[j] & 0xF;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
282 }
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
283 buf += n;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
284 ptr += linesize;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
285 }
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
286 break;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
287 case 16:
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
288 for(i = 0; i < avctx->height; i++){
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
289 const uint16_t *src = (const uint16_t *) buf;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
290 uint16_t *dst = (uint16_t *) ptr;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
291
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
292 for(j = 0; j < avctx->width; j++)
12129
8b28e74de2c0 Add av_ prefix to bswap macros
mru
parents: 12128
diff changeset
293 *dst++ = av_le2ne16(*src++);
7911
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
294
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
295 buf += n;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
296 ptr += linesize;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
297 }
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
298 break;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
299 case 32:
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
300 for(i = 0; i < avctx->height; i++){
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
301 const uint8_t *src = buf;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
302 uint8_t *dst = ptr;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
303
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
304 for(j = 0; j < avctx->width; j++){
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
305 dst[0] = src[rgb[2]];
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
306 dst[1] = src[rgb[1]];
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
307 dst[2] = src[rgb[0]];
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
308 dst += 3;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
309 src += 4;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
310 }
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
311
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
312 buf += n;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
313 ptr += linesize;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
314 }
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
315 break;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
316 default:
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
317 av_log(avctx, AV_LOG_ERROR, "BMP decoder is broken\n");
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
318 return -1;
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
319 }
7910
87bbd8322244 Add RLE4 and RLE8 decoding support for BMP
kostya
parents: 7909
diff changeset
320 }
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
321
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
322 *picture = s->picture;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
323 *data_size = sizeof(AVPicture);
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
324
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
325 return buf_size;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
326 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
327
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6265
diff changeset
328 static av_cold int bmp_decode_end(AVCodecContext *avctx)
4455
8ecfb7ecbb53 Add decode_end method to bmp decoder. Patch by Michel Bardiaux,
takis
parents: 4445
diff changeset
329 {
8ecfb7ecbb53 Add decode_end method to bmp decoder. Patch by Michel Bardiaux,
takis
parents: 4445
diff changeset
330 BMPContext* c = avctx->priv_data;
8ecfb7ecbb53 Add decode_end method to bmp decoder. Patch by Michel Bardiaux,
takis
parents: 4445
diff changeset
331
8ecfb7ecbb53 Add decode_end method to bmp decoder. Patch by Michel Bardiaux,
takis
parents: 4445
diff changeset
332 if (c->picture.data[0])
8ecfb7ecbb53 Add decode_end method to bmp decoder. Patch by Michel Bardiaux,
takis
parents: 4445
diff changeset
333 avctx->release_buffer(avctx, &c->picture);
8ecfb7ecbb53 Add decode_end method to bmp decoder. Patch by Michel Bardiaux,
takis
parents: 4445
diff changeset
334
8ecfb7ecbb53 Add decode_end method to bmp decoder. Patch by Michel Bardiaux,
takis
parents: 4445
diff changeset
335 return 0;
8ecfb7ecbb53 Add decode_end method to bmp decoder. Patch by Michel Bardiaux,
takis
parents: 4445
diff changeset
336 }
8ecfb7ecbb53 Add decode_end method to bmp decoder. Patch by Michel Bardiaux,
takis
parents: 4445
diff changeset
337
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
338 AVCodec bmp_decoder = {
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
339 "bmp",
11560
8a4984c5cacc Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 10335
diff changeset
340 AVMEDIA_TYPE_VIDEO,
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
341 CODEC_ID_BMP,
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
342 sizeof(BMPContext),
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
343 bmp_decode_init,
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
344 NULL,
4455
8ecfb7ecbb53 Add decode_end method to bmp decoder. Patch by Michel Bardiaux,
takis
parents: 4445
diff changeset
345 bmp_decode_end,
6722
6eeb19edcee3 Add long names to some AVCodec declarations.
diego
parents: 6595
diff changeset
346 bmp_decode_frame,
9798
6e4c341027f2 bmp decoder uses get_buffer, set CODEC_CAP_DR1
bcoudurier
parents: 9355
diff changeset
347 CODEC_CAP_DR1,
12108
c35d7bc64882 Add new decoder property max_lowres and do not init decoder if requested value is higher.
cehoyos
parents: 11560
diff changeset
348 .max_lowres = 5,
7040
e943e1409077 Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents: 6722
diff changeset
349 .long_name = NULL_IF_CONFIG_SMALL("BMP image"),
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
350 };