GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/pamenc.c Lines: 65 86 75.6 %
Date: 2019-11-22 03:34:36 Branches: 15 20 75.0 %

Line Branch Exec Source
1
/*
2
 * PAM image format
3
 * Copyright (c) 2002, 2003 Fabrice Bellard
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
22
#include "avcodec.h"
23
#include "internal.h"
24
25
78
static int pam_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
26
                            const AVFrame *p, int *got_packet)
27
{
28
    uint8_t *bytestream_start, *bytestream, *bytestream_end;
29
    int i, h, w, n, linesize, depth, maxval, ret;
30
    const char *tuple_type;
31
    uint8_t *ptr;
32
33
78
    h = avctx->height;
34
78
    w = avctx->width;
35


78
    switch (avctx->pix_fmt) {
36
13
    case AV_PIX_FMT_MONOBLACK:
37
13
        n          = w;
38
13
        depth      = 1;
39
13
        maxval     = 1;
40
13
        tuple_type = "BLACKANDWHITE";
41
13
        break;
42
13
    case AV_PIX_FMT_GRAY8:
43
13
        n          = w;
44
13
        depth      = 1;
45
13
        maxval     = 255;
46
13
        tuple_type = "GRAYSCALE";
47
13
        break;
48
13
    case AV_PIX_FMT_GRAY16BE:
49
13
        n          = w * 2;
50
13
        depth      = 1;
51
13
        maxval     = 0xFFFF;
52
13
        tuple_type = "GRAYSCALE";
53
13
        break;
54
    case AV_PIX_FMT_GRAY8A:
55
        n          = w * 2;
56
        depth      = 2;
57
        maxval     = 255;
58
        tuple_type = "GRAYSCALE_ALPHA";
59
        break;
60
    case AV_PIX_FMT_YA16BE:
61
        n          = w * 4;
62
        depth      = 2;
63
        maxval     = 0xFFFF;
64
        tuple_type = "GRAYSCALE_ALPHA";
65
        break;
66
13
    case AV_PIX_FMT_RGB24:
67
13
        n          = w * 3;
68
13
        depth      = 3;
69
13
        maxval     = 255;
70
13
        tuple_type = "RGB";
71
13
        break;
72
13
    case AV_PIX_FMT_RGBA:
73
13
        n          = w * 4;
74
13
        depth      = 4;
75
13
        maxval     = 255;
76
13
        tuple_type = "RGB_ALPHA";
77
13
        break;
78
13
    case AV_PIX_FMT_RGB48BE:
79
13
        n          = w * 6;
80
13
        depth      = 3;
81
13
        maxval     = 0xFFFF;
82
13
        tuple_type = "RGB";
83
13
        break;
84
    case AV_PIX_FMT_RGBA64BE:
85
        n          = w * 8;
86
        depth      = 4;
87
        maxval     = 0xFFFF;
88
        tuple_type = "RGB_ALPHA";
89
        break;
90
    default:
91
        return -1;
92
    }
93
94
78
    if ((ret = ff_alloc_packet2(avctx, pkt, n*h + 200, 0)) < 0)
95
        return ret;
96
97
78
    bytestream_start =
98
78
    bytestream       = pkt->data;
99
78
    bytestream_end   = pkt->data + pkt->size;
100
101
78
    snprintf(bytestream, bytestream_end - bytestream,
102
             "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
103
             w, h, depth, maxval, tuple_type);
104
78
    bytestream += strlen(bytestream);
105
106
78
    ptr      = p->data[0];
107
78
    linesize = p->linesize[0];
108
109
78
    if (avctx->pix_fmt == AV_PIX_FMT_MONOBLACK){
110
        int j;
111
3757
        for (i = 0; i < h; i++) {
112
1321632
            for (j = 0; j < w; j++)
113
1317888
                *bytestream++ = ptr[j >> 3] >> (7 - j & 7) & 1;
114
3744
            ptr += linesize;
115
        }
116
    } else {
117
18785
        for (i = 0; i < h; i++) {
118
18720
            memcpy(bytestream, ptr, n);
119
18720
            bytestream += n;
120
18720
            ptr        += linesize;
121
        }
122
    }
123
124
78
    pkt->size   = bytestream - bytestream_start;
125
78
    pkt->flags |= AV_PKT_FLAG_KEY;
126
78
    *got_packet = 1;
127
78
    return 0;
128
}
129
130
6
static av_cold int pam_encode_init(AVCodecContext *avctx)
131
{
132
#if FF_API_CODED_FRAME
133
FF_DISABLE_DEPRECATION_WARNINGS
134
6
    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
135
6
    avctx->coded_frame->key_frame = 1;
136
FF_ENABLE_DEPRECATION_WARNINGS
137
#endif
138
139
6
    return 0;
140
}
141
142
AVCodec ff_pam_encoder = {
143
    .name           = "pam",
144
    .long_name      = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"),
145
    .type           = AVMEDIA_TYPE_VIDEO,
146
    .id             = AV_CODEC_ID_PAM,
147
    .init           = pam_encode_init,
148
    .encode2        = pam_encode_frame,
149
    .pix_fmts       = (const enum AVPixelFormat[]){
150
        AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA,
151
        AV_PIX_FMT_RGB48BE, AV_PIX_FMT_RGBA64BE,
152
        AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY8A,
153
        AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_YA16BE,
154
        AV_PIX_FMT_MONOBLACK, AV_PIX_FMT_NONE
155
    },
156
};