• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/bmp.c

Go to the documentation of this file.
00001 /*
00002  * BMP image format decoder
00003  * Copyright (c) 2005 Mans Rullgard
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00022 #include "avcodec.h"
00023 #include "bytestream.h"
00024 #include "bmp.h"
00025 #include "msrledec.h"
00026 
00027 static av_cold int bmp_decode_init(AVCodecContext *avctx){
00028     BMPContext *s = avctx->priv_data;
00029 
00030     avcodec_get_frame_defaults((AVFrame*)&s->picture);
00031     avctx->coded_frame = (AVFrame*)&s->picture;
00032 
00033     return 0;
00034 }
00035 
00036 static int bmp_decode_frame(AVCodecContext *avctx,
00037                             void *data, int *data_size,
00038                             const uint8_t *buf, int buf_size)
00039 {
00040     BMPContext *s = avctx->priv_data;
00041     AVFrame *picture = data;
00042     AVFrame *p = &s->picture;
00043     unsigned int fsize, hsize;
00044     int width, height;
00045     unsigned int depth;
00046     BiCompression comp;
00047     unsigned int ihsize;
00048     int i, j, n, linesize;
00049     uint32_t rgb[3];
00050     uint8_t *ptr;
00051     int dsize;
00052     const uint8_t *buf0 = buf;
00053 
00054     if(buf_size < 14){
00055         av_log(avctx, AV_LOG_ERROR, "buf size too small (%d)\n", buf_size);
00056         return -1;
00057     }
00058 
00059     if(bytestream_get_byte(&buf) != 'B' ||
00060        bytestream_get_byte(&buf) != 'M') {
00061         av_log(avctx, AV_LOG_ERROR, "bad magic number\n");
00062         return -1;
00063     }
00064 
00065     fsize = bytestream_get_le32(&buf);
00066     if(buf_size < fsize){
00067         av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d), trying to decode anyway\n",
00068                buf_size, fsize);
00069         fsize = buf_size;
00070     }
00071 
00072     buf += 2; /* reserved1 */
00073     buf += 2; /* reserved2 */
00074 
00075     hsize = bytestream_get_le32(&buf); /* header size */
00076     ihsize = bytestream_get_le32(&buf);       /* more header size */
00077     if(ihsize + 14 > hsize){
00078         av_log(avctx, AV_LOG_ERROR, "invalid header size %d\n", hsize);
00079         return -1;
00080     }
00081 
00082     /* sometimes file size is set to some headers size, set a real size in that case */
00083     if(fsize == 14 || fsize == ihsize + 14)
00084         fsize = buf_size - 2;
00085 
00086     if(fsize <= hsize){
00087         av_log(avctx, AV_LOG_ERROR, "declared file size is less than header size (%d < %d)\n",
00088                fsize, hsize);
00089         return -1;
00090     }
00091 
00092     switch(ihsize){
00093     case  40: // windib v3
00094     case  64: // OS/2 v2
00095     case 108: // windib v4
00096     case 124: // windib v5
00097         width = bytestream_get_le32(&buf);
00098         height = bytestream_get_le32(&buf);
00099         break;
00100     case  12: // OS/2 v1
00101         width  = bytestream_get_le16(&buf);
00102         height = bytestream_get_le16(&buf);
00103         break;
00104     default:
00105         av_log(avctx, AV_LOG_ERROR, "unsupported BMP file, patch welcome\n");
00106         return -1;
00107     }
00108 
00109     if(bytestream_get_le16(&buf) != 1){ /* planes */
00110         av_log(avctx, AV_LOG_ERROR, "invalid BMP header\n");
00111         return -1;
00112     }
00113 
00114     depth = bytestream_get_le16(&buf);
00115 
00116     if(ihsize == 40)
00117         comp = bytestream_get_le32(&buf);
00118     else
00119         comp = BMP_RGB;
00120 
00121     if(comp != BMP_RGB && comp != BMP_BITFIELDS && comp != BMP_RLE4 && comp != BMP_RLE8){
00122         av_log(avctx, AV_LOG_ERROR, "BMP coding %d not supported\n", comp);
00123         return -1;
00124     }
00125 
00126     if(comp == BMP_BITFIELDS){
00127         buf += 20;
00128         rgb[0] = bytestream_get_le32(&buf);
00129         rgb[1] = bytestream_get_le32(&buf);
00130         rgb[2] = bytestream_get_le32(&buf);
00131     }
00132 
00133     avctx->width = width;
00134     avctx->height = height > 0? height: -height;
00135 
00136     avctx->pix_fmt = PIX_FMT_NONE;
00137 
00138     switch(depth){
00139     case 32:
00140         if(comp == BMP_BITFIELDS){
00141             rgb[0] = (rgb[0] >> 15) & 3;
00142             rgb[1] = (rgb[1] >> 15) & 3;
00143             rgb[2] = (rgb[2] >> 15) & 3;
00144 
00145             if(rgb[0] + rgb[1] + rgb[2] != 3 ||
00146                rgb[0] == rgb[1] || rgb[0] == rgb[2] || rgb[1] == rgb[2]){
00147                 break;
00148             }
00149         } else {
00150             rgb[0] = 2;
00151             rgb[1] = 1;
00152             rgb[2] = 0;
00153         }
00154 
00155         avctx->pix_fmt = PIX_FMT_BGR24;
00156         break;
00157     case 24:
00158         avctx->pix_fmt = PIX_FMT_BGR24;
00159         break;
00160     case 16:
00161         if(comp == BMP_RGB)
00162             avctx->pix_fmt = PIX_FMT_RGB555;
00163         if(comp == BMP_BITFIELDS)
00164             avctx->pix_fmt = rgb[1] == 0x07E0 ? PIX_FMT_RGB565 : PIX_FMT_RGB555;
00165         break;
00166     case 8:
00167         if(hsize - ihsize - 14 > 0)
00168             avctx->pix_fmt = PIX_FMT_PAL8;
00169         else
00170             avctx->pix_fmt = PIX_FMT_GRAY8;
00171         break;
00172     case 4:
00173         if(hsize - ihsize - 14 > 0){
00174             avctx->pix_fmt = PIX_FMT_PAL8;
00175         }else{
00176             av_log(avctx, AV_LOG_ERROR, "Unknown palette for 16-colour BMP\n");
00177             return -1;
00178         }
00179         break;
00180     case 1:
00181         avctx->pix_fmt = PIX_FMT_MONOBLACK;
00182         break;
00183     default:
00184         av_log(avctx, AV_LOG_ERROR, "depth %d not supported\n", depth);
00185         return -1;
00186     }
00187 
00188     if(avctx->pix_fmt == PIX_FMT_NONE){
00189         av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n");
00190         return -1;
00191     }
00192 
00193     if(p->data[0])
00194         avctx->release_buffer(avctx, p);
00195 
00196     p->reference = 0;
00197     if(avctx->get_buffer(avctx, p) < 0){
00198         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00199         return -1;
00200     }
00201     p->pict_type = FF_I_TYPE;
00202     p->key_frame = 1;
00203 
00204     buf = buf0 + hsize;
00205     dsize = buf_size - hsize;
00206 
00207     /* Line size in file multiple of 4 */
00208     n = ((avctx->width * depth) / 8 + 3) & ~3;
00209 
00210     if(n * avctx->height > dsize && comp != BMP_RLE4 && comp != BMP_RLE8){
00211         av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n",
00212                dsize, n * avctx->height);
00213         return -1;
00214     }
00215 
00216     // RLE may skip decoding some picture areas, so blank picture before decoding
00217     if(comp == BMP_RLE4 || comp == BMP_RLE8)
00218         memset(p->data[0], 0, avctx->height * p->linesize[0]);
00219 
00220     if(height > 0){
00221         ptr = p->data[0] + (avctx->height - 1) * p->linesize[0];
00222         linesize = -p->linesize[0];
00223     } else {
00224         ptr = p->data[0];
00225         linesize = p->linesize[0];
00226     }
00227 
00228     if(avctx->pix_fmt == PIX_FMT_PAL8){
00229 
00230         memset(p->data[1], 0, 1024);
00231 
00232         buf = buf0 + 14 + ihsize; //palette location
00233         if((hsize-ihsize-14)>>depth < 4){ // OS/2 bitmap, 3 bytes per palette entry
00234             for(i = 0; i < (1 << depth); i++)
00235                 ((uint32_t*)p->data[1])[i] = bytestream_get_le24(&buf);
00236         }else{
00237             for(i = 0; i < (1 << depth); i++)
00238                 ((uint32_t*)p->data[1])[i] = bytestream_get_le32(&buf);
00239         }
00240         buf = buf0 + hsize;
00241     }
00242     if(comp == BMP_RLE4 || comp == BMP_RLE8){
00243         ff_msrle_decode(avctx, (AVPicture*)p, depth, buf, dsize);
00244     }else{
00245         switch(depth){
00246         case 1:
00247             for(i = 0; i < avctx->height; i++){
00248                 memcpy(ptr, buf, n);
00249                 buf += n;
00250                 ptr += linesize;
00251             }
00252             break;
00253         case 4:
00254             for(i = 0; i < avctx->height; i++){
00255                 int j;
00256                 for(j = 0; j < n; j++){
00257                     ptr[j*2+0] = (buf[j] >> 4) & 0xF;
00258                     ptr[j*2+1] = buf[j] & 0xF;
00259                 }
00260                 buf += n;
00261                 ptr += linesize;
00262             }
00263             break;
00264         case 8:
00265             for(i = 0; i < avctx->height; i++){
00266                 memcpy(ptr, buf, avctx->width);
00267                 buf += n;
00268                 ptr += linesize;
00269             }
00270             break;
00271         case 24:
00272             for(i = 0; i < avctx->height; i++){
00273                 memcpy(ptr, buf, avctx->width*(depth>>3));
00274                 buf += n;
00275                 ptr += linesize;
00276             }
00277             break;
00278         case 16:
00279             for(i = 0; i < avctx->height; i++){
00280                 const uint16_t *src = (const uint16_t *) buf;
00281                 uint16_t *dst = (uint16_t *) ptr;
00282 
00283                 for(j = 0; j < avctx->width; j++)
00284                     *dst++ = le2me_16(*src++);
00285 
00286                 buf += n;
00287                 ptr += linesize;
00288             }
00289             break;
00290         case 32:
00291             for(i = 0; i < avctx->height; i++){
00292                 const uint8_t *src = buf;
00293                 uint8_t *dst = ptr;
00294 
00295                 for(j = 0; j < avctx->width; j++){
00296                     dst[0] = src[rgb[2]];
00297                     dst[1] = src[rgb[1]];
00298                     dst[2] = src[rgb[0]];
00299                     dst += 3;
00300                     src += 4;
00301                 }
00302 
00303                 buf += n;
00304                 ptr += linesize;
00305             }
00306             break;
00307         default:
00308             av_log(avctx, AV_LOG_ERROR, "BMP decoder is broken\n");
00309             return -1;
00310         }
00311     }
00312 
00313     *picture = s->picture;
00314     *data_size = sizeof(AVPicture);
00315 
00316     return buf_size;
00317 }
00318 
00319 static av_cold int bmp_decode_end(AVCodecContext *avctx)
00320 {
00321     BMPContext* c = avctx->priv_data;
00322 
00323     if (c->picture.data[0])
00324         avctx->release_buffer(avctx, &c->picture);
00325 
00326     return 0;
00327 }
00328 
00329 AVCodec bmp_decoder = {
00330     "bmp",
00331     CODEC_TYPE_VIDEO,
00332     CODEC_ID_BMP,
00333     sizeof(BMPContext),
00334     bmp_decode_init,
00335     NULL,
00336     bmp_decode_end,
00337     bmp_decode_frame,
00338     .long_name = NULL_IF_CONFIG_SMALL("BMP image"),
00339 };

Generated on Sat Feb 16 2013 09:23:11 for ffmpeg by  doxygen 1.7.1