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