Subversion Repositories Kolibri OS

Rev

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.     const AVFrame * const p = pict;
  70.     int n_bytes_image, n_bytes_per_row, n_bytes, i, n, hsize, ret;
  71.     const uint32_t *pal = NULL;
  72.     uint32_t palette256[256];
  73.     int pad_bytes_per_row, pal_entries = 0, compression = BMP_RGB;
  74.     int bit_count = avctx->bits_per_coded_sample;
  75.     uint8_t *ptr, *buf;
  76.  
  77. #if FF_API_CODED_FRAME
  78. FF_DISABLE_DEPRECATION_WARNINGS
  79.     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
  80.     avctx->coded_frame->key_frame = 1;
  81. FF_ENABLE_DEPRECATION_WARNINGS
  82. #endif
  83.     switch (avctx->pix_fmt) {
  84.     case AV_PIX_FMT_RGB444:
  85.         compression = BMP_BITFIELDS;
  86.         pal = rgb444_masks; // abuse pal to hold color masks
  87.         pal_entries = 3;
  88.         break;
  89.     case AV_PIX_FMT_RGB565:
  90.         compression = BMP_BITFIELDS;
  91.         pal = rgb565_masks; // abuse pal to hold color masks
  92.         pal_entries = 3;
  93.         break;
  94.     case AV_PIX_FMT_RGB8:
  95.     case AV_PIX_FMT_BGR8:
  96.     case AV_PIX_FMT_RGB4_BYTE:
  97.     case AV_PIX_FMT_BGR4_BYTE:
  98.     case AV_PIX_FMT_GRAY8:
  99.         av_assert1(bit_count == 8);
  100.         avpriv_set_systematic_pal2(palette256, avctx->pix_fmt);
  101.         pal = palette256;
  102.         break;
  103.     case AV_PIX_FMT_PAL8:
  104.         pal = (uint32_t *)p->data[1];
  105.         break;
  106.     case AV_PIX_FMT_MONOBLACK:
  107.         pal = monoblack_pal;
  108.         break;
  109.     }
  110.     if (pal && !pal_entries) pal_entries = 1 << bit_count;
  111.     n_bytes_per_row = ((int64_t)avctx->width * (int64_t)bit_count + 7LL) >> 3LL;
  112.     pad_bytes_per_row = (4 - n_bytes_per_row) & 3;
  113.     n_bytes_image = avctx->height * (n_bytes_per_row + pad_bytes_per_row);
  114.  
  115.     // STRUCTURE.field refer to the MSVC documentation for BITMAPFILEHEADER
  116.     // and related pages.
  117. #define SIZE_BITMAPFILEHEADER 14
  118. #define SIZE_BITMAPINFOHEADER 40
  119.     hsize = SIZE_BITMAPFILEHEADER + SIZE_BITMAPINFOHEADER + (pal_entries << 2);
  120.     n_bytes = n_bytes_image + hsize;
  121.     if ((ret = ff_alloc_packet2(avctx, pkt, n_bytes, 0)) < 0)
  122.         return ret;
  123.     buf = pkt->data;
  124.     bytestream_put_byte(&buf, 'B');                   // BITMAPFILEHEADER.bfType
  125.     bytestream_put_byte(&buf, 'M');                   // do.
  126.     bytestream_put_le32(&buf, n_bytes);               // BITMAPFILEHEADER.bfSize
  127.     bytestream_put_le16(&buf, 0);                     // BITMAPFILEHEADER.bfReserved1
  128.     bytestream_put_le16(&buf, 0);                     // BITMAPFILEHEADER.bfReserved2
  129.     bytestream_put_le32(&buf, hsize);                 // BITMAPFILEHEADER.bfOffBits
  130.     bytestream_put_le32(&buf, SIZE_BITMAPINFOHEADER); // BITMAPINFOHEADER.biSize
  131.     bytestream_put_le32(&buf, avctx->width);          // BITMAPINFOHEADER.biWidth
  132.     bytestream_put_le32(&buf, avctx->height);         // BITMAPINFOHEADER.biHeight
  133.     bytestream_put_le16(&buf, 1);                     // BITMAPINFOHEADER.biPlanes
  134.     bytestream_put_le16(&buf, bit_count);             // BITMAPINFOHEADER.biBitCount
  135.     bytestream_put_le32(&buf, compression);           // BITMAPINFOHEADER.biCompression
  136.     bytestream_put_le32(&buf, n_bytes_image);         // BITMAPINFOHEADER.biSizeImage
  137.     bytestream_put_le32(&buf, 0);                     // BITMAPINFOHEADER.biXPelsPerMeter
  138.     bytestream_put_le32(&buf, 0);                     // BITMAPINFOHEADER.biYPelsPerMeter
  139.     bytestream_put_le32(&buf, 0);                     // BITMAPINFOHEADER.biClrUsed
  140.     bytestream_put_le32(&buf, 0);                     // BITMAPINFOHEADER.biClrImportant
  141.     for (i = 0; i < pal_entries; i++)
  142.         bytestream_put_le32(&buf, pal[i] & 0xFFFFFF);
  143.     // BMP files are bottom-to-top so we start from the end...
  144.     ptr = p->data[0] + (avctx->height - 1) * p->linesize[0];
  145.     buf = pkt->data + hsize;
  146.     for(i = 0; i < avctx->height; i++) {
  147.         if (bit_count == 16) {
  148.             const uint16_t *src = (const uint16_t *) ptr;
  149.             uint16_t *dst = (uint16_t *) buf;
  150.             for(n = 0; n < avctx->width; n++)
  151.                 AV_WL16(dst + n, src[n]);
  152.         } else {
  153.             memcpy(buf, ptr, n_bytes_per_row);
  154.         }
  155.         buf += n_bytes_per_row;
  156.         memset(buf, 0, pad_bytes_per_row);
  157.         buf += pad_bytes_per_row;
  158.         ptr -= p->linesize[0]; // ... and go back
  159.     }
  160.  
  161.     pkt->flags |= AV_PKT_FLAG_KEY;
  162.     *got_packet = 1;
  163.     return 0;
  164. }
  165.  
  166. AVCodec ff_bmp_encoder = {
  167.     .name           = "bmp",
  168.     .long_name      = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"),
  169.     .type           = AVMEDIA_TYPE_VIDEO,
  170.     .id             = AV_CODEC_ID_BMP,
  171.     .init           = bmp_encode_init,
  172.     .encode2        = bmp_encode_frame,
  173.     .pix_fmts       = (const enum AVPixelFormat[]){
  174.         AV_PIX_FMT_BGRA, AV_PIX_FMT_BGR24,
  175.         AV_PIX_FMT_RGB565, AV_PIX_FMT_RGB555, AV_PIX_FMT_RGB444,
  176.         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,
  177.         AV_PIX_FMT_MONOBLACK,
  178.         AV_PIX_FMT_NONE
  179.     },
  180. };
  181.