bmp.c 10.5 KB
Newer Older
Måns Rullgård's avatar
Måns Rullgård committed
1
/*
2
 * BMP image format decoder
Måns Rullgård's avatar
Måns Rullgård committed
3 4
 * Copyright (c) 2005 Mans Rullgard
 *
5 6 7
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
Måns Rullgård's avatar
Måns Rullgård committed
8 9
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
Måns Rullgård's avatar
Måns Rullgård committed
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
Måns Rullgård's avatar
Måns Rullgård committed
13 14 15 16 17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
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
Måns Rullgård's avatar
Måns Rullgård committed
20 21 22
 */

#include "avcodec.h"
23
#include "bytestream.h"
24
#include "bmp.h"
25
#include "msrledec.h"
Måns Rullgård's avatar
Måns Rullgård committed
26

27
static av_cold int bmp_decode_init(AVCodecContext *avctx){
Måns Rullgård's avatar
Måns Rullgård committed
28 29 30 31 32 33 34 35
    BMPContext *s = avctx->priv_data;

    avcodec_get_frame_defaults((AVFrame*)&s->picture);
    avctx->coded_frame = (AVFrame*)&s->picture;

    return 0;
}

36
static int bmp_decode_frame(AVCodecContext *avctx,
Måns Rullgård's avatar
Måns Rullgård committed
37
                            void *data, int *data_size,
38
                            AVPacket *avpkt)
Måns Rullgård's avatar
Måns Rullgård committed
39
{
40 41
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
Måns Rullgård's avatar
Måns Rullgård committed
42 43 44 45 46 47
    BMPContext *s = avctx->priv_data;
    AVFrame *picture = data;
    AVFrame *p = &s->picture;
    unsigned int fsize, hsize;
    int width, height;
    unsigned int depth;
Michael Niedermayer's avatar
Michael Niedermayer committed
48
    BiCompression comp;
Måns Rullgård's avatar
Måns Rullgård committed
49 50 51 52 53
    unsigned int ihsize;
    int i, j, n, linesize;
    uint32_t rgb[3];
    uint8_t *ptr;
    int dsize;
Michael Niedermayer's avatar
Michael Niedermayer committed
54
    const uint8_t *buf0 = buf;
Måns Rullgård's avatar
Måns Rullgård committed
55 56 57 58 59 60

    if(buf_size < 14){
        av_log(avctx, AV_LOG_ERROR, "buf size too small (%d)\n", buf_size);
        return -1;
    }

61 62
    if(bytestream_get_byte(&buf) != 'B' ||
       bytestream_get_byte(&buf) != 'M') {
Måns Rullgård's avatar
Måns Rullgård committed
63 64 65 66
        av_log(avctx, AV_LOG_ERROR, "bad magic number\n");
        return -1;
    }

67
    fsize = bytestream_get_le32(&buf);
Måns Rullgård's avatar
Måns Rullgård committed
68
    if(buf_size < fsize){
69
        av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d), trying to decode anyway\n",
Måns Rullgård's avatar
Måns Rullgård committed
70
               buf_size, fsize);
71
        fsize = buf_size;
Måns Rullgård's avatar
Måns Rullgård committed
72 73
    }

74 75
    buf += 2; /* reserved1 */
    buf += 2; /* reserved2 */
Måns Rullgård's avatar
Måns Rullgård committed
76

77 78
    hsize = bytestream_get_le32(&buf); /* header size */
    ihsize = bytestream_get_le32(&buf);       /* more header size */
Måns Rullgård's avatar
Måns Rullgård committed
79 80 81 82 83
    if(ihsize + 14 > hsize){
        av_log(avctx, AV_LOG_ERROR, "invalid header size %d\n", hsize);
        return -1;
    }

84 85 86 87 88 89 90 91 92 93
    /* sometimes file size is set to some headers size, set a real size in that case */
    if(fsize == 14 || fsize == ihsize + 14)
        fsize = buf_size - 2;

    if(fsize <= hsize){
        av_log(avctx, AV_LOG_ERROR, "declared file size is less than header size (%d < %d)\n",
               fsize, hsize);
        return -1;
    }

94 95 96 97 98
    switch(ihsize){
    case  40: // windib v3
    case  64: // OS/2 v2
    case 108: // windib v4
    case 124: // windib v5
Benoit Fouet's avatar
Benoit Fouet committed
99 100
        width = bytestream_get_le32(&buf);
        height = bytestream_get_le32(&buf);
101 102
        break;
    case  12: // OS/2 v1
Benoit Fouet's avatar
Benoit Fouet committed
103 104
        width  = bytestream_get_le16(&buf);
        height = bytestream_get_le16(&buf);
105 106
        break;
    default:
107
        av_log(avctx, AV_LOG_ERROR, "unsupported BMP file, patch welcome\n");
Benoit Fouet's avatar
Benoit Fouet committed
108 109
        return -1;
    }
Måns Rullgård's avatar
Måns Rullgård committed
110

111
    if(bytestream_get_le16(&buf) != 1){ /* planes */
Måns Rullgård's avatar
Måns Rullgård committed
112 113 114 115
        av_log(avctx, AV_LOG_ERROR, "invalid BMP header\n");
        return -1;
    }

116
    depth = bytestream_get_le16(&buf);
Måns Rullgård's avatar
Måns Rullgård committed
117

Benoit Fouet's avatar
Benoit Fouet committed
118
    if(ihsize == 40)
119
        comp = bytestream_get_le32(&buf);
Måns Rullgård's avatar
Måns Rullgård committed
120 121 122
    else
        comp = BMP_RGB;

123
    if(comp != BMP_RGB && comp != BMP_BITFIELDS && comp != BMP_RLE4 && comp != BMP_RLE8){
Måns Rullgård's avatar
Måns Rullgård committed
124 125 126 127 128
        av_log(avctx, AV_LOG_ERROR, "BMP coding %d not supported\n", comp);
        return -1;
    }

    if(comp == BMP_BITFIELDS){
129 130 131 132
        buf += 20;
        rgb[0] = bytestream_get_le32(&buf);
        rgb[1] = bytestream_get_le32(&buf);
        rgb[2] = bytestream_get_le32(&buf);
Måns Rullgård's avatar
Måns Rullgård committed
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
    }

    avctx->width = width;
    avctx->height = height > 0? height: -height;

    avctx->pix_fmt = PIX_FMT_NONE;

    switch(depth){
    case 32:
        if(comp == BMP_BITFIELDS){
            rgb[0] = (rgb[0] >> 15) & 3;
            rgb[1] = (rgb[1] >> 15) & 3;
            rgb[2] = (rgb[2] >> 15) & 3;

            if(rgb[0] + rgb[1] + rgb[2] != 3 ||
               rgb[0] == rgb[1] || rgb[0] == rgb[2] || rgb[1] == rgb[2]){
                break;
            }
        } else {
            rgb[0] = 2;
            rgb[1] = 1;
            rgb[2] = 0;
        }

        avctx->pix_fmt = PIX_FMT_BGR24;
        break;
    case 24:
        avctx->pix_fmt = PIX_FMT_BGR24;
        break;
    case 16:
        if(comp == BMP_RGB)
            avctx->pix_fmt = PIX_FMT_RGB555;
165 166 167 168 169 170 171 172 173
        if(comp == BMP_BITFIELDS)
            avctx->pix_fmt = rgb[1] == 0x07E0 ? PIX_FMT_RGB565 : PIX_FMT_RGB555;
        break;
    case 8:
        if(hsize - ihsize - 14 > 0)
            avctx->pix_fmt = PIX_FMT_PAL8;
        else
            avctx->pix_fmt = PIX_FMT_GRAY8;
        break;
174
    case 1:
175 176 177 178
    case 4:
        if(hsize - ihsize - 14 > 0){
            avctx->pix_fmt = PIX_FMT_PAL8;
        }else{
179
            av_log(avctx, AV_LOG_ERROR, "Unknown palette for %d-colour BMP\n", 1<<depth);
180 181 182
            return -1;
        }
        break;
Måns Rullgård's avatar
Måns Rullgård committed
183 184 185 186 187 188 189 190 191 192
    default:
        av_log(avctx, AV_LOG_ERROR, "depth %d not supported\n", depth);
        return -1;
    }

    if(avctx->pix_fmt == PIX_FMT_NONE){
        av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n");
        return -1;
    }

193 194 195
    if(p->data[0])
        avctx->release_buffer(avctx, p);

Måns Rullgård's avatar
Måns Rullgård committed
196 197 198 199 200
    p->reference = 0;
    if(avctx->get_buffer(avctx, p) < 0){
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        return -1;
    }
201
    p->pict_type = AV_PICTURE_TYPE_I;
Måns Rullgård's avatar
Måns Rullgård committed
202 203
    p->key_frame = 1;

204
    buf = buf0 + hsize;
Måns Rullgård's avatar
Måns Rullgård committed
205 206
    dsize = buf_size - hsize;

207
    /* Line size in file multiple of 4 */
208
    n = ((avctx->width * depth) / 8 + 3) & ~3;
Måns Rullgård's avatar
Måns Rullgård committed
209

210
    if(n * avctx->height > dsize && comp != BMP_RLE4 && comp != BMP_RLE8){
Måns Rullgård's avatar
Måns Rullgård committed
211 212 213 214 215
        av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n",
               dsize, n * avctx->height);
        return -1;
    }

216 217 218 219
    // RLE may skip decoding some picture areas, so blank picture before decoding
    if(comp == BMP_RLE4 || comp == BMP_RLE8)
        memset(p->data[0], 0, avctx->height * p->linesize[0]);

220 221 222
    if(depth == 4 || depth == 8)
        memset(p->data[1], 0, 1024);

Måns Rullgård's avatar
Måns Rullgård committed
223 224 225 226 227 228 229 230
    if(height > 0){
        ptr = p->data[0] + (avctx->height - 1) * p->linesize[0];
        linesize = -p->linesize[0];
    } else {
        ptr = p->data[0];
        linesize = p->linesize[0];
    }

231
    if(avctx->pix_fmt == PIX_FMT_PAL8){
232 233 234 235 236 237 238 239 240 241 242
        int colors = 1 << depth;
        if(ihsize >= 36){
            int t;
            buf = buf0 + 46;
            t = bytestream_get_le32(&buf);
            if(t < 0 || t > (1 << depth)){
                av_log(avctx, AV_LOG_ERROR, "Incorrect number of colors - %X for bitdepth %d\n", t, depth);
            }else if(t){
                colors = t;
            }
        }
243
        buf = buf0 + 14 + ihsize; //palette location
244 245
        if((hsize-ihsize-14) < (colors << 2)){ // OS/2 bitmap, 3 bytes per palette entry
            for(i = 0; i < colors; i++)
246
                ((uint32_t*)p->data[1])[i] = (0xff<<24) | bytestream_get_le24(&buf);
247
        }else{
248
            for(i = 0; i < colors; i++)
249 250 251 252
                ((uint32_t*)p->data[1])[i] = bytestream_get_le32(&buf);
        }
        buf = buf0 + hsize;
    }
253
    if(comp == BMP_RLE4 || comp == BMP_RLE8){
254 255 256 257
        if(height < 0){
            p->data[0] += p->linesize[0] * (avctx->height - 1);
            p->linesize[0] = -p->linesize[0];
        }
258
        ff_msrle_decode(avctx, (AVPicture*)p, depth, buf, dsize);
259 260 261 262
        if(height < 0){
            p->data[0] += p->linesize[0] * (avctx->height - 1);
            p->linesize[0] = -p->linesize[0];
        }
263
    }else{
264 265
        switch(depth){
        case 1:
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
            for(i = 0; i < avctx->height; i++){
                int j;
                for(j = 0; j < n; j++){
                    ptr[j*8+0] =  buf[j] >> 7;
                    ptr[j*8+1] = (buf[j] >> 6) & 1;
                    ptr[j*8+2] = (buf[j] >> 5) & 1;
                    ptr[j*8+3] = (buf[j] >> 4) & 1;
                    ptr[j*8+4] = (buf[j] >> 3) & 1;
                    ptr[j*8+5] = (buf[j] >> 2) & 1;
                    ptr[j*8+6] = (buf[j] >> 1) & 1;
                    ptr[j*8+7] =  buf[j]       & 1;
                }
                buf += n;
                ptr += linesize;
            }
            break;
282 283
        case 8:
        case 24:
284 285 286 287
            for(i = 0; i < avctx->height; i++){
                memcpy(ptr, buf, n);
                buf += n;
                ptr += linesize;
288
            }
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
            break;
        case 4:
            for(i = 0; i < avctx->height; i++){
                int j;
                for(j = 0; j < n; j++){
                    ptr[j*2+0] = (buf[j] >> 4) & 0xF;
                    ptr[j*2+1] = buf[j] & 0xF;
                }
                buf += n;
                ptr += linesize;
            }
            break;
        case 16:
            for(i = 0; i < avctx->height; i++){
                const uint16_t *src = (const uint16_t *) buf;
                uint16_t *dst = (uint16_t *) ptr;
Måns Rullgård's avatar
Måns Rullgård committed
305

306
                for(j = 0; j < avctx->width; j++)
307
                    *dst++ = av_le2ne16(*src++);
Måns Rullgård's avatar
Måns Rullgård committed
308

309 310
                buf += n;
                ptr += linesize;
Måns Rullgård's avatar
Måns Rullgård committed
311
            }
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
            break;
        case 32:
            for(i = 0; i < avctx->height; i++){
                const uint8_t *src = buf;
                uint8_t *dst = ptr;

                for(j = 0; j < avctx->width; j++){
                    dst[0] = src[rgb[2]];
                    dst[1] = src[rgb[1]];
                    dst[2] = src[rgb[0]];
                    dst += 3;
                    src += 4;
                }

                buf += n;
                ptr += linesize;
            }
            break;
        default:
            av_log(avctx, AV_LOG_ERROR, "BMP decoder is broken\n");
            return -1;
Måns Rullgård's avatar
Måns Rullgård committed
333
        }
334
    }
Måns Rullgård's avatar
Måns Rullgård committed
335 336 337 338 339 340 341

    *picture = s->picture;
    *data_size = sizeof(AVPicture);

    return buf_size;
}

342
static av_cold int bmp_decode_end(AVCodecContext *avctx)
343 344 345 346 347 348 349 350 351
{
    BMPContext* c = avctx->priv_data;

    if (c->picture.data[0])
        avctx->release_buffer(avctx, &c->picture);

    return 0;
}

352
AVCodec ff_bmp_decoder = {
353 354 355 356 357 358 359 360
    .name           = "bmp",
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = CODEC_ID_BMP,
    .priv_data_size = sizeof(BMPContext),
    .init           = bmp_decode_init,
    .close          = bmp_decode_end,
    .decode         = bmp_decode_frame,
    .capabilities   = CODEC_CAP_DR1,
361
    .long_name = NULL_IF_CONFIG_SMALL("BMP image"),
Måns Rullgård's avatar
Måns Rullgård committed
362
};