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  while (c != '\n' && bs < end)
96  c = *bs++;
97  } else if (c == 'P') {
98  next = bs - pnmctx.bytestream_start + skip - 1;
99  pnmpc->ascii_scan = 0;
100  break;
101  }
102  }
103  if (next == END_NOT_FOUND)
104  pnmpc->ascii_scan = sync - pnmctx.bytestream + skip;
105  } else {
106  next = pnmctx.bytestream - pnmctx.bytestream_start + skip
107  + av_image_get_buffer_size(avctx->pix_fmt, avctx->width, avctx->height, 1);
108  }
109  if (next != END_NOT_FOUND && pnmctx.bytestream_start != buf + skip)
110  next -= pc->index;
111  if (next > buf_size) {
112  pnmpc->remaining_bytes = next - buf_size;
113  next = END_NOT_FOUND;
114  }
115 end:
116  if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
117  *poutbuf = NULL;
118  *poutbuf_size = 0;
119  return buf_size;
120  }
121  *poutbuf = buf;
122  *poutbuf_size = buf_size;
123  return next;
124 }
125 
129  .priv_data_size = sizeof(PNMParseContext),
130  .parser_parse = pnm_parse,
131  .parser_close = ff_parse_close,
132 };
#define NULL
Definition: coverity.c:32
misc image utilities
int codec_ids[5]
Definition: avcodec.h:5276
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1775
uint8_t * bytestream
Definition: pnm.h:28
AVCodecParser ff_pnm_parser
Definition: pnm_parser.c:126
#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:315
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:1738
#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:65
main external API structure.
Definition: avcodec.h:1565
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