annotate bmpenc.c @ 8204:507854688c43 libavcodec

Some BMP files have file size declared in the header equal to headers size without image data, so try to correct that value before conducting checks on declared file size.
author kostya
date Mon, 24 Nov 2008 11:24:02 +0000
parents e943e1409077
children c48f55549c06
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4477
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
1 /*
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
2 * BMP image format encoder
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
3 * Copyright (c) 2006, 2007 Michel Bardiaux
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
4 *
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
5 * This file is part of FFmpeg.
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
6 *
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
11 *
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
15 * Lesser General Public License for more details.
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
16 *
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
20 */
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
21
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
22 #include "avcodec.h"
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
23 #include "bytestream.h"
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
24 #include "bmp.h"
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
25
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 4477
diff changeset
26 static av_cold int bmp_encode_init(AVCodecContext *avctx){
4477
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
27 BMPContext *s = avctx->priv_data;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
28
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
29 avcodec_get_frame_defaults((AVFrame*)&s->picture);
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
30 avctx->coded_frame = (AVFrame*)&s->picture;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
31
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
32 return 0;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
33 }
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
34
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
35 static int bmp_encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
36 BMPContext *s = avctx->priv_data;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
37 AVFrame *pict = data;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
38 AVFrame * const p= (AVFrame*)&s->picture;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
39 int n_bytes_image, n_bytes_per_row, n_bytes, i, n, hsize;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
40 uint8_t *ptr;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
41 unsigned char* buf0 = buf;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
42 *p = *pict;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
43 p->pict_type= FF_I_TYPE;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
44 p->key_frame= 1;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
45 n_bytes_per_row = (avctx->width*3 + 3) & ~3;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
46 n_bytes_image = avctx->height*n_bytes_per_row;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
47
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
48 // STRUCTURE.field refer to the MSVC documentation for BITMAPFILEHEADER
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
49 // and related pages.
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
50 #define SIZE_BITMAPFILEHEADER 14
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
51 #define SIZE_BITMAPINFOHEADER 40
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
52 hsize = SIZE_BITMAPFILEHEADER + SIZE_BITMAPINFOHEADER;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
53 n_bytes = n_bytes_image + hsize;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
54 if(n_bytes>buf_size) {
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
55 av_log(avctx, AV_LOG_ERROR, "buf size too small (need %d, got %d)\n", n_bytes, buf_size);
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
56 return -1;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
57 }
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
58 bytestream_put_byte(&buf, 'B'); // BITMAPFILEHEADER.bfType
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
59 bytestream_put_byte(&buf, 'M'); // do.
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
60 bytestream_put_le32(&buf, n_bytes); // BITMAPFILEHEADER.bfSize
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
61 bytestream_put_le16(&buf, 0); // BITMAPFILEHEADER.bfReserved1
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
62 bytestream_put_le16(&buf, 0); // BITMAPFILEHEADER.bfReserved2
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
63 bytestream_put_le32(&buf, hsize); // BITMAPFILEHEADER.bfOffBits
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
64 bytestream_put_le32(&buf, SIZE_BITMAPINFOHEADER); // BITMAPINFOHEADER.biSize
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
65 bytestream_put_le32(&buf, avctx->width); // BITMAPINFOHEADER.biWidth
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
66 bytestream_put_le32(&buf, avctx->height); // BITMAPINFOHEADER.biHeight
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
67 bytestream_put_le16(&buf, 1); // BITMAPINFOHEADER.biPlanes
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
68 bytestream_put_le16(&buf, 24); // BITMAPINFOHEADER.biBitCount
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
69 bytestream_put_le32(&buf, BMP_RGB); // BITMAPINFOHEADER.biCompression
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
70 bytestream_put_le32(&buf, n_bytes_image); // BITMAPINFOHEADER.biSizeImage
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
71 bytestream_put_le32(&buf, 0); // BITMAPINFOHEADER.biXPelsPerMeter
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
72 bytestream_put_le32(&buf, 0); // BITMAPINFOHEADER.biYPelsPerMeter
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
73 bytestream_put_le32(&buf, 0); // BITMAPINFOHEADER.biClrUsed
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
74 bytestream_put_le32(&buf, 0); // BITMAPINFOHEADER.biClrImportant
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
75 // BMP files are bottom-to-top so we start from the end...
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
76 ptr = p->data[0] + (avctx->height - 1) * p->linesize[0];
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
77 buf = buf0 + hsize;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
78 for(i = 0; i < avctx->height; i++) {
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
79 n = 3*avctx->width;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
80 memcpy(buf, ptr, n);
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
81 buf += n;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
82 memset(buf, 0, n_bytes_per_row-n);
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
83 buf += n_bytes_per_row-n;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
84 ptr -= p->linesize[0]; // ... and go back
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
85 }
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
86 return n_bytes;
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
87 }
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
88
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
89 AVCodec bmp_encoder = {
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
90 "bmp",
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
91 CODEC_TYPE_VIDEO,
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
92 CODEC_ID_BMP,
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
93 sizeof(BMPContext),
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
94 bmp_encode_init,
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
95 bmp_encode_frame,
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
96 NULL, //encode_end,
6788
e1302edb0f69 Replace some occurrences of -1 with PIX_FMT_NONE.
cehoyos
parents: 6722
diff changeset
97 .pix_fmts= (enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_NONE},
7040
e943e1409077 Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents: 6788
diff changeset
98 .long_name = NULL_IF_CONFIG_SMALL("BMP image"),
4477
87e943798698 BMP encoder by Michel Bardiaux, mbardiaux mediaxim be
diego
parents:
diff changeset
99 };