Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * BMP image format encoder
  3.  * Copyright (c) 2006, 2007 Michel Bardiaux
  4.  * Copyright (c) 2009 Daniel Verkamp <daniel at drv.nu>
  5.  *
  6.  * This file is part of FFmpeg.
  7.  *
  8.  * FFmpeg is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Lesser General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2.1 of the License, or (at your option) any later version.
  12.  *
  13.  * FFmpeg is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Lesser General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Lesser General Public
  19.  * License along with FFmpeg; if not, write to the Free Software
  20.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21.  */
  22.  
  23. #include "libavutil/imgutils.h"
  24. #include "libavutil/avassert.h"
  25. #include "avcodec.h"
  26. #include "bytestream.h"
  27. #include "bmp.h"
  28. #include "internal.h"
  29.  
  30. static const uint32_t monoblack_pal[] = { 0x000000, 0xFFFFFF };
  31. static const uint32_t rgb565_masks[]  = { 0xF800, 0x07E0, 0x001F };
  32. static const uint32_t rgb444_masks[]  = { 0x0F00, 0x00F0, 0x000F };
  33.  
  34. static av_cold int bmp_encode_init(AVCodecContext *avctx){
  35.     switch (avctx->pix_fmt) {
  36.     case AV_PIX_FMT_BGRA:
  37.         avctx->bits_per_coded_sample = 32;
  38.         break;
  39.     case AV_PIX_FMT_BGR24:
  40.         avctx->bits_per_coded_sample = 24;
  41.         break;
  42.     case AV_PIX_FMT_RGB555:
  43.     case AV_PIX_FMT_RGB565:
  44.     case AV_PIX_FMT_RGB444:
  45.         avctx->bits_per_coded_sample = 16;
  46.         break;
  47.     case AV_PIX_FMT_RGB8:
  48.     case AV_PIX_FMT_BGR8:
  49.     case AV_PIX_FMT_RGB4_BYTE:
  50.     case AV_PIX_FMT_BGR4_BYTE:
  51.     case AV_PIX_FMT_GRAY8:
  52.     case AV_PIX_FMT_PAL8:
  53.         avctx->bits_per_coded_sample = 8;
  54.         break;
  55.     case AV_PIX_FMT_MONOBLACK:
  56.         avctx->bits_per_coded_sample = 1;
  57.         break;
  58.     default:
  59.         av_log(avctx, AV_LOG_INFO, "unsupported pixel format\n");
  60.         return AVERROR(EINVAL);
  61.     }
  62.  
  63.     return 0;
  64. }
  65.  
  66. static int bmp_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
  67.                             const AVFrame *pict, int *got_packet)
  68. {
  69.     int n_bytes_image, n_bytes_per_row, n_bytes, i, n, hsize, ret;
  70.     const uint32_t *pal = NULL;
  71.     uint32_t palette256[256];
  72.     int pad_bytes_per_row, pal_entries = 0, compression = BMP_RGB;
  73.     int bit_count = avctx->bits_per_coded_sample;
  74.     uint8_t *ptr, *buf;
  75.     AVFrame * const p = (AVFrame *)pict;
  76.  
  77.     p->pict_type= AV_PICTURE_TYPE_I;
  78.     p->key_frame= 1;
  79.     switch (avctx->pix_fmt) {
  80.     case AV_PIX_FMT_RGB444:
  81.         compression = BMP_BITFIELDS;
  82.         pal = rgb444_masks; // abuse pal to hold color masks
  83.         pal_entries = 3;
  84.         break;
  85.     case AV_PIX_FMT_RGB565:
  86.         compression = BMP_BITFIELDS;
  87.         pal = rgb565_masks; // abuse pal to hold color masks
  88.         pal_entries = 3;
  89.         break;
  90.     case AV_PIX_FMT_RGB8:
  91.     case AV_PIX_FMT_BGR8:
  92.     case AV_PIX_FMT_RGB4_BYTE:
  93.     case AV_PIX_FMT_BGR4_BYTE:
  94.     case AV_PIX_FMT_GRAY8:
  95.         av_assert1(bit_count == 8);
  96.         avpriv_set_systematic_pal2(palette256, avctx->pix_fmt);
  97.         pal = palette256;
  98.         break;
  99.     case AV_PIX_FMT_PAL8:
  100.         pal = (uint32_t *)p->data[1];
  101.         break;
  102.     case AV_PIX_FMT_MONOBLACK:
  103.         pal = monoblack_pal;
  104.         break;
  105.     }
  106.     if (pal && !pal_entries) pal_entries = 1 << bit_count;
  107.     n_bytes_per_row = ((int64_t)avctx->width * (int64_t)bit_count + 7LL) >> 3LL;
  108.     pad_bytes_per_row = (4 - n_bytes_per_row) & 3;
  109.     n_bytes_image = avctx->height * (n_bytes_per_row + pad_bytes_per_row);
  110.  
  111.     // STRUCTURE.field refer to the MSVC documentation for BITMAPFILEHEADER
  112.     // and related pages.
  113. #define SIZE_BITMAPFILEHEADER 14
  114. #define SIZE_BITMAPINFOHEADER 40
  115.     hsize = SIZE_BITMAPFILEHEADER + SIZE_BITMAPINFOHEADER + (pal_entries << 2);
  116.     n_bytes = n_bytes_image + hsize;
  117.     if ((ret = ff_alloc_packet2(avctx, pkt, n_bytes)) < 0)
  118.         return ret;
  119.     buf = pkt->data;
  120.     bytestream_put_byte(&buf, 'B');                   // BITMAPFILEHEADER.bfType
  121.     bytestream_put_byte(&buf, 'M');                   // do.
  122.     bytestream_put_le32(&buf, n_bytes);               // BITMAPFILEHEADER.bfSize
  123.     bytestream_put_le16(&buf, 0);                     // BITMAPFILEHEADER.bfReserved1
  124.     bytestream_put_le16(&buf, 0);                     // BITMAPFILEHEADER.bfReserved2
  125.     bytestream_put_le32(&buf, hsize);                 // BITMAPFILEHEADER.bfOffBits
  126.     bytestream_put_le32(&buf, SIZE_BITMAPINFOHEADER); // BITMAPINFOHEADER.biSize
  127.     bytestream_put_le32(&buf, avctx->width);          // BITMAPINFOHEADER.biWidth
  128.     bytestream_put_le32(&buf, avctx->height);         // BITMAPINFOHEADER.biHeight
  129.     bytestream_put_le16(&buf, 1);                     // BITMAPINFOHEADER.biPlanes
  130.     bytestream_put_le16(&buf, bit_count);             // BITMAPINFOHEADER.biBitCount
  131.     bytestream_put_le32(&buf, compression);           // BITMAPINFOHEADER.biCompression
  132.     bytestream_put_le32(&buf, n_bytes_image);         // BITMAPINFOHEADER.biSizeImage
  133.     bytestream_put_le32(&buf, 0);                     // BITMAPINFOHEADER.biXPelsPerMeter
  134.     bytestream_put_le32(&buf, 0);                     // BITMAPINFOHEADER.biYPelsPerMeter
  135.     bytestream_put_le32(&buf, 0);                     // BITMAPINFOHEADER.biClrUsed
  136.     bytestream_put_le32(&buf, 0);                     // BITMAPINFOHEADER.biClrImportant
  137.     for (i = 0; i < pal_entries; i++)
  138.         bytestream_put_le32(&buf, pal[i] & 0xFFFFFF);
  139.     // BMP files are bottom-to-top so we start from the end...
  140.     ptr = p->data[0] + (avctx->height - 1) * p->linesize[0];
  141.     buf = pkt->data + hsize;
  142.     for(i = 0; i < avctx->height; i++) {
  143.         if (bit_count == 16) {
  144.             const uint16_t *src = (const uint16_t *) ptr;
  145.             uint16_t *dst = (uint16_t *) buf;
  146.             for(n = 0; n < avctx->width; n++)
  147.                 AV_WL16(dst + n, src[n]);
  148.         } else {
  149.             memcpy(buf, ptr, n_bytes_per_row);
  150.         }
  151.         buf += n_bytes_per_row;
  152.         memset(buf, 0, pad_bytes_per_row);
  153.         buf += pad_bytes_per_row;
  154.         ptr -= p->linesize[0]; // ... and go back
  155.     }
  156.  
  157.     pkt->flags |= AV_PKT_FLAG_KEY;
  158.     *got_packet = 1;
  159.     return 0;
  160. }
  161.  
  162. AVCodec ff_bmp_encoder = {
  163.     .name           = "bmp",
  164.     .long_name      = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"),
  165.     .type           = AVMEDIA_TYPE_VIDEO,
  166.     .id             = AV_CODEC_ID_BMP,
  167.     .init           = bmp_encode_init,
  168.     .encode2        = bmp_encode_frame,
  169.     .pix_fmts       = (const enum AVPixelFormat[]){
  170.         AV_PIX_FMT_BGRA, AV_PIX_FMT_BGR24,
  171.         AV_PIX_FMT_RGB565, AV_PIX_FMT_RGB555, AV_PIX_FMT_RGB444,
  172.         AV_PIX_FMT_RGB8, AV_PIX_FMT_BGR8, AV_PIX_FMT_RGB4_BYTE, AV_PIX_FMT_BGR4_BYTE, AV_PIX_FMT_GRAY8, AV_PIX_FMT_PAL8,
  173.         AV_PIX_FMT_MONOBLACK,
  174.         AV_PIX_FMT_NONE
  175.     },
  176. };
  177.