Mercurial > libavcodec.hg
comparison bmp.c @ 4439:3af19e140d67 libavcodec
Make BMP decoder use bytestream. Patch by Michel Bardiaux
mbardiaux mediaxim dot be.
author | takis |
---|---|
date | Wed, 31 Jan 2007 00:34:56 +0000 |
parents | a848b652f0ac |
children | fc9a42d0e848 |
comparison
equal
deleted
inserted
replaced
4438:fe3179006730 | 4439:3af19e140d67 |
---|---|
18 * License along with FFmpeg; if not, write to the Free Software | 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 | 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 */ | 20 */ |
21 | 21 |
22 #include "avcodec.h" | 22 #include "avcodec.h" |
23 #include "bitstream.h" | 23 #include "bytestream.h" |
24 #include "bswap.h" | |
25 #include "bmp.h" | 24 #include "bmp.h" |
26 | |
27 #define read16(bits) bswap_16(get_bits(bits, 16)) | |
28 #define read32(bits) bswap_32(get_bits_long(bits, 32)) | |
29 | 25 |
30 static int bmp_decode_init(AVCodecContext *avctx){ | 26 static int bmp_decode_init(AVCodecContext *avctx){ |
31 BMPContext *s = avctx->priv_data; | 27 BMPContext *s = avctx->priv_data; |
32 | 28 |
33 avcodec_get_frame_defaults((AVFrame*)&s->picture); | 29 avcodec_get_frame_defaults((AVFrame*)&s->picture); |
41 uint8_t *buf, int buf_size) | 37 uint8_t *buf, int buf_size) |
42 { | 38 { |
43 BMPContext *s = avctx->priv_data; | 39 BMPContext *s = avctx->priv_data; |
44 AVFrame *picture = data; | 40 AVFrame *picture = data; |
45 AVFrame *p = &s->picture; | 41 AVFrame *p = &s->picture; |
46 GetBitContext bits; | |
47 unsigned int fsize, hsize; | 42 unsigned int fsize, hsize; |
48 int width, height; | 43 int width, height; |
49 unsigned int depth; | 44 unsigned int depth; |
50 BiCompression comp; | 45 BiCompression comp; |
51 unsigned int ihsize; | 46 unsigned int ihsize; |
52 int i, j, n, linesize; | 47 int i, j, n, linesize; |
53 uint32_t rgb[3]; | 48 uint32_t rgb[3]; |
54 uint8_t *ptr; | 49 uint8_t *ptr; |
55 int dsize; | 50 int dsize; |
51 uint8_t *buf0 = buf; | |
56 | 52 |
57 if(buf_size < 14){ | 53 if(buf_size < 14){ |
58 av_log(avctx, AV_LOG_ERROR, "buf size too small (%d)\n", buf_size); | 54 av_log(avctx, AV_LOG_ERROR, "buf size too small (%d)\n", buf_size); |
59 return -1; | 55 return -1; |
60 } | 56 } |
61 | 57 |
62 init_get_bits(&bits, buf, buf_size); | 58 if(bytestream_get_byte(&buf) != 'B' || |
63 | 59 bytestream_get_byte(&buf) != 'M') { |
64 if(get_bits(&bits, 16) != 0x424d){ /* 'BM' */ | |
65 av_log(avctx, AV_LOG_ERROR, "bad magic number\n"); | 60 av_log(avctx, AV_LOG_ERROR, "bad magic number\n"); |
66 return -1; | 61 return -1; |
67 } | 62 } |
68 | 63 |
69 fsize = read32(&bits); | 64 fsize = bytestream_get_le32(&buf); |
70 if(buf_size < fsize){ | 65 if(buf_size < fsize){ |
71 av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n", | 66 av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n", |
72 buf_size, fsize); | 67 buf_size, fsize); |
73 return -1; | 68 return -1; |
74 } | 69 } |
75 | 70 |
76 skip_bits(&bits, 16); /* reserved1 */ | 71 buf += 2; /* reserved1 */ |
77 skip_bits(&bits, 16); /* reserved2 */ | 72 buf += 2; /* reserved2 */ |
78 | 73 |
79 hsize = read32(&bits); /* header size */ | 74 hsize = bytestream_get_le32(&buf); /* header size */ |
80 if(fsize <= hsize){ | 75 if(fsize <= hsize){ |
81 av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n", | 76 av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n", |
82 fsize, hsize); | 77 fsize, hsize); |
83 return -1; | 78 return -1; |
84 } | 79 } |
85 | 80 |
86 ihsize = read32(&bits); /* more header size */ | 81 ihsize = bytestream_get_le32(&buf); /* more header size */ |
87 if(ihsize + 14 > hsize){ | 82 if(ihsize + 14 > hsize){ |
88 av_log(avctx, AV_LOG_ERROR, "invalid header size %d\n", hsize); | 83 av_log(avctx, AV_LOG_ERROR, "invalid header size %d\n", hsize); |
89 return -1; | 84 return -1; |
90 } | 85 } |
91 | 86 |
92 width = read32(&bits); | 87 width = bytestream_get_le32(&buf); |
93 height = read32(&bits); | 88 height = bytestream_get_le32(&buf); |
94 | 89 |
95 if(read16(&bits) != 1){ /* planes */ | 90 if(bytestream_get_le16(&buf) != 1){ /* planes */ |
96 av_log(avctx, AV_LOG_ERROR, "invalid BMP header\n"); | 91 av_log(avctx, AV_LOG_ERROR, "invalid BMP header\n"); |
97 return -1; | 92 return -1; |
98 } | 93 } |
99 | 94 |
100 depth = read16(&bits); | 95 depth = bytestream_get_le16(&buf); |
101 | 96 |
102 if(ihsize > 16) | 97 if(ihsize > 16) |
103 comp = read32(&bits); | 98 comp = bytestream_get_le32(&buf); |
104 else | 99 else |
105 comp = BMP_RGB; | 100 comp = BMP_RGB; |
106 | 101 |
107 if(comp != BMP_RGB && comp != BMP_BITFIELDS){ | 102 if(comp != BMP_RGB && comp != BMP_BITFIELDS){ |
108 av_log(avctx, AV_LOG_ERROR, "BMP coding %d not supported\n", comp); | 103 av_log(avctx, AV_LOG_ERROR, "BMP coding %d not supported\n", comp); |
109 return -1; | 104 return -1; |
110 } | 105 } |
111 | 106 |
112 if(comp == BMP_BITFIELDS){ | 107 if(comp == BMP_BITFIELDS){ |
113 skip_bits(&bits, 20 * 8); | 108 buf += 20; |
114 rgb[0] = read32(&bits); | 109 rgb[0] = bytestream_get_le32(&buf); |
115 rgb[1] = read32(&bits); | 110 rgb[1] = bytestream_get_le32(&buf); |
116 rgb[2] = read32(&bits); | 111 rgb[2] = bytestream_get_le32(&buf); |
117 } | 112 } |
118 | 113 |
119 avctx->codec_id = CODEC_ID_BMP; | 114 avctx->codec_id = CODEC_ID_BMP; |
120 avctx->width = width; | 115 avctx->width = width; |
121 avctx->height = height > 0? height: -height; | 116 avctx->height = height > 0? height: -height; |
167 return -1; | 162 return -1; |
168 } | 163 } |
169 p->pict_type = FF_I_TYPE; | 164 p->pict_type = FF_I_TYPE; |
170 p->key_frame = 1; | 165 p->key_frame = 1; |
171 | 166 |
172 buf += hsize; | 167 buf = buf0 + hsize; |
173 dsize = buf_size - hsize; | 168 dsize = buf_size - hsize; |
174 | 169 |
175 /* Line size in file multiple of 4 */ | 170 /* Line size in file multiple of 4 */ |
176 n = (avctx->width * (depth / 8) + 3) & ~3; | 171 n = (avctx->width * (depth / 8) + 3) & ~3; |
177 | 172 |