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  if (pc->overread > 0) {
45  memmove(pc->buffer + pc->index, pc->buffer + pc->overread_index, pc->overread);
46  pc->index += pc->overread;
47  pc->overread_index += pc->overread;
48  pc->overread = 0;
49  }
50 
51  if (pnmpc->remaining_bytes) {
52  int inc = FFMIN(pnmpc->remaining_bytes, buf_size);
53  skip += inc;
54  pnmpc->remaining_bytes -= inc;
55 
56  if (!pnmpc->remaining_bytes)
57  next = skip;
58  goto end;
59  }
60 
61 retry:
62  if (pc->index) {
63  pnmctx.bytestream_start =
64  pnmctx.bytestream = pc->buffer;
65  pnmctx.bytestream_end = pc->buffer + pc->index;
66  } else {
67  pnmctx.bytestream_start =
68  pnmctx.bytestream = (uint8_t *) buf + skip; /* casts avoid warnings */
69  pnmctx.bytestream_end = (uint8_t *) buf + buf_size - skip;
70  }
71  if (ff_pnm_decode_header(avctx, &pnmctx) < 0) {
72  if (pnmctx.bytestream < pnmctx.bytestream_end) {
73  if (pc->index) {
74  pc->index = 0;
75  pnmpc->ascii_scan = 0;
76  } else {
77  unsigned step = FFMAX(1, pnmctx.bytestream - pnmctx.bytestream_start);
78 
79  skip += step;
80  }
81  goto retry;
82  }
83  } else if (pnmctx.type < 4) {
84  uint8_t *bs = pnmctx.bytestream;
85  const uint8_t *end = pnmctx.bytestream_end;
86  uint8_t *sync = bs;
87 
88  if (pc->index) {
89  av_assert0(pnmpc->ascii_scan <= end - bs);
90  bs += pnmpc->ascii_scan;
91  }
92 
93  while (bs < end) {
94  int c;
95  sync = bs;
96  c = *bs++;
97  if (c == '#') {
98  uint8_t *match = memchr(bs, '\n', end-bs);
99  if (match)
100  bs = match + 1;
101  else
102  break;
103  } else if (c == 'P') {
104  next = bs - pnmctx.bytestream_start + skip - 1;
105  pnmpc->ascii_scan = 0;
106  break;
107  }
108  }
109  if (next == END_NOT_FOUND)
110  pnmpc->ascii_scan = sync - pnmctx.bytestream + skip;
111  } else {
112  next = pnmctx.bytestream - pnmctx.bytestream_start + skip
113  + av_image_get_buffer_size(avctx->pix_fmt, avctx->width, avctx->height, 1);
114  }
115  if (next != END_NOT_FOUND && pnmctx.bytestream_start != buf + skip)
116  next -= pc->index;
117  if (next > buf_size) {
118  pnmpc->remaining_bytes = next - buf_size;
119  next = END_NOT_FOUND;
120  }
121 end:
122  if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
123  *poutbuf = NULL;
124  *poutbuf_size = 0;
125  return buf_size;
126  }
127  *poutbuf = buf;
128  *poutbuf_size = buf_size;
129  return next;
130 }
131 
135  .priv_data_size = sizeof(PNMParseContext),
136  .parser_parse = pnm_parse,
137  .parser_close = ff_parse_close,
138 };
#define NULL
Definition: coverity.c:32
misc image utilities
int codec_ids[5]
Definition: avcodec.h:5287
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1778
uint8_t * bytestream
Definition: pnm.h:28
AVCodecParser ff_pnm_parser
Definition: pnm_parser.c:132
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
uint8_t
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
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
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
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
simple assert() macros that are a bit more flexible than ISO C assert().
int overread_index
the index into ParseContext.buffer of the overread bytes
Definition: parser.h:36
uint8_t * bytestream_end
Definition: pnm.h:30
#define FFMAX(a, b)
Definition: common.h:94
void ff_parse_close(AVCodecParserContext *s)
Definition: parser.c:319
int overread
the number of bytes which where irreversibly read from the next frame
Definition: parser.h:35
#define FFMIN(a, b)
Definition: common.h:96
int width
picture width / height.
Definition: avcodec.h:1741
#define s(width, name)
Definition: cbs_vp9.c:257
Definition: pnm.h:27
uint8_t * buffer
Definition: parser.h:29
int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext *const s)
Definition: pnm.c:64
main external API structure.
Definition: avcodec.h:1568
void * buf
Definition: avisynth_c.h:766
#define END_NOT_FOUND
Definition: parser.h:40
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
ParseContext pc
Definition: pnm_parser.c:29
int index
Definition: parser.h:30
uint8_t * bytestream_start
Definition: pnm.h:29
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
int type
Definition: pnm.h:32