FFmpeg
pnm_parser.c
Go to the documentation of this file.
1 /*
2  * PNM image parser
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 "libavutil/imgutils.h"
24 
25 #include "parser.h" //for ParseContext
26 #include "pnm.h"
27 
28 typedef struct PNMParseContext {
33 
35  const uint8_t **poutbuf, int *poutbuf_size,
36  const uint8_t *buf, int buf_size)
37 {
38  PNMParseContext *pnmpc = s->priv_data;
39  ParseContext *pc = &pnmpc->pc;
40  PNMContext pnmctx;
41  int next = END_NOT_FOUND;
42  int skip = 0;
43 
44  for (; pc->overread > 0; pc->overread--) {
45  pc->buffer[pc->index++]= pc->buffer[pc->overread_index++];
46  }
47 
48  if (pnmpc->remaining_bytes) {
49  int inc = FFMIN(pnmpc->remaining_bytes, buf_size);
50  skip += inc;
51  pnmpc->remaining_bytes -= inc;
52 
53  if (!pnmpc->remaining_bytes)
54  next = skip;
55  goto end;
56  }
57 
58 retry:
59  if (pc->index) {
60  pnmctx.bytestream_start =
61  pnmctx.bytestream = pc->buffer;
62  pnmctx.bytestream_end = pc->buffer + pc->index;
63  } else {
64  pnmctx.bytestream_start =
65  pnmctx.bytestream = (uint8_t *) buf + skip; /* casts avoid warnings */
66  pnmctx.bytestream_end = (uint8_t *) buf + buf_size - skip;
67  }
68  if (ff_pnm_decode_header(avctx, &pnmctx) < 0) {
69  if (pnmctx.bytestream < pnmctx.bytestream_end) {
70  if (pc->index) {
71  pc->index = 0;
72  pnmpc->ascii_scan = 0;
73  } else {
74  unsigned step = FFMAX(1, pnmctx.bytestream - pnmctx.bytestream_start);
75 
76  skip += step;
77  }
78  goto retry;
79  }
80  } else if (pnmctx.type < 4) {
81  uint8_t *bs = pnmctx.bytestream;
82  const uint8_t *end = pnmctx.bytestream_end;
83  uint8_t *sync = bs;
84 
85  if (pc->index) {
86  av_assert0(pnmpc->ascii_scan <= end - bs);
87  bs += pnmpc->ascii_scan;
88  }
89 
90  while (bs < end) {
91  int c;
92  sync = bs;
93  c = *bs++;
94  if (c == '#') {
95  uint8_t *match = memchr(bs, '\n', end-bs);
96  if (match)
97  bs = match + 1;
98  else
99  break;
100  } else if (c == 'P') {
101  next = bs - pnmctx.bytestream_start + skip - 1;
102  pnmpc->ascii_scan = 0;
103  break;
104  }
105  }
106  if (next == END_NOT_FOUND)
107  pnmpc->ascii_scan = sync - pnmctx.bytestream + skip;
108  } else {
109  int ret = av_image_get_buffer_size(avctx->pix_fmt, avctx->width, avctx->height, 1);
110  next = pnmctx.bytestream - pnmctx.bytestream_start + skip;
111  if (ret >= 0 && next + (uint64_t)ret <= INT_MAX)
112  next += ret;
113  }
114  if (next != END_NOT_FOUND && pnmctx.bytestream_start != buf + skip)
115  next -= pc->index;
116  if (next > buf_size) {
117  pnmpc->remaining_bytes = next - buf_size;
118  next = END_NOT_FOUND;
119  }
120 end:
121  if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
122  *poutbuf = NULL;
123  *poutbuf_size = 0;
124  return buf_size;
125  }
126  *poutbuf = buf;
127  *poutbuf_size = buf_size;
128  return next;
129 }
130 
134  .priv_data_size = sizeof(PNMParseContext),
135  .parser_parse = pnm_parse,
136  .parser_close = ff_parse_close,
137 };
ff_pnm_parser
AVCodecParser ff_pnm_parser
Definition: pnm_parser.c:131
AV_CODEC_ID_PBM
@ AV_CODEC_ID_PBM
Definition: avcodec.h:281
ParseContext::overread_index
int overread_index
the index into ParseContext.buffer of the overread bytes
Definition: parser.h:36
PNMParseContext::ascii_scan
int ascii_scan
Definition: pnm_parser.c:31
end
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
step
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about which is also called distortion Distortion can be quantified by almost any quality measurement one chooses the sum of squared differences is used but more complex methods that consider psychovisual effects can be used as well It makes no difference in this discussion First step
Definition: rate_distortion.txt:58
ff_parse_close
void ff_parse_close(AVCodecParserContext *s)
Definition: parser.c:315
AV_CODEC_ID_PPM
@ AV_CODEC_ID_PPM
Definition: avcodec.h:280
AV_CODEC_ID_PGM
@ AV_CODEC_ID_PGM
Definition: avcodec.h:282
PNMContext::bytestream_end
uint8_t * bytestream_end
Definition: pnm.h:30
ParseContext
Definition: parser.h:28
ParseContext::buffer
uint8_t * buffer
Definition: parser.h:29
avassert.h
buf
void * buf
Definition: avisynth_c.h:766
ParseContext::index
int index
Definition: parser.h:30
s
#define s(width, name)
Definition: cbs_vp9.c:257
pnm_parse
static int pnm_parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition: pnm_parser.c:34
PNMContext::bytestream_start
uint8_t * bytestream_start
Definition: pnm.h:29
PNMParseContext::pc
ParseContext pc
Definition: pnm_parser.c:29
ParseContext::overread
int overread
the number of bytes which where irreversibly read from the next frame
Definition: parser.h:35
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
NULL
#define NULL
Definition: coverity.c:32
AVCodecParser::codec_ids
int codec_ids[5]
Definition: avcodec.h:5276
AV_CODEC_ID_PGMYUV
@ AV_CODEC_ID_PGMYUV
Definition: avcodec.h:283
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
pnm.h
AV_CODEC_ID_PAM
@ AV_CODEC_ID_PAM
Definition: avcodec.h:284
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
PNMContext
Definition: pnm.h:27
av_image_get_buffer_size
int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align)
Return the size in bytes of the amount of data required to store an image with the given parameters.
Definition: imgutils.c:431
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
ff_combine_frame
int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size)
Combine the (truncated) bitstream to a complete frame.
Definition: parser.c:234
uint8_t
uint8_t
Definition: audio_convert.c:194
parser.h
AVCodecContext::height
int height
Definition: avcodec.h:1738
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1775
AVCodecParserContext
Definition: avcodec.h:5108
ret
ret
Definition: filter_design.txt:187
PNMContext::bytestream
uint8_t * bytestream
Definition: pnm.h:28
PNMParseContext
Definition: pnm_parser.c:28
PNMContext::type
int type
Definition: pnm.h:32
AVCodecContext
main external API structure.
Definition: avcodec.h:1565
ff_pnm_decode_header
int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext *const s)
Definition: pnm.c:65
END_NOT_FOUND
#define END_NOT_FOUND
Definition: parser.h:40
AVCodecParser
Definition: avcodec.h:5275
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:1738
imgutils.h
PNMParseContext::remaining_bytes
int remaining_bytes
Definition: pnm_parser.c:30