GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/xwdenc.c Lines: 120 135 88.9 %
Date: 2020-08-14 10:39:37 Branches: 24 36 66.7 %

Line Branch Exec Source
1
/*
2
 * XWD image format
3
 *
4
 * Copyright (c) 2012 Paul B Mahol
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/intreadwrite.h"
24
#include "libavutil/pixdesc.h"
25
#include "avcodec.h"
26
#include "bytestream.h"
27
#include "internal.h"
28
#include "xwd.h"
29
30
#define WINDOW_NAME         "lavcxwdenc"
31
#define WINDOW_NAME_SIZE    11
32
33
104
static int xwd_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
34
                            const AVFrame *pict, int *got_packet)
35
{
36
104
    enum AVPixelFormat pix_fmt = avctx->pix_fmt;
37
104
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
38
104
    uint32_t pixdepth, bpp, bpad, ncolors = 0, lsize, vclass, be = 0;
39
104
    uint32_t rgb[3] = { 0 }, bitorder = 0;
40
    uint32_t header_size;
41
    int i, out_size, ret;
42
    uint8_t *ptr, *buf;
43
104
    AVFrame * const p = (AVFrame *)pict;
44
    uint32_t pal[256];
45
46
104
    pixdepth = av_get_bits_per_pixel(desc);
47
104
    if (desc->flags & AV_PIX_FMT_FLAG_BE)
48
26
        be = 1;
49


104
    switch (pix_fmt) {
50
13
    case AV_PIX_FMT_ARGB:
51
    case AV_PIX_FMT_BGRA:
52
    case AV_PIX_FMT_RGBA:
53
    case AV_PIX_FMT_ABGR:
54

13
        if (pix_fmt == AV_PIX_FMT_ARGB ||
55
            pix_fmt == AV_PIX_FMT_ABGR)
56
            be = 1;
57

13
        if (pix_fmt == AV_PIX_FMT_ABGR ||
58
            pix_fmt == AV_PIX_FMT_RGBA) {
59
13
            rgb[0] = 0xFF;
60
13
            rgb[1] = 0xFF00;
61
13
            rgb[2] = 0xFF0000;
62
        } else {
63
            rgb[0] = 0xFF0000;
64
            rgb[1] = 0xFF00;
65
            rgb[2] = 0xFF;
66
        }
67
13
        bpp      = 32;
68
13
        pixdepth = 24;
69
13
        vclass   = XWD_TRUE_COLOR;
70
13
        bpad     = 32;
71
13
        break;
72
13
    case AV_PIX_FMT_BGR24:
73
    case AV_PIX_FMT_RGB24:
74
13
        if (pix_fmt == AV_PIX_FMT_RGB24)
75
13
            be = 1;
76
13
        bpp      = 24;
77
13
        vclass   = XWD_TRUE_COLOR;
78
13
        bpad     = 32;
79
13
        rgb[0]   = 0xFF0000;
80
13
        rgb[1]   = 0xFF00;
81
13
        rgb[2]   = 0xFF;
82
13
        break;
83
13
    case AV_PIX_FMT_RGB565LE:
84
    case AV_PIX_FMT_RGB565BE:
85
    case AV_PIX_FMT_BGR565LE:
86
    case AV_PIX_FMT_BGR565BE:
87

13
        if (pix_fmt == AV_PIX_FMT_BGR565LE ||
88
            pix_fmt == AV_PIX_FMT_BGR565BE) {
89
            rgb[0] = 0x1F;
90
            rgb[1] = 0x7E0;
91
            rgb[2] = 0xF800;
92
        } else {
93
13
            rgb[0] = 0xF800;
94
13
            rgb[1] = 0x7E0;
95
13
            rgb[2] = 0x1F;
96
        }
97
13
        bpp      = 16;
98
13
        vclass   = XWD_TRUE_COLOR;
99
13
        bpad     = 16;
100
13
        break;
101
13
    case AV_PIX_FMT_RGB555LE:
102
    case AV_PIX_FMT_RGB555BE:
103
    case AV_PIX_FMT_BGR555LE:
104
    case AV_PIX_FMT_BGR555BE:
105

13
        if (pix_fmt == AV_PIX_FMT_BGR555LE ||
106
            pix_fmt == AV_PIX_FMT_BGR555BE) {
107
            rgb[0] = 0x1F;
108
            rgb[1] = 0x3E0;
109
            rgb[2] = 0x7C00;
110
        } else {
111
13
            rgb[0] = 0x7C00;
112
13
            rgb[1] = 0x3E0;
113
13
            rgb[2] = 0x1F;
114
        }
115
13
        bpp      = 16;
116
13
        vclass   = XWD_TRUE_COLOR;
117
13
        bpad     = 16;
118
13
        break;
119
26
    case AV_PIX_FMT_RGB8:
120
    case AV_PIX_FMT_BGR8:
121
    case AV_PIX_FMT_RGB4_BYTE:
122
    case AV_PIX_FMT_BGR4_BYTE:
123
    case AV_PIX_FMT_PAL8:
124
26
        bpp      = 8;
125
26
        vclass   = XWD_PSEUDO_COLOR;
126
26
        bpad     = 8;
127
26
        ncolors  = 256;
128
26
        break;
129
13
    case AV_PIX_FMT_GRAY8:
130
13
        bpp      = 8;
131
13
        bpad     = 8;
132
13
        vclass   = XWD_STATIC_GRAY;
133
13
        break;
134
13
    case AV_PIX_FMT_MONOWHITE:
135
13
        be       = 1;
136
13
        bitorder = 1;
137
13
        bpp      = 1;
138
13
        bpad     = 8;
139
13
        vclass   = XWD_STATIC_GRAY;
140
13
        break;
141
    default:
142
        av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n");
143
        return AVERROR(EINVAL);
144
    }
145
146
104
    lsize       = FFALIGN(bpp * avctx->width, bpad) / 8;
147
104
    header_size = XWD_HEADER_SIZE + WINDOW_NAME_SIZE;
148
104
    out_size    = header_size + ncolors * XWD_CMAP_SIZE + avctx->height * lsize;
149
150
104
    if ((ret = ff_alloc_packet2(avctx, pkt, out_size, 0)) < 0)
151
        return ret;
152
104
    buf = pkt->data;
153
154
104
    p->key_frame = 1;
155
104
    p->pict_type = AV_PICTURE_TYPE_I;
156
157
104
    bytestream_put_be32(&buf, header_size);
158
104
    bytestream_put_be32(&buf, XWD_VERSION);   // file version
159
104
    bytestream_put_be32(&buf, XWD_Z_PIXMAP);  // pixmap format
160
104
    bytestream_put_be32(&buf, pixdepth);      // pixmap depth in pixels
161
104
    bytestream_put_be32(&buf, avctx->width);  // pixmap width in pixels
162
104
    bytestream_put_be32(&buf, avctx->height); // pixmap height in pixels
163
104
    bytestream_put_be32(&buf, 0);             // bitmap x offset
164
104
    bytestream_put_be32(&buf, be);            // byte order
165
104
    bytestream_put_be32(&buf, 32);            // bitmap unit
166
104
    bytestream_put_be32(&buf, bitorder);      // bit-order of image data
167
104
    bytestream_put_be32(&buf, bpad);          // bitmap scan-line pad in bits
168
104
    bytestream_put_be32(&buf, bpp);           // bits per pixel
169
104
    bytestream_put_be32(&buf, lsize);         // bytes per scan-line
170
104
    bytestream_put_be32(&buf, vclass);        // visual class
171
104
    bytestream_put_be32(&buf, rgb[0]);        // red mask
172
104
    bytestream_put_be32(&buf, rgb[1]);        // green mask
173
104
    bytestream_put_be32(&buf, rgb[2]);        // blue mask
174
104
    bytestream_put_be32(&buf, 8);             // size of each bitmask in bits
175
104
    bytestream_put_be32(&buf, ncolors);       // number of colors
176
104
    bytestream_put_be32(&buf, ncolors);       // number of entries in color map
177
104
    bytestream_put_be32(&buf, avctx->width);  // window width
178
104
    bytestream_put_be32(&buf, avctx->height); // window height
179
104
    bytestream_put_be32(&buf, 0);             // window upper left X coordinate
180
104
    bytestream_put_be32(&buf, 0);             // window upper left Y coordinate
181
104
    bytestream_put_be32(&buf, 0);             // window border width
182
104
    bytestream_put_buffer(&buf, WINDOW_NAME, WINDOW_NAME_SIZE);
183
184
104
    if (pix_fmt == AV_PIX_FMT_PAL8) {
185
        memcpy(pal, p->data[1], sizeof(pal));
186
    } else {
187
104
        avpriv_set_systematic_pal2(pal, pix_fmt);
188
    }
189
190
6760
    for (i = 0; i < ncolors; i++) {
191
        uint32_t val;
192
        uint8_t red, green, blue;
193
194
6656
        val   = pal[i];
195
6656
        red   = (val >> 16) & 0xFF;
196
6656
        green = (val >>  8) & 0xFF;
197
6656
        blue  =  val        & 0xFF;
198
199
6656
        bytestream_put_be32(&buf, i);         // colormap entry number
200
6656
        bytestream_put_be16(&buf, red   << 8);
201
6656
        bytestream_put_be16(&buf, green << 8);
202
6656
        bytestream_put_be16(&buf, blue  << 8);
203
6656
        bytestream_put_byte(&buf, 0x7);       // bitmask flag
204
6656
        bytestream_put_byte(&buf, 0);         // padding
205
    }
206
207
104
    ptr = p->data[0];
208
30056
    for (i = 0; i < avctx->height; i++) {
209
29952
        bytestream_put_buffer(&buf, ptr, lsize);
210
29952
        ptr += p->linesize[0];
211
    }
212
213
104
    pkt->flags |= AV_PKT_FLAG_KEY;
214
104
    *got_packet = 1;
215
104
    return 0;
216
}
217
218
AVCodec ff_xwd_encoder = {
219
    .name         = "xwd",
220
    .long_name    = NULL_IF_CONFIG_SMALL("XWD (X Window Dump) image"),
221
    .type         = AVMEDIA_TYPE_VIDEO,
222
    .id           = AV_CODEC_ID_XWD,
223
    .encode2      = xwd_encode_frame,
224
    .pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGRA,
225
                                                 AV_PIX_FMT_RGBA,
226
                                                 AV_PIX_FMT_ARGB,
227
                                                 AV_PIX_FMT_ABGR,
228
                                                 AV_PIX_FMT_RGB24,
229
                                                 AV_PIX_FMT_BGR24,
230
                                                 AV_PIX_FMT_RGB565BE,
231
                                                 AV_PIX_FMT_RGB565LE,
232
                                                 AV_PIX_FMT_BGR565BE,
233
                                                 AV_PIX_FMT_BGR565LE,
234
                                                 AV_PIX_FMT_RGB555BE,
235
                                                 AV_PIX_FMT_RGB555LE,
236
                                                 AV_PIX_FMT_BGR555BE,
237
                                                 AV_PIX_FMT_BGR555LE,
238
                                                 AV_PIX_FMT_RGB8,
239
                                                 AV_PIX_FMT_BGR8,
240
                                                 AV_PIX_FMT_RGB4_BYTE,
241
                                                 AV_PIX_FMT_BGR4_BYTE,
242
                                                 AV_PIX_FMT_PAL8,
243
                                                 AV_PIX_FMT_GRAY8,
244
                                                 AV_PIX_FMT_MONOWHITE,
245
                                                 AV_PIX_FMT_NONE },
246
};