Coverage Report

Created: 2026-04-01 07:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavcodec/pamenc.c
Line
Count
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 "libavutil/avassert.h"
23
#include "avcodec.h"
24
#include "codec_internal.h"
25
#include "encode.h"
26
27
static int pam_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
28
                            const AVFrame *p, int *got_packet)
29
9.01k
{
30
9.01k
    int i, h, w, n, linesize, depth, maxval, ret, header_size;
31
9.01k
    uint8_t *bytestream;
32
9.01k
    const uint8_t *ptr;
33
9.01k
    const char *tuple_type;
34
9.01k
    char header[100];
35
36
9.01k
    h = avctx->height;
37
9.01k
    w = avctx->width;
38
9.01k
    switch (avctx->pix_fmt) {
39
1.36k
    case AV_PIX_FMT_MONOBLACK:
40
1.36k
        n          = w;
41
1.36k
        depth      = 1;
42
1.36k
        maxval     = 1;
43
1.36k
        tuple_type = "BLACKANDWHITE";
44
1.36k
        break;
45
642
    case AV_PIX_FMT_GRAY8:
46
642
        n          = w;
47
642
        depth      = 1;
48
642
        maxval     = 255;
49
642
        tuple_type = "GRAYSCALE";
50
642
        break;
51
1.20k
    case AV_PIX_FMT_GRAY16BE:
52
1.20k
        n          = w * 2;
53
1.20k
        depth      = 1;
54
1.20k
        maxval     = 0xFFFF;
55
1.20k
        tuple_type = "GRAYSCALE";
56
1.20k
        break;
57
435
    case AV_PIX_FMT_GRAY8A:
58
435
        n          = w * 2;
59
435
        depth      = 2;
60
435
        maxval     = 255;
61
435
        tuple_type = "GRAYSCALE_ALPHA";
62
435
        break;
63
1.12k
    case AV_PIX_FMT_YA16BE:
64
1.12k
        n          = w * 4;
65
1.12k
        depth      = 2;
66
1.12k
        maxval     = 0xFFFF;
67
1.12k
        tuple_type = "GRAYSCALE_ALPHA";
68
1.12k
        break;
69
218
    case AV_PIX_FMT_RGB24:
70
218
        n          = w * 3;
71
218
        depth      = 3;
72
218
        maxval     = 255;
73
218
        tuple_type = "RGB";
74
218
        break;
75
1.73k
    case AV_PIX_FMT_RGBA:
76
1.73k
        n          = w * 4;
77
1.73k
        depth      = 4;
78
1.73k
        maxval     = 255;
79
1.73k
        tuple_type = "RGB_ALPHA";
80
1.73k
        break;
81
195
    case AV_PIX_FMT_RGB48BE:
82
195
        n          = w * 6;
83
195
        depth      = 3;
84
195
        maxval     = 0xFFFF;
85
195
        tuple_type = "RGB";
86
195
        break;
87
2.10k
    case AV_PIX_FMT_RGBA64BE:
88
2.10k
        n          = w * 8;
89
2.10k
        depth      = 4;
90
2.10k
        maxval     = 0xFFFF;
91
2.10k
        tuple_type = "RGB_ALPHA";
92
2.10k
        break;
93
0
    default:
94
0
        return -1;
95
9.01k
    }
96
97
9.01k
    header_size = snprintf(header, sizeof(header),
98
9.01k
             "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
99
9.01k
             w, h, depth, maxval, tuple_type);
100
9.01k
    av_assert1(header_size < sizeof(header));
101
102
9.01k
    if ((ret = ff_get_encode_buffer(avctx, pkt, n*h + header_size, 0)) < 0)
103
0
        return ret;
104
105
9.01k
    bytestream       = pkt->data;
106
9.01k
    memcpy(bytestream, header, header_size);
107
9.01k
    bytestream += header_size;
108
109
9.01k
    ptr      = p->data[0];
110
9.01k
    linesize = p->linesize[0];
111
112
9.01k
    if (avctx->pix_fmt == AV_PIX_FMT_MONOBLACK){
113
1.36k
        int j;
114
770k
        for (i = 0; i < h; i++) {
115
4.80M
            for (j = 0; j < w; j++)
116
4.03M
                *bytestream++ = ptr[j >> 3] >> (7 - j & 7) & 1;
117
769k
            ptr += linesize;
118
769k
        }
119
7.65k
    } else {
120
556k
        for (i = 0; i < h; i++) {
121
548k
            memcpy(bytestream, ptr, n);
122
548k
            bytestream += n;
123
548k
            ptr        += linesize;
124
548k
        }
125
7.65k
    }
126
127
9.01k
    *got_packet = 1;
128
9.01k
    return 0;
129
9.01k
}
130
131
const FFCodec ff_pam_encoder = {
132
    .p.name         = "pam",
133
    CODEC_LONG_NAME("PAM (Portable AnyMap) image"),
134
    .p.type         = AVMEDIA_TYPE_VIDEO,
135
    .p.id           = AV_CODEC_ID_PAM,
136
    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
137
    FF_CODEC_ENCODE_CB(pam_encode_frame),
138
    CODEC_PIXFMTS(AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA,
139
                  AV_PIX_FMT_RGB48BE, AV_PIX_FMT_RGBA64BE,
140
                  AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY8A,
141
                  AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_YA16BE,
142
                  AV_PIX_FMT_MONOBLACK),
143
};