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 "parser_internal.h"
27 #include "pnm.h"
28 
29 typedef struct PNMParseContext {
34 
36  const uint8_t **poutbuf, int *poutbuf_size,
37  const uint8_t *buf, int buf_size)
38 {
39  PNMParseContext *pnmpc = s->priv_data;
40  ParseContext *pc = &pnmpc->pc;
41  PNMContext pnmctx;
42  int next = END_NOT_FOUND;
43  int skip = 0;
44 
45  if (pc->overread > 0) {
46  memmove(pc->buffer + pc->index, pc->buffer + pc->overread_index, pc->overread);
47  pc->index += pc->overread;
48  pc->overread_index += pc->overread;
49  pc->overread = 0;
50  }
51 
52  if (pnmpc->remaining_bytes) {
53  int inc = FFMIN(pnmpc->remaining_bytes, buf_size);
54  skip += inc;
55  pnmpc->remaining_bytes -= inc;
56 
57  if (!pnmpc->remaining_bytes)
58  next = skip;
59  goto end;
60  }
61 
62 retry:
63  if (pc->index) {
64  pnmctx.bytestream_start =
65  pnmctx.bytestream = pc->buffer;
66  pnmctx.bytestream_end = pc->buffer + pc->index;
67  } else {
68  pnmctx.bytestream_start =
69  pnmctx.bytestream = buf + skip;
70  pnmctx.bytestream_end = buf + buf_size - skip;
71  }
72  if (ff_pnm_decode_header(avctx, &pnmctx) < 0) {
73  if (pnmctx.bytestream < pnmctx.bytestream_end) {
74  if (pc->index) {
75  pc->index = 0;
76  pnmpc->ascii_scan = 0;
77  } else {
78  unsigned step = FFMAX(1, pnmctx.bytestream - pnmctx.bytestream_start);
79 
80  skip += step;
81  }
82  goto retry;
83  }
84  } else if (pnmctx.type < 4) {
85  const uint8_t *bs = pnmctx.bytestream;
86  const uint8_t *end = pnmctx.bytestream_end;
87  const uint8_t *sync = bs;
88 
89  if (pc->index) {
90  av_assert0(pnmpc->ascii_scan <= end - bs);
91  bs += pnmpc->ascii_scan;
92  }
93 
94  while (bs < end) {
95  int c;
96  sync = bs;
97  c = *bs++;
98  if (c == '#') {
99  uint8_t *match = memchr(bs, '\n', end-bs);
100  if (match)
101  bs = match + 1;
102  else
103  break;
104  } else if (c == 'P') {
105  next = bs - pnmctx.bytestream_start + skip - 1;
106  pnmpc->ascii_scan = 0;
107  break;
108  }
109  }
110  if (next == END_NOT_FOUND)
111  pnmpc->ascii_scan = sync - pnmctx.bytestream + skip;
112  } else {
113  int ret = av_image_get_buffer_size(avctx->pix_fmt, avctx->width, avctx->height, 1);
114  next = pnmctx.bytestream - pnmctx.bytestream_start + skip;
115  if (ret > 0 && pnmctx.half)
116  ret >>= 1;
117  if (ret >= 0 && next + (uint64_t)ret <= INT_MAX)
118  next += ret;
119  }
120  if (next != END_NOT_FOUND && pnmctx.bytestream_start != buf + skip)
121  next -= pc->index;
122  if (next > buf_size) {
123  pnmpc->remaining_bytes = next - buf_size;
124  next = END_NOT_FOUND;
125  }
126 end:
127  if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
128  *poutbuf = NULL;
129  *poutbuf_size = 0;
130  return buf_size;
131  }
132  *poutbuf = buf;
133  *poutbuf_size = buf_size;
134  return next;
135 }
136 
141  .priv_data_size = sizeof(PNMParseContext),
142  .parse = pnm_parse,
144 };
AV_CODEC_ID_PBM
@ AV_CODEC_ID_PBM
Definition: codec_id.h:115
ff_parse_close
av_cold void ff_parse_close(AVCodecParserContext *s)
Definition: parser.c:298
AV_CODEC_ID_PFM
@ AV_CODEC_ID_PFM
Definition: codec_id.h:307
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:32
parser_internal.h
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
AV_CODEC_ID_PPM
@ AV_CODEC_ID_PPM
Definition: codec_id.h:114
AV_CODEC_ID_PGM
@ AV_CODEC_ID_PGM
Definition: codec_id.h:116
PNMContext::bytestream_end
const uint8_t * bytestream_end
Definition: pnm.h:31
ff_pnm_parser
const FFCodecParser ff_pnm_parser
Definition: pnm_parser.c:137
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AV_CODEC_ID_PHM
@ AV_CODEC_ID_PHM
Definition: codec_id.h:319
close
static av_cold void close(AVCodecParserContext *s)
Definition: apv_parser.c:136
ParseContext
Definition: parser.h:28
PNMContext::bytestream_start
const uint8_t * bytestream_start
Definition: pnm.h:30
ParseContext::buffer
uint8_t * buffer
Definition: parser.h:29
avassert.h
ParseContext::index
int index
Definition: parser.h:30
s
#define s(width, name)
Definition: cbs_vp9.c:198
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:35
PNMParseContext::pc
ParseContext pc
Definition: pnm_parser.c:30
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:41
NULL
#define NULL
Definition: coverity.c:32
AV_CODEC_ID_PGMYUV
@ AV_CODEC_ID_PGMYUV
Definition: codec_id.h:117
parse
static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition: apv_parser.c:46
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
inc
static int inc(int num, int period)
Definition: perlin.c:34
pnm.h
AV_CODEC_ID_PAM
@ AV_CODEC_ID_PAM
Definition: codec_id.h:118
PNMContext
Definition: pnm.h:28
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:466
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:211
FFCodecParser
Definition: parser_internal.h:29
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
parser.h
AVCodecContext::height
int height
Definition: avcodec.h:592
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:631
PARSER_CODEC_LIST
#define PARSER_CODEC_LIST(...)
Definition: parser_internal.h:76
AVCodecParserContext
Definition: avcodec.h:2575
ret
ret
Definition: filter_design.txt:187
PNMParseContext
Definition: pnm_parser.c:29
PNMContext::type
int type
Definition: pnm.h:33
AVCodecContext
main external API structure.
Definition: avcodec.h:431
PNMContext::bytestream
const uint8_t * bytestream
Definition: pnm.h:29
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
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:592
imgutils.h
PNMContext::half
int half
Definition: pnm.h:35
skip
static void BS_FUNC() skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
Definition: bitstream_template.h:383
PNMParseContext::remaining_bytes
int remaining_bytes
Definition: pnm_parser.c:31