annotate pnm.c @ 12530:63edd10ad4bc libavcodec tip

Try to fix crashes introduced by r25218 r25218 made assumptions about the existence of past reference frames that weren't necessarily true.
author darkshikari
date Tue, 28 Sep 2010 09:06:22 +0000
parents ffb3668ff7af
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
1 /*
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
2 * PNM image format
8629
04423b2f6e0b cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents: 7865
diff changeset
3 * Copyright (c) 2002, 2003 Fabrice Bellard
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
4 *
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
5 * This file is part of FFmpeg.
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
6 *
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
11 *
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
15 * Lesser General Public License for more details.
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
16 *
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
20 */
10459
a6bb56636f90 whitespace cosmetics: K&R coding style, prettyprinting
diego
parents: 9145
diff changeset
21
12372
914f484bb476 Remove use of the deprecated function avcodec_check_dimensions(), use
stefano
parents: 10612
diff changeset
22 #include "libavcore/imgutils.h"
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
23 #include "avcodec.h"
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
24 #include "pnm.h"
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
25
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
26 static inline int pnm_space(int c)
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
27 {
6750
c93570aeb3eb Remove unnecessary parentheses from return calls.
diego
parents: 4985
diff changeset
28 return c == ' ' || c == '\n' || c == '\r' || c == '\t';
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
29 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
30
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
31 static void pnm_get(PNMContext *sc, char *str, int buf_size)
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
32 {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
33 char *s;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
34 int c;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
35
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
36 /* skip spaces and comments */
10459
a6bb56636f90 whitespace cosmetics: K&R coding style, prettyprinting
diego
parents: 9145
diff changeset
37 for (;;) {
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
38 c = *sc->bytestream++;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
39 if (c == '#') {
10459
a6bb56636f90 whitespace cosmetics: K&R coding style, prettyprinting
diego
parents: 9145
diff changeset
40 do {
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
41 c = *sc->bytestream++;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
42 } while (c != '\n' && sc->bytestream < sc->bytestream_end);
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
43 } else if (!pnm_space(c)) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
44 break;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
45 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
46 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
47
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
48 s = str;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
49 while (sc->bytestream < sc->bytestream_end && !pnm_space(c)) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
50 if ((s - str) < buf_size - 1)
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
51 *s++ = c;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
52 c = *sc->bytestream++;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
53 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
54 *s = '\0';
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
55 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
56
10459
a6bb56636f90 whitespace cosmetics: K&R coding style, prettyprinting
diego
parents: 9145
diff changeset
57 int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s)
a6bb56636f90 whitespace cosmetics: K&R coding style, prettyprinting
diego
parents: 9145
diff changeset
58 {
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
59 char buf1[32], tuple_type[32];
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
60 int h, w, depth, maxval;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
61
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
62 pnm_get(s, buf1, sizeof(buf1));
10612
d6860312274c Support ASCII pnms.
michael
parents: 10460
diff changeset
63 s->type= buf1[1]-'0';
d6860312274c Support ASCII pnms.
michael
parents: 10460
diff changeset
64 if(buf1[0] != 'P')
d6860312274c Support ASCII pnms.
michael
parents: 10460
diff changeset
65 return -1;
d6860312274c Support ASCII pnms.
michael
parents: 10460
diff changeset
66
d6860312274c Support ASCII pnms.
michael
parents: 10460
diff changeset
67 if (s->type==1 || s->type==4) {
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
68 avctx->pix_fmt = PIX_FMT_MONOWHITE;
10612
d6860312274c Support ASCII pnms.
michael
parents: 10460
diff changeset
69 } else if (s->type==2 || s->type==5) {
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
70 if (avctx->codec_id == CODEC_ID_PGMYUV)
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
71 avctx->pix_fmt = PIX_FMT_YUV420P;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
72 else
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
73 avctx->pix_fmt = PIX_FMT_GRAY8;
10612
d6860312274c Support ASCII pnms.
michael
parents: 10460
diff changeset
74 } else if (s->type==3 || s->type==6) {
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
75 avctx->pix_fmt = PIX_FMT_RGB24;
10612
d6860312274c Support ASCII pnms.
michael
parents: 10460
diff changeset
76 } else if (s->type==7) {
10459
a6bb56636f90 whitespace cosmetics: K&R coding style, prettyprinting
diego
parents: 9145
diff changeset
77 w = -1;
a6bb56636f90 whitespace cosmetics: K&R coding style, prettyprinting
diego
parents: 9145
diff changeset
78 h = -1;
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
79 maxval = -1;
10459
a6bb56636f90 whitespace cosmetics: K&R coding style, prettyprinting
diego
parents: 9145
diff changeset
80 depth = -1;
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
81 tuple_type[0] = '\0';
10459
a6bb56636f90 whitespace cosmetics: K&R coding style, prettyprinting
diego
parents: 9145
diff changeset
82 for (;;) {
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
83 pnm_get(s, buf1, sizeof(buf1));
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
84 if (!strcmp(buf1, "WIDTH")) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
85 pnm_get(s, buf1, sizeof(buf1));
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
86 w = strtol(buf1, NULL, 10);
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
87 } else if (!strcmp(buf1, "HEIGHT")) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
88 pnm_get(s, buf1, sizeof(buf1));
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
89 h = strtol(buf1, NULL, 10);
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
90 } else if (!strcmp(buf1, "DEPTH")) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
91 pnm_get(s, buf1, sizeof(buf1));
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
92 depth = strtol(buf1, NULL, 10);
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
93 } else if (!strcmp(buf1, "MAXVAL")) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
94 pnm_get(s, buf1, sizeof(buf1));
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
95 maxval = strtol(buf1, NULL, 10);
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
96 } else if (!strcmp(buf1, "TUPLETYPE")) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
97 pnm_get(s, tuple_type, sizeof(tuple_type));
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
98 } else if (!strcmp(buf1, "ENDHDR")) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
99 break;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
100 } else {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
101 return -1;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
102 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
103 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
104 /* check that all tags are present */
12462
ffb3668ff7af Use new imgutils.h API names, fix deprecation warnings.
stefano
parents: 12372
diff changeset
105 if (w <= 0 || h <= 0 || maxval <= 0 || depth <= 0 || tuple_type[0] == '\0' || av_image_check_size(w, h, 0, avctx))
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
106 return -1;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
107
10459
a6bb56636f90 whitespace cosmetics: K&R coding style, prettyprinting
diego
parents: 9145
diff changeset
108 avctx->width = w;
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
109 avctx->height = h;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
110 if (depth == 1) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
111 if (maxval == 1)
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
112 avctx->pix_fmt = PIX_FMT_MONOWHITE;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
113 else
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
114 avctx->pix_fmt = PIX_FMT_GRAY8;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
115 } else if (depth == 3) {
7859
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
116 if (maxval < 256) {
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
117 avctx->pix_fmt = PIX_FMT_RGB24;
7859
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
118 } else {
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
119 av_log(avctx, AV_LOG_ERROR, "16-bit components are only supported for grayscale\n");
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
120 avctx->pix_fmt = PIX_FMT_NONE;
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
121 return -1;
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
122 }
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
123 } else if (depth == 4) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
124 avctx->pix_fmt = PIX_FMT_RGB32;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
125 } else {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
126 return -1;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
127 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
128 return 0;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
129 } else {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
130 return -1;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
131 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
132 pnm_get(s, buf1, sizeof(buf1));
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
133 avctx->width = atoi(buf1);
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
134 if (avctx->width <= 0)
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
135 return -1;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
136 pnm_get(s, buf1, sizeof(buf1));
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
137 avctx->height = atoi(buf1);
12462
ffb3668ff7af Use new imgutils.h API names, fix deprecation warnings.
stefano
parents: 12372
diff changeset
138 if(av_image_check_size(avctx->width, avctx->height, 0, avctx))
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
139 return -1;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
140 if (avctx->pix_fmt != PIX_FMT_MONOWHITE) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
141 pnm_get(s, buf1, sizeof(buf1));
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
142 s->maxval = atoi(buf1);
7859
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
143 if (s->maxval >= 256) {
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
144 if (avctx->pix_fmt == PIX_FMT_GRAY8) {
7865
c7420b070961 cosmetics: fix indentation after r15321
jbr
parents: 7859
diff changeset
145 avctx->pix_fmt = PIX_FMT_GRAY16BE;
c7420b070961 cosmetics: fix indentation after r15321
jbr
parents: 7859
diff changeset
146 if (s->maxval != 65535)
c7420b070961 cosmetics: fix indentation after r15321
jbr
parents: 7859
diff changeset
147 avctx->pix_fmt = PIX_FMT_GRAY16;
9145
de31b10455cc pnm: Add missing 'else'. Fixes decoding for 16-bit pgm.
jbr
parents: 9002
diff changeset
148 } else if (avctx->pix_fmt == PIX_FMT_RGB24) {
9002
eb98d61af310 Support 48-bit RGB PPM image.
pross
parents: 8629
diff changeset
149 if (s->maxval > 255)
eb98d61af310 Support 48-bit RGB PPM image.
pross
parents: 8629
diff changeset
150 avctx->pix_fmt = PIX_FMT_RGB48BE;
7859
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
151 } else {
9002
eb98d61af310 Support 48-bit RGB PPM image.
pross
parents: 8629
diff changeset
152 av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format\n");
7859
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
153 avctx->pix_fmt = PIX_FMT_NONE;
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
154 return -1;
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
155 }
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
156 }
10612
d6860312274c Support ASCII pnms.
michael
parents: 10460
diff changeset
157 }else
d6860312274c Support ASCII pnms.
michael
parents: 10460
diff changeset
158 s->maxval=1;
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
159 /* more check if YUV420 */
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
160 if (avctx->pix_fmt == PIX_FMT_YUV420P) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
161 if ((avctx->width & 1) != 0)
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
162 return -1;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
163 h = (avctx->height * 2);
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
164 if ((h % 3) != 0)
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
165 return -1;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
166 h /= 3;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
167 avctx->height = h;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
168 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
169 return 0;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
170 }
10460
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
171
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
172 av_cold int ff_pnm_end(AVCodecContext *avctx)
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
173 {
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
174 PNMContext *s = avctx->priv_data;
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
175
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
176 if (s->picture.data[0])
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
177 avctx->release_buffer(avctx, &s->picture);
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
178
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
179 return 0;
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
180 }
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
181
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
182 av_cold int ff_pnm_init(AVCodecContext *avctx)
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
183 {
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
184 PNMContext *s = avctx->priv_data;
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
185
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
186 avcodec_get_frame_defaults((AVFrame*)&s->picture);
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
187 avctx->coded_frame = (AVFrame*)&s->picture;
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
188
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
189 return 0;
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
190 }