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