Mercurial > libavcodec.hg
comparison bmp.c @ 7910:87bbd8322244 libavcodec
Add RLE4 and RLE8 decoding support for BMP
author | kostya |
---|---|
date | Tue, 23 Sep 2008 08:45:12 +0000 |
parents | 9fd3f57e4c16 |
children | a7b88e5846f6 |
comparison
equal
deleted
inserted
replaced
7909:9fd3f57e4c16 | 7910:87bbd8322244 |
---|---|
20 */ | 20 */ |
21 | 21 |
22 #include "avcodec.h" | 22 #include "avcodec.h" |
23 #include "bytestream.h" | 23 #include "bytestream.h" |
24 #include "bmp.h" | 24 #include "bmp.h" |
25 #include "msrledec.h" | |
25 | 26 |
26 static av_cold int bmp_decode_init(AVCodecContext *avctx){ | 27 static av_cold int bmp_decode_init(AVCodecContext *avctx){ |
27 BMPContext *s = avctx->priv_data; | 28 BMPContext *s = avctx->priv_data; |
28 | 29 |
29 avcodec_get_frame_defaults((AVFrame*)&s->picture); | 30 avcodec_get_frame_defaults((AVFrame*)&s->picture); |
105 if(ihsize == 40) | 106 if(ihsize == 40) |
106 comp = bytestream_get_le32(&buf); | 107 comp = bytestream_get_le32(&buf); |
107 else | 108 else |
108 comp = BMP_RGB; | 109 comp = BMP_RGB; |
109 | 110 |
110 if(comp != BMP_RGB && comp != BMP_BITFIELDS){ | 111 if(comp != BMP_RGB && comp != BMP_BITFIELDS && comp != BMP_RLE4 && comp != BMP_RLE8){ |
111 av_log(avctx, AV_LOG_ERROR, "BMP coding %d not supported\n", comp); | 112 av_log(avctx, AV_LOG_ERROR, "BMP coding %d not supported\n", comp); |
112 return -1; | 113 return -1; |
113 } | 114 } |
114 | 115 |
115 if(comp == BMP_BITFIELDS){ | 116 if(comp == BMP_BITFIELDS){ |
194 dsize = buf_size - hsize; | 195 dsize = buf_size - hsize; |
195 | 196 |
196 /* Line size in file multiple of 4 */ | 197 /* Line size in file multiple of 4 */ |
197 n = ((avctx->width * depth) / 8 + 3) & ~3; | 198 n = ((avctx->width * depth) / 8 + 3) & ~3; |
198 | 199 |
199 if(n * avctx->height > dsize){ | 200 if(n * avctx->height > dsize && comp != BMP_RLE4 && comp != BMP_RLE8){ |
200 av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n", | 201 av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n", |
201 dsize, n * avctx->height); | 202 dsize, n * avctx->height); |
202 return -1; | 203 return -1; |
203 } | 204 } |
205 | |
206 // RLE may skip decoding some picture areas, so blank picture before decoding | |
207 if(comp == BMP_RLE4 || comp == BMP_RLE8) | |
208 memset(p->data[0], 0, avctx->height * p->linesize[0]); | |
204 | 209 |
205 if(depth == 4 || depth == 8) | 210 if(depth == 4 || depth == 8) |
206 memset(p->data[1], 0, 1024); | 211 memset(p->data[1], 0, 1024); |
207 | 212 |
208 if(height > 0){ | 213 if(height > 0){ |
222 for(i = 0; i < (1 << depth); i++) | 227 for(i = 0; i < (1 << depth); i++) |
223 ((uint32_t*)p->data[1])[i] = bytestream_get_le32(&buf); | 228 ((uint32_t*)p->data[1])[i] = bytestream_get_le32(&buf); |
224 } | 229 } |
225 buf = buf0 + hsize; | 230 buf = buf0 + hsize; |
226 } | 231 } |
232 if(comp == BMP_RLE4 || comp == BMP_RLE8){ | |
233 ff_msrle_decode(avctx, p, depth, buf, dsize); | |
234 }else{ | |
227 switch(depth){ | 235 switch(depth){ |
228 case 1: | 236 case 1: |
229 for(i = 0; i < avctx->height; i++){ | 237 for(i = 0; i < avctx->height; i++){ |
230 memcpy(ptr, buf, n); | 238 memcpy(ptr, buf, n); |
231 buf += n; | 239 buf += n; |
287 } | 295 } |
288 break; | 296 break; |
289 default: | 297 default: |
290 av_log(avctx, AV_LOG_ERROR, "BMP decoder is broken\n"); | 298 av_log(avctx, AV_LOG_ERROR, "BMP decoder is broken\n"); |
291 return -1; | 299 return -1; |
300 } | |
292 } | 301 } |
293 | 302 |
294 *picture = s->picture; | 303 *picture = s->picture; |
295 *data_size = sizeof(AVPicture); | 304 *data_size = sizeof(AVPicture); |
296 | 305 |