FFmpeg  4.4
pnmdec.c
Go to the documentation of this file.
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 "avcodec.h"
23 #include "internal.h"
24 #include "put_bits.h"
25 #include "pnm.h"
26 
27 static void samplecpy(uint8_t *dst, const uint8_t *src, int n, int maxval)
28 {
29  if (maxval <= 255) {
30  memcpy(dst, src, n);
31  } else {
32  int i;
33  for (i=0; i<n/2; i++) {
34  ((uint16_t *)dst)[i] = AV_RB16(src+2*i);
35  }
36  }
37 }
38 
39 static int pnm_decode_frame(AVCodecContext *avctx, void *data,
40  int *got_frame, AVPacket *avpkt)
41 {
42  const uint8_t *buf = avpkt->data;
43  int buf_size = avpkt->size;
44  PNMContext * const s = avctx->priv_data;
45  AVFrame * const p = data;
46  int i, j, k, n, linesize, h, upgrade = 0, is_mono = 0;
47  unsigned char *ptr;
48  int components, sample_len, ret;
49  float scale;
50 
51  s->bytestream_start =
52  s->bytestream = (uint8_t *)buf;
53  s->bytestream_end = (uint8_t *)buf + buf_size;
54 
55  if ((ret = ff_pnm_decode_header(avctx, s)) < 0)
56  return ret;
57 
58  if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
59  return ret;
61  p->key_frame = 1;
62  avctx->bits_per_raw_sample = av_log2(s->maxval) + 1;
63 
64  switch (avctx->pix_fmt) {
65  default:
66  return AVERROR(EINVAL);
67  case AV_PIX_FMT_RGBA64:
68  n = avctx->width * 8;
69  components=4;
70  sample_len=16;
71  if (s->maxval < 65535)
72  upgrade = 2;
73  goto do_read;
74  case AV_PIX_FMT_RGB48:
75  n = avctx->width * 6;
76  components=3;
77  sample_len=16;
78  if (s->maxval < 65535)
79  upgrade = 2;
80  goto do_read;
81  case AV_PIX_FMT_RGBA:
82  n = avctx->width * 4;
83  components=4;
84  sample_len=8;
85  goto do_read;
86  case AV_PIX_FMT_RGB24:
87  n = avctx->width * 3;
88  components=3;
89  sample_len=8;
90  if (s->maxval < 255)
91  upgrade = 1;
92  goto do_read;
93  case AV_PIX_FMT_GRAY8:
94  n = avctx->width;
95  components=1;
96  sample_len=8;
97  if (s->maxval < 255)
98  upgrade = 1;
99  goto do_read;
100  case AV_PIX_FMT_GRAY8A:
101  n = avctx->width * 2;
102  components=2;
103  sample_len=8;
104  goto do_read;
105  case AV_PIX_FMT_GRAY16:
106  n = avctx->width * 2;
107  components=1;
108  sample_len=16;
109  if (s->maxval < 65535)
110  upgrade = 2;
111  goto do_read;
112  case AV_PIX_FMT_YA16:
113  n = avctx->width * 4;
114  components=2;
115  sample_len=16;
116  if (s->maxval < 65535)
117  upgrade = 2;
118  goto do_read;
121  n = (avctx->width + 7) >> 3;
122  components=1;
123  sample_len=1;
124  is_mono = 1;
125  do_read:
126  ptr = p->data[0];
127  linesize = p->linesize[0];
128  if (n * avctx->height > s->bytestream_end - s->bytestream)
129  return AVERROR_INVALIDDATA;
130  if(s->type < 4 || (is_mono && s->type==7)){
131  for (i=0; i<avctx->height; i++) {
132  PutBitContext pb;
133  init_put_bits(&pb, ptr, linesize);
134  for(j=0; j<avctx->width * components; j++){
135  unsigned int c=0;
136  unsigned v=0;
137  if(s->type < 4)
138  while(s->bytestream < s->bytestream_end && (*s->bytestream < '0' || *s->bytestream > '9' ))
139  s->bytestream++;
140  if(s->bytestream >= s->bytestream_end)
141  return AVERROR_INVALIDDATA;
142  if (is_mono) {
143  /* read a single digit */
144  v = (*s->bytestream++)&1;
145  } else {
146  /* read a sequence of digits */
147  for (k = 0; k < 6 && c <= 9; k += 1) {
148  v = 10*v + c;
149  c = (*s->bytestream++) - '0';
150  }
151  if (v > s->maxval) {
152  av_log(avctx, AV_LOG_ERROR, "value %d larger than maxval %d\n", v, s->maxval);
153  return AVERROR_INVALIDDATA;
154  }
155  }
156  if (sample_len == 16) {
157  ((uint16_t*)ptr)[j] = (((1<<sample_len)-1)*v + (s->maxval>>1))/s->maxval;
158  } else
159  put_bits(&pb, sample_len, (((1<<sample_len)-1)*v + (s->maxval>>1))/s->maxval);
160  }
161  if (sample_len != 16)
162  flush_put_bits(&pb);
163  ptr+= linesize;
164  }
165  }else{
166  for (i = 0; i < avctx->height; i++) {
167  if (!upgrade)
168  samplecpy(ptr, s->bytestream, n, s->maxval);
169  else if (upgrade == 1) {
170  unsigned int j, f = (255 * 128 + s->maxval / 2) / s->maxval;
171  for (j = 0; j < n; j++)
172  ptr[j] = (s->bytestream[j] * f + 64) >> 7;
173  } else if (upgrade == 2) {
174  unsigned int j, v, f = (65535 * 32768 + s->maxval / 2) / s->maxval;
175  for (j = 0; j < n / 2; j++) {
176  v = AV_RB16(s->bytestream + 2*j);
177  ((uint16_t *)ptr)[j] = (v * f + 16384) >> 15;
178  }
179  }
180  s->bytestream += n;
181  ptr += linesize;
182  }
183  }
184  break;
185  case AV_PIX_FMT_YUV420P:
186  case AV_PIX_FMT_YUV420P9:
188  {
189  unsigned char *ptr1, *ptr2;
190 
191  n = avctx->width;
192  ptr = p->data[0];
193  linesize = p->linesize[0];
194  if (s->maxval >= 256)
195  n *= 2;
196  if (n * avctx->height * 3 / 2 > s->bytestream_end - s->bytestream)
197  return AVERROR_INVALIDDATA;
198  for (i = 0; i < avctx->height; i++) {
199  samplecpy(ptr, s->bytestream, n, s->maxval);
200  s->bytestream += n;
201  ptr += linesize;
202  }
203  ptr1 = p->data[1];
204  ptr2 = p->data[2];
205  n >>= 1;
206  h = avctx->height >> 1;
207  for (i = 0; i < h; i++) {
208  samplecpy(ptr1, s->bytestream, n, s->maxval);
209  s->bytestream += n;
210  samplecpy(ptr2, s->bytestream, n, s->maxval);
211  s->bytestream += n;
212  ptr1 += p->linesize[1];
213  ptr2 += p->linesize[2];
214  }
215  }
216  break;
218  {
219  uint16_t *ptr1, *ptr2;
220  const int f = (65535 * 32768 + s->maxval / 2) / s->maxval;
221  unsigned int j, v;
222 
223  n = avctx->width * 2;
224  ptr = p->data[0];
225  linesize = p->linesize[0];
226  if (n * avctx->height * 3 / 2 > s->bytestream_end - s->bytestream)
227  return AVERROR_INVALIDDATA;
228  for (i = 0; i < avctx->height; i++) {
229  for (j = 0; j < n / 2; j++) {
230  v = AV_RB16(s->bytestream + 2*j);
231  ((uint16_t *)ptr)[j] = (v * f + 16384) >> 15;
232  }
233  s->bytestream += n;
234  ptr += linesize;
235  }
236  ptr1 = (uint16_t*)p->data[1];
237  ptr2 = (uint16_t*)p->data[2];
238  n >>= 1;
239  h = avctx->height >> 1;
240  for (i = 0; i < h; i++) {
241  for (j = 0; j < n / 2; j++) {
242  v = AV_RB16(s->bytestream + 2*j);
243  ptr1[j] = (v * f + 16384) >> 15;
244  }
245  s->bytestream += n;
246 
247  for (j = 0; j < n / 2; j++) {
248  v = AV_RB16(s->bytestream + 2*j);
249  ptr2[j] = (v * f + 16384) >> 15;
250  }
251  s->bytestream += n;
252 
253  ptr1 += p->linesize[1] / 2;
254  ptr2 += p->linesize[2] / 2;
255  }
256  }
257  break;
258  case AV_PIX_FMT_GBRPF32:
259  if (avctx->width * avctx->height * 12 > s->bytestream_end - s->bytestream)
260  return AVERROR_INVALIDDATA;
261  scale = 1.f / s->scale;
262  if (s->endian) {
263  float *r, *g, *b;
264 
265  r = (float *)p->data[2];
266  g = (float *)p->data[0];
267  b = (float *)p->data[1];
268  for (int i = 0; i < avctx->height; i++) {
269  for (int j = 0; j < avctx->width; j++) {
270  r[j] = av_int2float(AV_RL32(s->bytestream+0)) * scale;
271  g[j] = av_int2float(AV_RL32(s->bytestream+4)) * scale;
272  b[j] = av_int2float(AV_RL32(s->bytestream+8)) * scale;
273  s->bytestream += 12;
274  }
275 
276  r += p->linesize[2] / 4;
277  g += p->linesize[0] / 4;
278  b += p->linesize[1] / 4;
279  }
280  } else {
281  float *r, *g, *b;
282 
283  r = (float *)p->data[2];
284  g = (float *)p->data[0];
285  b = (float *)p->data[1];
286  for (int i = 0; i < avctx->height; i++) {
287  for (int j = 0; j < avctx->width; j++) {
288  r[j] = av_int2float(AV_RB32(s->bytestream+0)) * scale;
289  g[j] = av_int2float(AV_RB32(s->bytestream+4)) * scale;
290  b[j] = av_int2float(AV_RB32(s->bytestream+8)) * scale;
291  s->bytestream += 12;
292  }
293 
294  r += p->linesize[2] / 4;
295  g += p->linesize[0] / 4;
296  b += p->linesize[1] / 4;
297  }
298  }
299  break;
300  case AV_PIX_FMT_GRAYF32:
301  if (avctx->width * avctx->height * 4 > s->bytestream_end - s->bytestream)
302  return AVERROR_INVALIDDATA;
303  scale = 1.f / s->scale;
304  if (s->endian) {
305  float *g = (float *)p->data[0];
306  for (int i = 0; i < avctx->height; i++) {
307  for (int j = 0; j < avctx->width; j++) {
308  g[j] = av_int2float(AV_RL32(s->bytestream)) * scale;
309  s->bytestream += 4;
310  }
311  g += p->linesize[0] / 4;
312  }
313  } else {
314  float *g = (float *)p->data[0];
315  for (int i = 0; i < avctx->height; i++) {
316  for (int j = 0; j < avctx->width; j++) {
317  g[j] = av_int2float(AV_RB32(s->bytestream)) * scale;
318  s->bytestream += 4;
319  }
320  g += p->linesize[0] / 4;
321  }
322  }
323  break;
324  }
325  *got_frame = 1;
326 
327  return s->bytestream - s->bytestream_start;
328 }
329 
330 
331 #if CONFIG_PGM_DECODER
333  .name = "pgm",
334  .long_name = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"),
335  .type = AVMEDIA_TYPE_VIDEO,
336  .id = AV_CODEC_ID_PGM,
337  .priv_data_size = sizeof(PNMContext),
339  .capabilities = AV_CODEC_CAP_DR1,
340 };
341 #endif
342 
343 #if CONFIG_PGMYUV_DECODER
345  .name = "pgmyuv",
346  .long_name = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"),
347  .type = AVMEDIA_TYPE_VIDEO,
348  .id = AV_CODEC_ID_PGMYUV,
349  .priv_data_size = sizeof(PNMContext),
351  .capabilities = AV_CODEC_CAP_DR1,
352 };
353 #endif
354 
355 #if CONFIG_PPM_DECODER
357  .name = "ppm",
358  .long_name = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"),
359  .type = AVMEDIA_TYPE_VIDEO,
360  .id = AV_CODEC_ID_PPM,
361  .priv_data_size = sizeof(PNMContext),
363  .capabilities = AV_CODEC_CAP_DR1,
364 };
365 #endif
366 
367 #if CONFIG_PBM_DECODER
369  .name = "pbm",
370  .long_name = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"),
371  .type = AVMEDIA_TYPE_VIDEO,
372  .id = AV_CODEC_ID_PBM,
373  .priv_data_size = sizeof(PNMContext),
375  .capabilities = AV_CODEC_CAP_DR1,
376 };
377 #endif
378 
379 #if CONFIG_PAM_DECODER
381  .name = "pam",
382  .long_name = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"),
383  .type = AVMEDIA_TYPE_VIDEO,
384  .id = AV_CODEC_ID_PAM,
385  .priv_data_size = sizeof(PNMContext),
387  .capabilities = AV_CODEC_CAP_DR1,
388 };
389 #endif
390 
391 #if CONFIG_PFM_DECODER
393  .name = "pfm",
394  .long_name = NULL_IF_CONFIG_SMALL("PFM (Portable FloatMap) image"),
395  .type = AVMEDIA_TYPE_VIDEO,
396  .id = AV_CODEC_ID_PFM,
397  .priv_data_size = sizeof(PNMContext),
399  .capabilities = AV_CODEC_CAP_DR1,
400 };
401 #endif
AVCodec ff_pam_decoder
AVCodec ff_pgm_decoder
AVCodec ff_ppm_decoder
AVCodec ff_pfm_decoder
AVCodec ff_pbm_decoder
AVCodec ff_pgmyuv_decoder
uint8_t
Libavcodec external API header.
#define AV_RB32
Definition: intreadwrite.h:130
#define AV_RB16
Definition: intreadwrite.h:53
#define AV_RL32
Definition: intreadwrite.h:146
#define s(width, name)
Definition: cbs_vp9.c:257
#define f(width, name)
Definition: cbs_vp9.c:255
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1893
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
@ AV_CODEC_ID_PGM
Definition: codec_id.h:113
@ AV_CODEC_ID_PAM
Definition: codec_id.h:115
@ AV_CODEC_ID_PBM
Definition: codec_id.h:112
@ AV_CODEC_ID_PGMYUV
Definition: codec_id.h:114
@ AV_CODEC_ID_PPM
Definition: codec_id.h:111
@ AV_CODEC_ID_PFM
Definition: codec_id.h:302
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
#define AVERROR(e)
Definition: error.h:43
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
for(j=16;j >0;--j)
int i
Definition: input.c:407
static av_always_inline float av_int2float(uint32_t i)
Reinterpret a 32-bit integer as a float.
Definition: intfloat.h:40
#define av_log2
Definition: intmath.h:83
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition: j2kenc.c:218
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
const char data[16]
Definition: mxf.c:142
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:410
#define AV_PIX_FMT_GBRPF32
Definition: pixfmt.h:428
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:399
#define AV_PIX_FMT_YA16
Definition: pixfmt.h:384
#define AV_PIX_FMT_RGBA64
Definition: pixfmt.h:389
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:396
#define AV_PIX_FMT_RGB48
Definition: pixfmt.h:385
#define AV_PIX_FMT_GRAYF32
Definition: pixfmt.h:431
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
@ AV_PIX_FMT_MONOBLACK
Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb.
Definition: pixfmt.h:76
@ AV_PIX_FMT_GRAY8A
alias for AV_PIX_FMT_YA8
Definition: pixfmt.h:146
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:93
@ AV_PIX_FMT_MONOWHITE
Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb.
Definition: pixfmt.h:75
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:383
int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext *const s)
Definition: pnm.c:65
static int pnm_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: pnmdec.c:39
static void samplecpy(uint8_t *dst, const uint8_t *src, int n, int maxval)
Definition: pnmdec.c:27
bitstream writer API
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition: put_bits.h:57
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition: put_bits.h:110
main external API structure.
Definition: avcodec.h:536
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:746
int width
picture width / height.
Definition: avcodec.h:709
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:1747
void * priv_data
Definition: avcodec.h:563
AVCodec.
Definition: codec.h:197
const char * name
Name of the codec implementation.
Definition: codec.h:204
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:332
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:396
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:349
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:401
This structure stores compressed data.
Definition: packet.h:346
int size
Definition: packet.h:370
uint8_t * data
Definition: packet.h:369
Definition: pnm.h:27
#define av_log(a,...)
#define src
Definition: vp8dsp.c:255
const char * b
Definition: vf_curves.c:118
const char * g
Definition: vf_curves.c:117
const char * r
Definition: vf_curves.c:116
if(ret< 0)
Definition: vf_mcdeint.c:282
static double c[64]