Mercurial > libavcodec.hg
annotate bmp.c @ 3990:746a60ba3177 libavcodec
enable CMOV_IS_FAST as its faster or equal speed on every cpu (duron, athlon, PM, P3) from which ive seen benchmarks, it might be slower on P4 but noone has posted benchmarks ...
author | michael |
---|---|
date | Wed, 11 Oct 2006 12:23:40 +0000 |
parents | c8c591fe26f8 |
children | a90490a13ac4 |
rev | line source |
---|---|
2949 | 1 /* |
2 * BMP image format | |
3 * Copyright (c) 2005 Mans Rullgard | |
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 | 8 * modify it under the terms of the GNU Lesser General Public |
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 | 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 | 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 | |
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 | 20 */ |
21 | |
22 #include "avcodec.h" | |
23 #include "bitstream.h" | |
24 #include "bswap.h" | |
25 | |
26 typedef struct BMPContext { | |
27 AVFrame picture; | |
28 } BMPContext; | |
29 | |
30 #define BMP_RGB 0 | |
31 #define BMP_RLE8 1 | |
32 #define BMP_RLE4 2 | |
33 #define BMP_BITFIELDS 3 | |
34 | |
35 #define read16(bits) bswap_16(get_bits(bits, 16)) | |
36 #define read32(bits) bswap_32(get_bits_long(bits, 32)) | |
37 | |
38 static int bmp_decode_init(AVCodecContext *avctx){ | |
39 BMPContext *s = avctx->priv_data; | |
40 | |
41 avcodec_get_frame_defaults((AVFrame*)&s->picture); | |
42 avctx->coded_frame = (AVFrame*)&s->picture; | |
43 | |
44 return 0; | |
45 } | |
46 | |
2967 | 47 static int bmp_decode_frame(AVCodecContext *avctx, |
2949 | 48 void *data, int *data_size, |
49 uint8_t *buf, int buf_size) | |
50 { | |
51 BMPContext *s = avctx->priv_data; | |
52 AVFrame *picture = data; | |
53 AVFrame *p = &s->picture; | |
54 GetBitContext bits; | |
55 unsigned int fsize, hsize; | |
56 int width, height; | |
57 unsigned int depth; | |
58 unsigned int comp; | |
59 unsigned int ihsize; | |
60 int i, j, n, linesize; | |
61 uint32_t rgb[3]; | |
62 uint8_t *ptr; | |
63 int dsize; | |
64 | |
65 if(buf_size < 14){ | |
66 av_log(avctx, AV_LOG_ERROR, "buf size too small (%d)\n", buf_size); | |
67 return -1; | |
68 } | |
69 | |
70 init_get_bits(&bits, buf, buf_size); | |
71 | |
72 if(get_bits(&bits, 16) != 0x424d){ /* 'BM' */ | |
73 av_log(avctx, AV_LOG_ERROR, "bad magic number\n"); | |
74 return -1; | |
75 } | |
76 | |
77 fsize = read32(&bits); | |
78 if(buf_size < fsize){ | |
79 av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n", | |
80 buf_size, fsize); | |
81 return -1; | |
82 } | |
83 | |
84 skip_bits(&bits, 16); /* reserved1 */ | |
85 skip_bits(&bits, 16); /* reserved2 */ | |
86 | |
87 hsize = read32(&bits); /* header size */ | |
88 if(fsize <= hsize){ | |
89 av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n", | |
90 fsize, hsize); | |
91 return -1; | |
92 } | |
93 | |
94 ihsize = read32(&bits); /* more header size */ | |
95 if(ihsize + 14 > hsize){ | |
96 av_log(avctx, AV_LOG_ERROR, "invalid header size %d\n", hsize); | |
97 return -1; | |
98 } | |
99 | |
100 width = read32(&bits); | |
101 height = read32(&bits); | |
102 | |
103 if(read16(&bits) != 1){ /* planes */ | |
104 av_log(avctx, AV_LOG_ERROR, "invalid BMP header\n"); | |
105 return -1; | |
106 } | |
107 | |
108 depth = read16(&bits); | |
109 | |
110 if(ihsize > 16) | |
111 comp = read32(&bits); | |
112 else | |
113 comp = BMP_RGB; | |
114 | |
115 if(comp != BMP_RGB && comp != BMP_BITFIELDS){ | |
116 av_log(avctx, AV_LOG_ERROR, "BMP coding %d not supported\n", comp); | |
117 return -1; | |
118 } | |
119 | |
120 if(comp == BMP_BITFIELDS){ | |
121 skip_bits(&bits, 20 * 8); | |
122 rgb[0] = read32(&bits); | |
123 rgb[1] = read32(&bits); | |
124 rgb[2] = read32(&bits); | |
125 } | |
126 | |
127 avctx->codec_id = CODEC_ID_BMP; | |
128 avctx->width = width; | |
129 avctx->height = height > 0? height: -height; | |
130 | |
131 avctx->pix_fmt = 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 = PIX_FMT_BGR24; | |
151 break; | |
152 case 24: | |
153 avctx->pix_fmt = PIX_FMT_BGR24; | |
154 break; | |
155 case 16: | |
156 if(comp == BMP_RGB) | |
157 avctx->pix_fmt = PIX_FMT_RGB555; | |
158 break; | |
159 default: | |
160 av_log(avctx, AV_LOG_ERROR, "depth %d not supported\n", depth); | |
161 return -1; | |
162 } | |
163 | |
164 if(avctx->pix_fmt == PIX_FMT_NONE){ | |
165 av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n"); | |
166 return -1; | |
167 } | |
168 | |
169 p->reference = 0; | |
170 if(avctx->get_buffer(avctx, p) < 0){ | |
171 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
172 return -1; | |
173 } | |
174 p->pict_type = FF_I_TYPE; | |
175 p->key_frame = 1; | |
176 | |
177 buf += hsize; | |
178 dsize = buf_size - hsize; | |
179 | |
180 n = avctx->width * (depth / 8); | |
181 | |
182 if(n * avctx->height > dsize){ | |
183 av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n", | |
184 dsize, n * avctx->height); | |
185 return -1; | |
186 } | |
187 | |
188 if(height > 0){ | |
189 ptr = p->data[0] + (avctx->height - 1) * p->linesize[0]; | |
190 linesize = -p->linesize[0]; | |
191 } else { | |
192 ptr = p->data[0]; | |
193 linesize = p->linesize[0]; | |
194 } | |
195 | |
196 switch(depth){ | |
197 case 24: | |
198 for(i = 0; i < avctx->height; i++){ | |
199 memcpy(ptr, buf, n); | |
200 buf += n; | |
201 ptr += linesize; | |
202 } | |
203 break; | |
204 case 16: | |
205 for(i = 0; i < avctx->height; i++){ | |
206 uint16_t *src = (uint16_t *) buf; | |
207 uint16_t *dst = (uint16_t *) ptr; | |
208 | |
209 for(j = 0; j < avctx->width; j++) | |
210 *dst++ = le2me_16(*src++); | |
211 | |
212 buf += n; | |
213 ptr += linesize; | |
214 } | |
215 break; | |
216 case 32: | |
217 for(i = 0; i < avctx->height; i++){ | |
218 uint8_t *src = buf; | |
219 uint8_t *dst = ptr; | |
220 | |
221 for(j = 0; j < avctx->width; j++){ | |
222 dst[0] = src[rgb[2]]; | |
223 dst[1] = src[rgb[1]]; | |
224 dst[2] = src[rgb[0]]; | |
225 dst += 3; | |
226 src += 4; | |
227 } | |
228 | |
229 buf += n; | |
230 ptr += linesize; | |
231 } | |
232 break; | |
233 default: | |
234 av_log(avctx, AV_LOG_ERROR, "BMP decoder is broken\n"); | |
235 return -1; | |
236 } | |
237 | |
238 *picture = s->picture; | |
239 *data_size = sizeof(AVPicture); | |
240 | |
241 return buf_size; | |
242 } | |
243 | |
244 AVCodec bmp_decoder = { | |
245 "bmp", | |
246 CODEC_TYPE_VIDEO, | |
247 CODEC_ID_BMP, | |
248 sizeof(BMPContext), | |
249 bmp_decode_init, | |
250 NULL, | |
251 NULL, | |
252 bmp_decode_frame | |
253 }; |