Mercurial > libavcodec.hg
annotate pnm.c @ 11389:7b9896e85410 libavcodec
Increase FF_INPUT_BUFFER_PADDING_SIZE to 64.
The purpose of this is to give decoders a reasonable amount of buffer to work
with before needing to check for overreads.
author | alexc |
---|---|
date | Sun, 07 Mar 2010 21:16:44 +0000 |
parents | d6860312274c |
children | 914f484bb476 |
rev | line source |
---|---|
4978 | 1 /* |
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 | 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 */ | |
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
21 |
4978 | 22 #include "avcodec.h" |
23 #include "pnm.h" | |
24 | |
25 static inline int pnm_space(int c) | |
26 { | |
6750 | 27 return c == ' ' || c == '\n' || c == '\r' || c == '\t'; |
4978 | 28 } |
29 | |
30 static void pnm_get(PNMContext *sc, char *str, int buf_size) | |
31 { | |
32 char *s; | |
33 int c; | |
34 | |
35 /* skip spaces and comments */ | |
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
36 for (;;) { |
4978 | 37 c = *sc->bytestream++; |
38 if (c == '#') { | |
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
39 do { |
4978 | 40 c = *sc->bytestream++; |
41 } while (c != '\n' && sc->bytestream < sc->bytestream_end); | |
42 } else if (!pnm_space(c)) { | |
43 break; | |
44 } | |
45 } | |
46 | |
47 s = str; | |
48 while (sc->bytestream < sc->bytestream_end && !pnm_space(c)) { | |
49 if ((s - str) < buf_size - 1) | |
50 *s++ = c; | |
51 c = *sc->bytestream++; | |
52 } | |
53 *s = '\0'; | |
54 } | |
55 | |
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
56 int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) |
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
57 { |
4978 | 58 char buf1[32], tuple_type[32]; |
59 int h, w, depth, maxval; | |
60 | |
61 pnm_get(s, buf1, sizeof(buf1)); | |
10612 | 62 s->type= buf1[1]-'0'; |
63 if(buf1[0] != 'P') | |
64 return -1; | |
65 | |
66 if (s->type==1 || s->type==4) { | |
4978 | 67 avctx->pix_fmt = PIX_FMT_MONOWHITE; |
10612 | 68 } else if (s->type==2 || s->type==5) { |
4978 | 69 if (avctx->codec_id == CODEC_ID_PGMYUV) |
70 avctx->pix_fmt = PIX_FMT_YUV420P; | |
71 else | |
72 avctx->pix_fmt = PIX_FMT_GRAY8; | |
10612 | 73 } else if (s->type==3 || s->type==6) { |
4978 | 74 avctx->pix_fmt = PIX_FMT_RGB24; |
10612 | 75 } else if (s->type==7) { |
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
76 w = -1; |
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
77 h = -1; |
4978 | 78 maxval = -1; |
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
79 depth = -1; |
4978 | 80 tuple_type[0] = '\0'; |
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
81 for (;;) { |
4978 | 82 pnm_get(s, buf1, sizeof(buf1)); |
83 if (!strcmp(buf1, "WIDTH")) { | |
84 pnm_get(s, buf1, sizeof(buf1)); | |
85 w = strtol(buf1, NULL, 10); | |
86 } else if (!strcmp(buf1, "HEIGHT")) { | |
87 pnm_get(s, buf1, sizeof(buf1)); | |
88 h = strtol(buf1, NULL, 10); | |
89 } else if (!strcmp(buf1, "DEPTH")) { | |
90 pnm_get(s, buf1, sizeof(buf1)); | |
91 depth = strtol(buf1, NULL, 10); | |
92 } else if (!strcmp(buf1, "MAXVAL")) { | |
93 pnm_get(s, buf1, sizeof(buf1)); | |
94 maxval = strtol(buf1, NULL, 10); | |
95 } else if (!strcmp(buf1, "TUPLETYPE")) { | |
96 pnm_get(s, tuple_type, sizeof(tuple_type)); | |
97 } else if (!strcmp(buf1, "ENDHDR")) { | |
98 break; | |
99 } else { | |
100 return -1; | |
101 } | |
102 } | |
103 /* check that all tags are present */ | |
104 if (w <= 0 || h <= 0 || maxval <= 0 || depth <= 0 || tuple_type[0] == '\0' || avcodec_check_dimensions(avctx, w, h)) | |
105 return -1; | |
106 | |
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
107 avctx->width = w; |
4978 | 108 avctx->height = h; |
109 if (depth == 1) { | |
110 if (maxval == 1) | |
111 avctx->pix_fmt = PIX_FMT_MONOWHITE; | |
112 else | |
113 avctx->pix_fmt = PIX_FMT_GRAY8; | |
114 } else if (depth == 3) { | |
7859
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
115 if (maxval < 256) { |
4978 | 116 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
|
117 } else { |
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
118 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
|
119 avctx->pix_fmt = PIX_FMT_NONE; |
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
120 return -1; |
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
121 } |
4978 | 122 } else if (depth == 4) { |
123 avctx->pix_fmt = PIX_FMT_RGB32; | |
124 } else { | |
125 return -1; | |
126 } | |
127 return 0; | |
128 } else { | |
129 return -1; | |
130 } | |
131 pnm_get(s, buf1, sizeof(buf1)); | |
132 avctx->width = atoi(buf1); | |
133 if (avctx->width <= 0) | |
134 return -1; | |
135 pnm_get(s, buf1, sizeof(buf1)); | |
136 avctx->height = atoi(buf1); | |
137 if(avcodec_check_dimensions(avctx, avctx->width, avctx->height)) | |
138 return -1; | |
139 if (avctx->pix_fmt != PIX_FMT_MONOWHITE) { | |
140 pnm_get(s, buf1, sizeof(buf1)); | |
141 s->maxval = atoi(buf1); | |
7859
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
142 if (s->maxval >= 256) { |
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
143 if (avctx->pix_fmt == PIX_FMT_GRAY8) { |
7865 | 144 avctx->pix_fmt = PIX_FMT_GRAY16BE; |
145 if (s->maxval != 65535) | |
146 avctx->pix_fmt = PIX_FMT_GRAY16; | |
9145
de31b10455cc
pnm: Add missing 'else'. Fixes decoding for 16-bit pgm.
jbr
parents:
9002
diff
changeset
|
147 } else if (avctx->pix_fmt == PIX_FMT_RGB24) { |
9002 | 148 if (s->maxval > 255) |
149 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
|
150 } else { |
9002 | 151 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
|
152 avctx->pix_fmt = PIX_FMT_NONE; |
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
153 return -1; |
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
154 } |
4978 | 155 } |
10612 | 156 }else |
157 s->maxval=1; | |
4978 | 158 /* more check if YUV420 */ |
159 if (avctx->pix_fmt == PIX_FMT_YUV420P) { | |
160 if ((avctx->width & 1) != 0) | |
161 return -1; | |
162 h = (avctx->height * 2); | |
163 if ((h % 3) != 0) | |
164 return -1; | |
165 h /= 3; | |
166 avctx->height = h; | |
167 } | |
168 return 0; | |
169 } | |
10460
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
170 |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
171 av_cold int ff_pnm_end(AVCodecContext *avctx) |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
172 { |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
173 PNMContext *s = avctx->priv_data; |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
174 |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
175 if (s->picture.data[0]) |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
176 avctx->release_buffer(avctx, &s->picture); |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
177 |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
178 return 0; |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
179 } |
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 av_cold int ff_pnm_init(AVCodecContext *avctx) |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
182 { |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
183 PNMContext *s = avctx->priv_data; |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
184 |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
185 avcodec_get_frame_defaults((AVFrame*)&s->picture); |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
186 avctx->coded_frame = (AVFrame*)&s->picture; |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
187 |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
188 return 0; |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
189 } |