FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/pnmdec.c
Date: 2026-04-10 22:11:37
Exec Total Coverage
Lines: 160 289 55.4%
Functions: 2 3 66.7%
Branches: 70 156 44.9%

Line Branch Exec Source
1 /*
2 * PNM 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 "config_components.h"
23
24 #include "libavutil/half2float.h"
25 #include "libavutil/intfloat.h"
26
27 #include "avcodec.h"
28 #include "codec_internal.h"
29 #include "decode.h"
30 #include "put_bits.h"
31 #include "pnm.h"
32
33 13176832 static void samplecpy(uint8_t *dst, const uint8_t *src, int n, int maxval)
34 {
35
2/2
✓ Branch 0 taken 13169344 times.
✓ Branch 1 taken 7488 times.
13176832 if (maxval <= 255) {
36 13169344 memcpy(dst, src, n);
37 } else {
38 int i;
39
2/2
✓ Branch 0 taken 5271552 times.
✓ Branch 1 taken 7488 times.
5279040 for (i=0; i<n/2; i++) {
40 5271552 ((uint16_t *)dst)[i] = AV_RB16(src+2*i);
41 }
42 }
43 13176832 }
44
45 26115 static int pnm_decode_frame(AVCodecContext *avctx, AVFrame *p,
46 int *got_frame, AVPacket *avpkt)
47 {
48 26115 const uint8_t *buf = avpkt->data;
49 26115 int buf_size = avpkt->size;
50 26115 PNMContext * const s = avctx->priv_data;
51 26115 int i, j, k, n, linesize, h, upgrade = 0, is_mono = 0;
52 unsigned char *ptr;
53 int components, sample_len, ret;
54 float scale;
55
56 26115 s->bytestream_start =
57 26115 s->bytestream = buf;
58 26115 s->bytestream_end = buf + buf_size;
59
60
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 26115 times.
26115 if ((ret = ff_pnm_decode_header(avctx, s)) < 0)
61 return ret;
62
63
2/2
✓ Branch 0 taken 3058 times.
✓ Branch 1 taken 23057 times.
26115 if (avctx->skip_frame >= AVDISCARD_ALL)
64 3058 return avpkt->size;
65
66
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23057 times.
23057 if (avctx->width * avctx->height / 8 > s->bytestream_end - s->bytestream)
67 return AVERROR_INVALIDDATA;
68
69
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 23057 times.
23057 if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
70 return ret;
71 23057 avctx->bits_per_raw_sample = av_log2(s->maxval) + 1;
72
73
9/14
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 13 times.
✓ Branch 4 taken 52 times.
✓ Branch 5 taken 179 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 38 times.
✓ Branch 10 taken 22697 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 26 times.
✓ Branch 13 taken 26 times.
23057 switch (avctx->pix_fmt) {
74 default:
75 return AVERROR(EINVAL);
76 case AV_PIX_FMT_RGBA64:
77 n = avctx->width * 8;
78 components=4;
79 sample_len=16;
80 if (s->maxval < 65535)
81 upgrade = 2;
82 goto do_read;
83 13 case AV_PIX_FMT_RGB48:
84 13 n = avctx->width * 6;
85 13 components=3;
86 13 sample_len=16;
87
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (s->maxval < 65535)
88 upgrade = 2;
89 13 goto do_read;
90 13 case AV_PIX_FMT_RGBA:
91 13 n = avctx->width * 4;
92 13 components=4;
93 13 sample_len=8;
94 13 goto do_read;
95 52 case AV_PIX_FMT_RGB24:
96 52 n = avctx->width * 3;
97 52 components=3;
98 52 sample_len=8;
99
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
52 if (s->maxval < 255)
100 upgrade = 1;
101 52 goto do_read;
102 179 case AV_PIX_FMT_GRAY8:
103 179 n = avctx->width;
104 179 components=1;
105 179 sample_len=8;
106
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 179 times.
179 if (s->maxval < 255)
107 upgrade = 1;
108 179 goto do_read;
109 case AV_PIX_FMT_GRAY8A:
110 n = avctx->width * 2;
111 components=2;
112 sample_len=8;
113 goto do_read;
114 13 case AV_PIX_FMT_GRAY16:
115 13 n = avctx->width * 2;
116 13 components=1;
117 13 sample_len=16;
118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (s->maxval < 65535)
119 upgrade = 2;
120 13 goto do_read;
121 case AV_PIX_FMT_YA16:
122 n = avctx->width * 4;
123 components=2;
124 sample_len=16;
125 if (s->maxval < 65535)
126 upgrade = 2;
127 goto do_read;
128 38 case AV_PIX_FMT_MONOWHITE:
129 case AV_PIX_FMT_MONOBLACK:
130 38 n = (avctx->width + 7) >> 3;
131 38 components=1;
132 38 sample_len=1;
133 38 is_mono = 1;
134 308 do_read:
135 308 ptr = p->data[0];
136 308 linesize = p->linesize[0];
137
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 308 times.
308 if (n * avctx->height > s->bytestream_end - s->bytestream)
138 return AVERROR_INVALIDDATA;
139
5/6
✓ Branch 0 taken 308 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 270 times.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 25 times.
308 if(s->type < 4 || (is_mono && s->type==7)){
140
2/2
✓ Branch 0 taken 3744 times.
✓ Branch 1 taken 13 times.
3757 for (i=0; i<avctx->height; i++) {
141 PutBitContext pb;
142 3744 init_put_bits(&pb, ptr, FFABS(linesize));
143
2/2
✓ Branch 0 taken 1317888 times.
✓ Branch 1 taken 3744 times.
1321632 for(j=0; j<avctx->width * components; j++){
144 1317888 unsigned int c=0;
145 1317888 unsigned v=0;
146
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1317888 times.
1317888 if(s->type < 4)
147 while(s->bytestream < s->bytestream_end && (*s->bytestream < '0' || *s->bytestream > '9' ))
148 s->bytestream++;
149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1317888 times.
1317888 if(s->bytestream >= s->bytestream_end)
150 return AVERROR_INVALIDDATA;
151
1/2
✓ Branch 0 taken 1317888 times.
✗ Branch 1 not taken.
1317888 if (is_mono) {
152 /* read a single digit */
153 1317888 v = (*s->bytestream++)&1;
154 } else {
155 /* read a sequence of digits */
156 for (k = 0; k < 6 && c <= 9; k += 1) {
157 v = 10*v + c;
158 c = (*s->bytestream++) - '0';
159 }
160 if (v > s->maxval) {
161 av_log(avctx, AV_LOG_ERROR, "value %d larger than maxval %d\n", v, s->maxval);
162 return AVERROR_INVALIDDATA;
163 }
164 }
165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1317888 times.
1317888 if (sample_len == 16) {
166 ((uint16_t*)ptr)[j] = (((1<<sample_len)-1)*v + (s->maxval>>1))/s->maxval;
167 } else
168 1317888 put_bits(&pb, sample_len, (((1<<sample_len)-1)*v + (s->maxval>>1))/s->maxval);
169 }
170
1/2
✓ Branch 0 taken 3744 times.
✗ Branch 1 not taken.
3744 if (sample_len != 16)
171 3744 flush_put_bits(&pb);
172 3744 ptr+= linesize;
173 }
174 }else{
175
2/2
✓ Branch 0 taken 103360 times.
✓ Branch 1 taken 295 times.
103655 for (int i = 0; i < avctx->height; i++) {
176
1/2
✓ Branch 0 taken 103360 times.
✗ Branch 1 not taken.
103360 if (!upgrade)
177 103360 samplecpy(ptr, s->bytestream, n, s->maxval);
178 else if (upgrade == 1) {
179 unsigned int f = (255 * 128 + s->maxval / 2) / s->maxval;
180 for (unsigned j = 0; j < n; j++)
181 ptr[j] = (s->bytestream[j] * f + 64) >> 7;
182 } else if (upgrade == 2) {
183 unsigned int f = (65535 * 32768 + s->maxval / 2) / s->maxval;
184 for (unsigned j = 0; j < n / 2; j++) {
185 unsigned v = AV_RB16(s->bytestream + 2*j);
186 ((uint16_t *)ptr)[j] = (v * f + 16384) >> 15;
187 }
188 }
189 103360 s->bytestream += n;
190 103360 ptr += linesize;
191 }
192 }
193 308 break;
194 22697 case AV_PIX_FMT_YUV420P:
195 case AV_PIX_FMT_YUV420P9:
196 case AV_PIX_FMT_YUV420P10:
197 {
198 unsigned char *ptr1, *ptr2;
199
200 22697 n = avctx->width;
201 22697 ptr = p->data[0];
202 22697 linesize = p->linesize[0];
203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22697 times.
22697 if (s->maxval >= 256)
204 n *= 2;
205
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22697 times.
22697 if (n * avctx->height * 3 / 2 > s->bytestream_end - s->bytestream)
206 return AVERROR_INVALIDDATA;
207
2/2
✓ Branch 0 taken 6536736 times.
✓ Branch 1 taken 22697 times.
6559433 for (i = 0; i < avctx->height; i++) {
208 6536736 samplecpy(ptr, s->bytestream, n, s->maxval);
209 6536736 s->bytestream += n;
210 6536736 ptr += linesize;
211 }
212 22697 ptr1 = p->data[1];
213 22697 ptr2 = p->data[2];
214 22697 n >>= 1;
215 22697 h = avctx->height >> 1;
216
2/2
✓ Branch 0 taken 3268368 times.
✓ Branch 1 taken 22697 times.
3291065 for (i = 0; i < h; i++) {
217 3268368 samplecpy(ptr1, s->bytestream, n, s->maxval);
218 3268368 s->bytestream += n;
219 3268368 samplecpy(ptr2, s->bytestream, n, s->maxval);
220 3268368 s->bytestream += n;
221 3268368 ptr1 += p->linesize[1];
222 3268368 ptr2 += p->linesize[2];
223 }
224 }
225 22697 break;
226 case AV_PIX_FMT_YUV420P16:
227 {
228 uint16_t *ptr1, *ptr2;
229 const int f = (65535 * 32768 + s->maxval / 2) / s->maxval;
230 unsigned int j, v;
231
232 n = avctx->width * 2;
233 ptr = p->data[0];
234 linesize = p->linesize[0];
235 if (n * avctx->height * 3 / 2 > s->bytestream_end - s->bytestream)
236 return AVERROR_INVALIDDATA;
237 for (i = 0; i < avctx->height; i++) {
238 for (j = 0; j < n / 2; j++) {
239 v = AV_RB16(s->bytestream + 2*j);
240 ((uint16_t *)ptr)[j] = (v * f + 16384) >> 15;
241 }
242 s->bytestream += n;
243 ptr += linesize;
244 }
245 ptr1 = (uint16_t*)p->data[1];
246 ptr2 = (uint16_t*)p->data[2];
247 n >>= 1;
248 h = avctx->height >> 1;
249 for (i = 0; i < h; i++) {
250 for (j = 0; j < n / 2; j++) {
251 v = AV_RB16(s->bytestream + 2*j);
252 ptr1[j] = (v * f + 16384) >> 15;
253 }
254 s->bytestream += n;
255
256 for (j = 0; j < n / 2; j++) {
257 v = AV_RB16(s->bytestream + 2*j);
258 ptr2[j] = (v * f + 16384) >> 15;
259 }
260 s->bytestream += n;
261
262 ptr1 += p->linesize[1] / 2;
263 ptr2 += p->linesize[2] / 2;
264 }
265 }
266 break;
267 26 case AV_PIX_FMT_GBRPF32:
268
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (!s->half) {
269
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (avctx->width * avctx->height * 12LL > s->bytestream_end - s->bytestream)
270 return AVERROR_INVALIDDATA;
271 26 scale = 1.f / s->scale;
272
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 13 times.
26 if (s->endian) {
273 float *r, *g, *b;
274
275 13 r = (float *)p->data[2];
276 13 g = (float *)p->data[0];
277 13 b = (float *)p->data[1];
278
2/2
✓ Branch 0 taken 3744 times.
✓ Branch 1 taken 13 times.
3757 for (int i = 0; i < avctx->height; i++) {
279
2/2
✓ Branch 0 taken 1317888 times.
✓ Branch 1 taken 3744 times.
1321632 for (int j = 0; j < avctx->width; j++) {
280 1317888 r[j] = av_int2float(AV_RL32(s->bytestream+0)) * scale;
281 1317888 g[j] = av_int2float(AV_RL32(s->bytestream+4)) * scale;
282 1317888 b[j] = av_int2float(AV_RL32(s->bytestream+8)) * scale;
283 1317888 s->bytestream += 12;
284 }
285
286 3744 r += p->linesize[2] / 4;
287 3744 g += p->linesize[0] / 4;
288 3744 b += p->linesize[1] / 4;
289 }
290 } else {
291 float *r, *g, *b;
292
293 13 r = (float *)p->data[2];
294 13 g = (float *)p->data[0];
295 13 b = (float *)p->data[1];
296
2/2
✓ Branch 0 taken 3744 times.
✓ Branch 1 taken 13 times.
3757 for (int i = 0; i < avctx->height; i++) {
297
2/2
✓ Branch 0 taken 1317888 times.
✓ Branch 1 taken 3744 times.
1321632 for (int j = 0; j < avctx->width; j++) {
298 1317888 r[j] = av_int2float(AV_RB32(s->bytestream+0)) * scale;
299 1317888 g[j] = av_int2float(AV_RB32(s->bytestream+4)) * scale;
300 1317888 b[j] = av_int2float(AV_RB32(s->bytestream+8)) * scale;
301 1317888 s->bytestream += 12;
302 }
303
304 3744 r += p->linesize[2] / 4;
305 3744 g += p->linesize[0] / 4;
306 3744 b += p->linesize[1] / 4;
307 }
308 }
309 } else {
310 if (avctx->width * avctx->height * 6 > s->bytestream_end - s->bytestream)
311 return AVERROR_INVALIDDATA;
312 scale = 1.f / s->scale;
313 if (s->endian) {
314 float *r, *g, *b;
315
316 r = (float *)p->data[2];
317 g = (float *)p->data[0];
318 b = (float *)p->data[1];
319 for (int i = 0; i < avctx->height; i++) {
320 for (int j = 0; j < avctx->width; j++) {
321 r[j] = av_int2float(half2float(AV_RL16(s->bytestream+0), &s->h2f_tables)) * scale;
322 g[j] = av_int2float(half2float(AV_RL16(s->bytestream+2), &s->h2f_tables)) * scale;
323 b[j] = av_int2float(half2float(AV_RL16(s->bytestream+4), &s->h2f_tables)) * scale;
324 s->bytestream += 6;
325 }
326
327 r += p->linesize[2] / 4;
328 g += p->linesize[0] / 4;
329 b += p->linesize[1] / 4;
330 }
331 } else {
332 float *r, *g, *b;
333
334 r = (float *)p->data[2];
335 g = (float *)p->data[0];
336 b = (float *)p->data[1];
337 for (int i = 0; i < avctx->height; i++) {
338 for (int j = 0; j < avctx->width; j++) {
339 r[j] = av_int2float(half2float(AV_RB16(s->bytestream+0), &s->h2f_tables)) * scale;
340 g[j] = av_int2float(half2float(AV_RB16(s->bytestream+2), &s->h2f_tables)) * scale;
341 b[j] = av_int2float(half2float(AV_RB16(s->bytestream+4), &s->h2f_tables)) * scale;
342 s->bytestream += 6;
343 }
344
345 r += p->linesize[2] / 4;
346 g += p->linesize[0] / 4;
347 b += p->linesize[1] / 4;
348 }
349 }
350 }
351 /* PFM is encoded from bottom to top */
352 26 p->data[0] += (avctx->height - 1) * p->linesize[0];
353 26 p->data[1] += (avctx->height - 1) * p->linesize[1];
354 26 p->data[2] += (avctx->height - 1) * p->linesize[2];
355 26 p->linesize[0] = -p->linesize[0];
356 26 p->linesize[1] = -p->linesize[1];
357 26 p->linesize[2] = -p->linesize[2];
358 26 break;
359 26 case AV_PIX_FMT_GRAYF32:
360
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (!s->half) {
361
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (avctx->width * avctx->height * 4 > s->bytestream_end - s->bytestream)
362 return AVERROR_INVALIDDATA;
363 26 scale = 1.f / s->scale;
364
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 13 times.
26 if (s->endian) {
365 13 float *g = (float *)p->data[0];
366
2/2
✓ Branch 0 taken 3744 times.
✓ Branch 1 taken 13 times.
3757 for (int i = 0; i < avctx->height; i++) {
367
2/2
✓ Branch 0 taken 1317888 times.
✓ Branch 1 taken 3744 times.
1321632 for (int j = 0; j < avctx->width; j++) {
368 1317888 g[j] = av_int2float(AV_RL32(s->bytestream)) * scale;
369 1317888 s->bytestream += 4;
370 }
371 3744 g += p->linesize[0] / 4;
372 }
373 } else {
374 13 float *g = (float *)p->data[0];
375
2/2
✓ Branch 0 taken 3744 times.
✓ Branch 1 taken 13 times.
3757 for (int i = 0; i < avctx->height; i++) {
376
2/2
✓ Branch 0 taken 1317888 times.
✓ Branch 1 taken 3744 times.
1321632 for (int j = 0; j < avctx->width; j++) {
377 1317888 g[j] = av_int2float(AV_RB32(s->bytestream)) * scale;
378 1317888 s->bytestream += 4;
379 }
380 3744 g += p->linesize[0] / 4;
381 }
382 }
383 } else {
384 if (avctx->width * avctx->height * 2 > s->bytestream_end - s->bytestream)
385 return AVERROR_INVALIDDATA;
386 scale = 1.f / s->scale;
387 if (s->endian) {
388 float *g = (float *)p->data[0];
389 for (int i = 0; i < avctx->height; i++) {
390 for (int j = 0; j < avctx->width; j++) {
391 g[j] = av_int2float(half2float(AV_RL16(s->bytestream), &s->h2f_tables)) * scale;
392 s->bytestream += 2;
393 }
394 g += p->linesize[0] / 4;
395 }
396 } else {
397 float *g = (float *)p->data[0];
398 for (int i = 0; i < avctx->height; i++) {
399 for (int j = 0; j < avctx->width; j++) {
400 g[j] = av_int2float(half2float(AV_RB16(s->bytestream), &s->h2f_tables)) * scale;
401 s->bytestream += 2;
402 }
403 g += p->linesize[0] / 4;
404 }
405 }
406 }
407 /* PFM is encoded from bottom to top */
408 26 p->data[0] += (avctx->height - 1) * p->linesize[0];
409 26 p->linesize[0] = -p->linesize[0];
410 26 break;
411 }
412 23057 *got_frame = 1;
413
414 23057 return s->bytestream - s->bytestream_start;
415 }
416
417
418 #if CONFIG_PGM_DECODER
419 const FFCodec ff_pgm_decoder = {
420 .p.name = "pgm",
421 CODEC_LONG_NAME("PGM (Portable GrayMap) image"),
422 .p.type = AVMEDIA_TYPE_VIDEO,
423 .p.id = AV_CODEC_ID_PGM,
424 .p.capabilities = AV_CODEC_CAP_DR1,
425 .priv_data_size = sizeof(PNMContext),
426 .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
427 FF_CODEC_DECODE_CB(pnm_decode_frame),
428 };
429 #endif
430
431 #if CONFIG_PGMYUV_DECODER
432 const FFCodec ff_pgmyuv_decoder = {
433 .p.name = "pgmyuv",
434 CODEC_LONG_NAME("PGMYUV (Portable GrayMap YUV) image"),
435 .p.type = AVMEDIA_TYPE_VIDEO,
436 .p.id = AV_CODEC_ID_PGMYUV,
437 .p.capabilities = AV_CODEC_CAP_DR1,
438 .priv_data_size = sizeof(PNMContext),
439 .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
440 FF_CODEC_DECODE_CB(pnm_decode_frame),
441 };
442 #endif
443
444 #if CONFIG_PPM_DECODER
445 const FFCodec ff_ppm_decoder = {
446 .p.name = "ppm",
447 CODEC_LONG_NAME("PPM (Portable PixelMap) image"),
448 .p.type = AVMEDIA_TYPE_VIDEO,
449 .p.id = AV_CODEC_ID_PPM,
450 .p.capabilities = AV_CODEC_CAP_DR1,
451 .priv_data_size = sizeof(PNMContext),
452 .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
453 FF_CODEC_DECODE_CB(pnm_decode_frame),
454 };
455 #endif
456
457 #if CONFIG_PBM_DECODER
458 const FFCodec ff_pbm_decoder = {
459 .p.name = "pbm",
460 CODEC_LONG_NAME("PBM (Portable BitMap) image"),
461 .p.type = AVMEDIA_TYPE_VIDEO,
462 .p.id = AV_CODEC_ID_PBM,
463 .p.capabilities = AV_CODEC_CAP_DR1,
464 .priv_data_size = sizeof(PNMContext),
465 .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
466 FF_CODEC_DECODE_CB(pnm_decode_frame),
467 };
468 #endif
469
470 #if CONFIG_PAM_DECODER
471 const FFCodec ff_pam_decoder = {
472 .p.name = "pam",
473 CODEC_LONG_NAME("PAM (Portable AnyMap) image"),
474 .p.type = AVMEDIA_TYPE_VIDEO,
475 .p.id = AV_CODEC_ID_PAM,
476 .p.capabilities = AV_CODEC_CAP_DR1,
477 .priv_data_size = sizeof(PNMContext),
478 .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
479 FF_CODEC_DECODE_CB(pnm_decode_frame),
480 };
481 #endif
482
483 #if CONFIG_PFM_DECODER
484 const FFCodec ff_pfm_decoder = {
485 .p.name = "pfm",
486 CODEC_LONG_NAME("PFM (Portable FloatMap) image"),
487 .p.type = AVMEDIA_TYPE_VIDEO,
488 .p.id = AV_CODEC_ID_PFM,
489 .p.capabilities = AV_CODEC_CAP_DR1,
490 .priv_data_size = sizeof(PNMContext),
491 .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
492 FF_CODEC_DECODE_CB(pnm_decode_frame),
493 };
494 #endif
495
496 #if CONFIG_PHM_DECODER
497 static av_cold int phm_dec_init(AVCodecContext *avctx)
498 {
499 PNMContext *s = avctx->priv_data;
500
501 ff_init_half2float_tables(&s->h2f_tables);
502
503 return 0;
504 }
505
506 const FFCodec ff_phm_decoder = {
507 .p.name = "phm",
508 CODEC_LONG_NAME("PHM (Portable HalfFloatMap) image"),
509 .p.type = AVMEDIA_TYPE_VIDEO,
510 .p.id = AV_CODEC_ID_PHM,
511 .p.capabilities = AV_CODEC_CAP_DR1,
512 .priv_data_size = sizeof(PNMContext),
513 .init = phm_dec_init,
514 .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
515 FF_CODEC_DECODE_CB(pnm_decode_frame),
516 };
517 #endif
518