annotate bmp.c @ 8204:507854688c43 libavcodec

Some BMP files have file size declared in the header equal to headers size without image data, so try to correct that value before conducting checks on declared file size.
author kostya
date Mon, 24 Nov 2008 11:24:02 +0000
parents 3b90f93d97a6
children 052c676c433b
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,
6265
michael
parents: 5327
diff changeset
38 const uint8_t *buf, int buf_size)
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
39 {
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
40 BMPContext *s = avctx->priv_data;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
41 AVFrame *picture = data;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
42 AVFrame *p = &s->picture;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
43 unsigned int fsize, hsize;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
44 int width, height;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
45 unsigned int depth;
4393
michael
parents: 4109
diff changeset
46 BiCompression comp;
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
47 unsigned int ihsize;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
48 int i, j, n, linesize;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
49 uint32_t rgb[3];
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
50 uint8_t *ptr;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
51 int dsize;
6265
michael
parents: 5327
diff changeset
52 const uint8_t *buf0 = buf;
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
53
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
54 if(buf_size < 14){
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
55 av_log(avctx, AV_LOG_ERROR, "buf size too small (%d)\n", buf_size);
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
56 return -1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
57 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
58
4439
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
59 if(bytestream_get_byte(&buf) != 'B' ||
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
60 bytestream_get_byte(&buf) != 'M') {
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
61 av_log(avctx, AV_LOG_ERROR, "bad magic number\n");
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
62 return -1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
63 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
64
4439
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
65 fsize = bytestream_get_le32(&buf);
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
66 if(buf_size < fsize){
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
67 av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n",
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
68 buf_size, fsize);
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
69 return -1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
70 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
71
4439
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
72 buf += 2; /* reserved1 */
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
73 buf += 2; /* reserved2 */
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
74
4439
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
75 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
76 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
77 if(ihsize + 14 > hsize){
507854688c43 Some BMP files have file size declared in the header equal to headers size
kostya
parents: 8203
diff changeset
78 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
79 return -1;
507854688c43 Some BMP files have file size declared in the header equal to headers size
kostya
parents: 8203
diff changeset
80 }
507854688c43 Some BMP files have file size declared in the header equal to headers size
kostya
parents: 8203
diff changeset
81
507854688c43 Some BMP files have file size declared in the header equal to headers size
kostya
parents: 8203
diff changeset
82 /* 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
83 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
84 fsize = buf_size - 2;
507854688c43 Some BMP files have file size declared in the header equal to headers size
kostya
parents: 8203
diff changeset
85
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
86 if(fsize <= hsize){
8203
3b90f93d97a6 Give more meaningful message on BMP header parsing error
kostya
parents: 8202
diff changeset
87 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
88 fsize, hsize);
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
89 return -1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
90 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
91
8202
5af44bd71254 Add known BMP header sizes.
kostya
parents: 7911
diff changeset
92 switch(ihsize){
5af44bd71254 Add known BMP header sizes.
kostya
parents: 7911
diff changeset
93 case 40: // windib v3
5af44bd71254 Add known BMP header sizes.
kostya
parents: 7911
diff changeset
94 case 64: // OS/2 v2
5af44bd71254 Add known BMP header sizes.
kostya
parents: 7911
diff changeset
95 case 108: // windib v4
5af44bd71254 Add known BMP header sizes.
kostya
parents: 7911
diff changeset
96 case 124: // windib v5
6595
92eb6af449dc Indentation
benoit
parents: 6594
diff changeset
97 width = bytestream_get_le32(&buf);
92eb6af449dc Indentation
benoit
parents: 6594
diff changeset
98 height = bytestream_get_le32(&buf);
8202
5af44bd71254 Add known BMP header sizes.
kostya
parents: 7911
diff changeset
99 break;
5af44bd71254 Add known BMP header sizes.
kostya
parents: 7911
diff changeset
100 case 12: // OS/2 v1
6594
e094b1b11e1d Support for BMP os2v1.
benoit
parents: 6517
diff changeset
101 width = bytestream_get_le16(&buf);
e094b1b11e1d Support for BMP os2v1.
benoit
parents: 6517
diff changeset
102 height = bytestream_get_le16(&buf);
8202
5af44bd71254 Add known BMP header sizes.
kostya
parents: 7911
diff changeset
103 break;
5af44bd71254 Add known BMP header sizes.
kostya
parents: 7911
diff changeset
104 default:
7887
44da2504ce69 add newline at the end of message
kostya
parents: 7040
diff changeset
105 av_log(avctx, AV_LOG_ERROR, "unsupported BMP file, patch welcome\n");
6594
e094b1b11e1d Support for BMP os2v1.
benoit
parents: 6517
diff changeset
106 return -1;
e094b1b11e1d Support for BMP os2v1.
benoit
parents: 6517
diff changeset
107 }
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
108
4439
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
109 if(bytestream_get_le16(&buf) != 1){ /* planes */
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
110 av_log(avctx, AV_LOG_ERROR, "invalid BMP header\n");
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
111 return -1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
112 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
113
4439
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
114 depth = bytestream_get_le16(&buf);
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
115
6594
e094b1b11e1d Support for BMP os2v1.
benoit
parents: 6517
diff changeset
116 if(ihsize == 40)
4439
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
117 comp = bytestream_get_le32(&buf);
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
118 else
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
119 comp = BMP_RGB;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
120
7910
87bbd8322244 Add RLE4 and RLE8 decoding support for BMP
kostya
parents: 7909
diff changeset
121 if(comp != BMP_RGB && comp != BMP_BITFIELDS && comp != BMP_RLE4 && comp != BMP_RLE8){
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
122 av_log(avctx, AV_LOG_ERROR, "BMP coding %d not supported\n", comp);
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
123 return -1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
124 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
125
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
126 if(comp == BMP_BITFIELDS){
4439
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
127 buf += 20;
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
128 rgb[0] = bytestream_get_le32(&buf);
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
129 rgb[1] = bytestream_get_le32(&buf);
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
130 rgb[2] = bytestream_get_le32(&buf);
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
131 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
132
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
133 avctx->width = width;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
134 avctx->height = height > 0? height: -height;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
135
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
136 avctx->pix_fmt = PIX_FMT_NONE;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
137
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
138 switch(depth){
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
139 case 32:
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
140 if(comp == BMP_BITFIELDS){
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
141 rgb[0] = (rgb[0] >> 15) & 3;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
142 rgb[1] = (rgb[1] >> 15) & 3;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
143 rgb[2] = (rgb[2] >> 15) & 3;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
144
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
145 if(rgb[0] + rgb[1] + rgb[2] != 3 ||
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
146 rgb[0] == rgb[1] || rgb[0] == rgb[2] || rgb[1] == rgb[2]){
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
147 break;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
148 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
149 } else {
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
150 rgb[0] = 2;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
151 rgb[1] = 1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
152 rgb[2] = 0;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
153 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
154
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
155 avctx->pix_fmt = PIX_FMT_BGR24;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
156 break;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
157 case 24:
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
158 avctx->pix_fmt = PIX_FMT_BGR24;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
159 break;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
160 case 16:
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
161 if(comp == BMP_RGB)
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
162 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
163 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
164 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
165 break;
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
166 case 8:
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
167 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
168 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
169 else
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_GRAY8;
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
171 break;
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
172 case 4:
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
173 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
174 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
175 }else{
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
176 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
177 return -1;
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
178 }
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
179 break;
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
180 case 1:
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
181 avctx->pix_fmt = PIX_FMT_MONOBLACK;
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
182 break;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
183 default:
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
184 av_log(avctx, AV_LOG_ERROR, "depth %d not supported\n", depth);
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
185 return -1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
186 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
187
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
188 if(avctx->pix_fmt == PIX_FMT_NONE){
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
189 av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n");
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
190 return -1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
191 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
192
4432
a848b652f0ac Fix segfault in bmp decoder. Patch by Michel Bardiaux mbardiaux mediaxim dot be.
takis
parents: 4415
diff changeset
193 if(p->data[0])
a848b652f0ac Fix segfault in bmp decoder. Patch by Michel Bardiaux mbardiaux mediaxim dot be.
takis
parents: 4415
diff changeset
194 avctx->release_buffer(avctx, p);
a848b652f0ac Fix segfault in bmp decoder. Patch by Michel Bardiaux mbardiaux mediaxim dot be.
takis
parents: 4415
diff changeset
195
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
196 p->reference = 0;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
197 if(avctx->get_buffer(avctx, p) < 0){
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
198 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
199 return -1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
200 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
201 p->pict_type = FF_I_TYPE;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
202 p->key_frame = 1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
203
4439
3af19e140d67 Make BMP decoder use bytestream. Patch by Michel Bardiaux
takis
parents: 4432
diff changeset
204 buf = buf0 + hsize;
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
205 dsize = buf_size - hsize;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
206
4109
a90490a13ac4 coded line size is a multiple of 4
mru
parents: 3947
diff changeset
207 /* Line size in file multiple of 4 */
7908
dc825905f93f Calculate line size correctly for bit depths < 8
kostya
parents: 7887
diff changeset
208 n = ((avctx->width * depth) / 8 + 3) & ~3;
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
209
7910
87bbd8322244 Add RLE4 and RLE8 decoding support for BMP
kostya
parents: 7909
diff changeset
210 if(n * avctx->height > dsize && comp != BMP_RLE4 && comp != BMP_RLE8){
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
211 av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n",
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
212 dsize, n * avctx->height);
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
213 return -1;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
214 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
215
7910
87bbd8322244 Add RLE4 and RLE8 decoding support for BMP
kostya
parents: 7909
diff changeset
216 // 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
217 if(comp == BMP_RLE4 || comp == BMP_RLE8)
87bbd8322244 Add RLE4 and RLE8 decoding support for BMP
kostya
parents: 7909
diff changeset
218 memset(p->data[0], 0, avctx->height * p->linesize[0]);
87bbd8322244 Add RLE4 and RLE8 decoding support for BMP
kostya
parents: 7909
diff changeset
219
7909
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
220 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
221 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
222
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
223 if(height > 0){
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
224 ptr = p->data[0] + (avctx->height - 1) * p->linesize[0];
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
225 linesize = -p->linesize[0];
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
226 } else {
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
227 ptr = p->data[0];
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
228 linesize = p->linesize[0];
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
229 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
230
7909
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
231 if(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
232 buf = buf0 + 14 + ihsize; //palette location
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
233 if((hsize-ihsize-14)>>depth < 4){ // OS/2 bitmap, 3 bytes per palette entry
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
234 for(i = 0; i < (1 << depth); i++)
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
235 ((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
236 }else{
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
237 for(i = 0; i < (1 << depth); i++)
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
238 ((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
239 }
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
240 buf = buf0 + hsize;
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
241 }
7910
87bbd8322244 Add RLE4 and RLE8 decoding support for BMP
kostya
parents: 7909
diff changeset
242 if(comp == BMP_RLE4 || comp == BMP_RLE8){
87bbd8322244 Add RLE4 and RLE8 decoding support for BMP
kostya
parents: 7909
diff changeset
243 ff_msrle_decode(avctx, p, depth, buf, dsize);
87bbd8322244 Add RLE4 and RLE8 decoding support for BMP
kostya
parents: 7909
diff changeset
244 }else{
7911
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
245 switch(depth){
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
246 case 1:
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
247 for(i = 0; i < avctx->height; i++){
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
248 memcpy(ptr, buf, n);
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
249 buf += n;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
250 ptr += linesize;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
251 }
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
252 break;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
253 case 4:
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
254 for(i = 0; i < avctx->height; i++){
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
255 int j;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
256 for(j = 0; j < n; j++){
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
257 ptr[j*2+0] = (buf[j] >> 4) & 0xF;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
258 ptr[j*2+1] = buf[j] & 0xF;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
259 }
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
260 buf += n;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
261 ptr += linesize;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
262 }
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
263 break;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
264 case 8:
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
265 for(i = 0; i < avctx->height; i++){
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
266 memcpy(ptr, buf, avctx->width);
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
267 buf += n;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
268 ptr += linesize;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
269 }
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
270 break;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
271 case 24:
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
272 for(i = 0; i < avctx->height; i++){
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
273 memcpy(ptr, buf, avctx->width*(depth>>3));
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
274 buf += n;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
275 ptr += linesize;
7909
9fd3f57e4c16 Add support for 1-bit, 4-bit, 8-bit and some 16-bit raw BMP
kostya
parents: 7908
diff changeset
276 }
7911
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
277 break;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
278 case 16:
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
279 for(i = 0; i < avctx->height; i++){
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
280 const uint16_t *src = (const uint16_t *) buf;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
281 uint16_t *dst = (uint16_t *) ptr;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
282
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
283 for(j = 0; j < avctx->width; j++)
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
284 *dst++ = le2me_16(*src++);
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
285
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
286 buf += n;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
287 ptr += linesize;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
288 }
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
289 break;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
290 case 32:
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
291 for(i = 0; i < avctx->height; i++){
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
292 const uint8_t *src = buf;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
293 uint8_t *dst = ptr;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
294
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
295 for(j = 0; j < avctx->width; j++){
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
296 dst[0] = src[rgb[2]];
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
297 dst[1] = src[rgb[1]];
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
298 dst[2] = src[rgb[0]];
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
299 dst += 3;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
300 src += 4;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
301 }
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
302
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
303 buf += n;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
304 ptr += linesize;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
305 }
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
306 break;
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
307 default:
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
308 av_log(avctx, AV_LOG_ERROR, "BMP decoder is broken\n");
a7b88e5846f6 Cosmetics: reindent after last commit
kostya
parents: 7910
diff changeset
309 return -1;
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
310 }
7910
87bbd8322244 Add RLE4 and RLE8 decoding support for BMP
kostya
parents: 7909
diff changeset
311 }
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
312
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
313 *picture = s->picture;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
314 *data_size = sizeof(AVPicture);
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
315
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
316 return buf_size;
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
317 }
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
318
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6265
diff changeset
319 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
320 {
8ecfb7ecbb53 Add decode_end method to bmp decoder. Patch by Michel Bardiaux,
takis
parents: 4445
diff changeset
321 BMPContext* c = avctx->priv_data;
8ecfb7ecbb53 Add decode_end method to bmp decoder. Patch by Michel Bardiaux,
takis
parents: 4445
diff changeset
322
8ecfb7ecbb53 Add decode_end method to bmp decoder. Patch by Michel Bardiaux,
takis
parents: 4445
diff changeset
323 if (c->picture.data[0])
8ecfb7ecbb53 Add decode_end method to bmp decoder. Patch by Michel Bardiaux,
takis
parents: 4445
diff changeset
324 avctx->release_buffer(avctx, &c->picture);
8ecfb7ecbb53 Add decode_end method to bmp decoder. Patch by Michel Bardiaux,
takis
parents: 4445
diff changeset
325
8ecfb7ecbb53 Add decode_end method to bmp decoder. Patch by Michel Bardiaux,
takis
parents: 4445
diff changeset
326 return 0;
8ecfb7ecbb53 Add decode_end method to bmp decoder. Patch by Michel Bardiaux,
takis
parents: 4445
diff changeset
327 }
8ecfb7ecbb53 Add decode_end method to bmp decoder. Patch by Michel Bardiaux,
takis
parents: 4445
diff changeset
328
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
329 AVCodec bmp_decoder = {
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
330 "bmp",
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
331 CODEC_TYPE_VIDEO,
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
332 CODEC_ID_BMP,
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
333 sizeof(BMPContext),
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
334 bmp_decode_init,
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
335 NULL,
4455
8ecfb7ecbb53 Add decode_end method to bmp decoder. Patch by Michel Bardiaux,
takis
parents: 4445
diff changeset
336 bmp_decode_end,
6722
6eeb19edcee3 Add long names to some AVCodec declarations.
diego
parents: 6595
diff changeset
337 bmp_decode_frame,
7040
e943e1409077 Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents: 6722
diff changeset
338 .long_name = NULL_IF_CONFIG_SMALL("BMP image"),
2949
e5a10ae14ffb BMP image decoder
mru
parents:
diff changeset
339 };