blob: 958c5e43b07c05a23f7146937070797dafe9a8fa
1 | /* |
2 | * PNM image format |
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 "avcodec.h" |
23 | #include "internal.h" |
24 | #include "put_bits.h" |
25 | #include "pnm.h" |
26 | |
27 | static void samplecpy(uint8_t *dst, const uint8_t *src, int n, int maxval) |
28 | { |
29 | if (maxval <= 255) { |
30 | memcpy(dst, src, n); |
31 | } else { |
32 | int i; |
33 | for (i=0; i<n/2; i++) { |
34 | ((uint16_t *)dst)[i] = AV_RB16(src+2*i); |
35 | } |
36 | } |
37 | } |
38 | |
39 | static int pnm_decode_frame(AVCodecContext *avctx, void *data, |
40 | int *got_frame, AVPacket *avpkt) |
41 | { |
42 | const uint8_t *buf = avpkt->data; |
43 | int buf_size = avpkt->size; |
44 | PNMContext * const s = avctx->priv_data; |
45 | AVFrame * const p = data; |
46 | int i, j, k, n, linesize, h, upgrade = 0, is_mono = 0; |
47 | unsigned char *ptr; |
48 | int components, sample_len, ret; |
49 | |
50 | s->bytestream_start = |
51 | s->bytestream = (uint8_t *)buf; |
52 | s->bytestream_end = (uint8_t *)buf + buf_size; |
53 | |
54 | if ((ret = ff_pnm_decode_header(avctx, s)) < 0) |
55 | return ret; |
56 | |
57 | if ((ret = ff_get_buffer(avctx, p, 0)) < 0) |
58 | return ret; |
59 | p->pict_type = AV_PICTURE_TYPE_I; |
60 | p->key_frame = 1; |
61 | avctx->bits_per_raw_sample = av_log2(s->maxval) + 1; |
62 | |
63 | switch (avctx->pix_fmt) { |
64 | default: |
65 | return AVERROR(EINVAL); |
66 | case AV_PIX_FMT_RGBA64: |
67 | n = avctx->width * 8; |
68 | components=4; |
69 | sample_len=16; |
70 | if (s->maxval < 65535) |
71 | upgrade = 2; |
72 | goto do_read; |
73 | case AV_PIX_FMT_RGB48: |
74 | n = avctx->width * 6; |
75 | components=3; |
76 | sample_len=16; |
77 | if (s->maxval < 65535) |
78 | upgrade = 2; |
79 | goto do_read; |
80 | case AV_PIX_FMT_RGBA: |
81 | n = avctx->width * 4; |
82 | components=4; |
83 | sample_len=8; |
84 | goto do_read; |
85 | case AV_PIX_FMT_RGB24: |
86 | n = avctx->width * 3; |
87 | components=3; |
88 | sample_len=8; |
89 | if (s->maxval < 255) |
90 | upgrade = 1; |
91 | goto do_read; |
92 | case AV_PIX_FMT_GRAY8: |
93 | n = avctx->width; |
94 | components=1; |
95 | sample_len=8; |
96 | if (s->maxval < 255) |
97 | upgrade = 1; |
98 | goto do_read; |
99 | case AV_PIX_FMT_GRAY8A: |
100 | n = avctx->width * 2; |
101 | components=2; |
102 | sample_len=8; |
103 | goto do_read; |
104 | case AV_PIX_FMT_GRAY16: |
105 | n = avctx->width * 2; |
106 | components=1; |
107 | sample_len=16; |
108 | if (s->maxval < 65535) |
109 | upgrade = 2; |
110 | goto do_read; |
111 | case AV_PIX_FMT_YA16: |
112 | n = avctx->width * 4; |
113 | components=2; |
114 | sample_len=16; |
115 | if (s->maxval < 65535) |
116 | upgrade = 2; |
117 | goto do_read; |
118 | case AV_PIX_FMT_MONOWHITE: |
119 | case AV_PIX_FMT_MONOBLACK: |
120 | n = (avctx->width + 7) >> 3; |
121 | components=1; |
122 | sample_len=1; |
123 | is_mono = 1; |
124 | do_read: |
125 | ptr = p->data[0]; |
126 | linesize = p->linesize[0]; |
127 | if (n * avctx->height > s->bytestream_end - s->bytestream) |
128 | return AVERROR_INVALIDDATA; |
129 | if(s->type < 4 || (is_mono && s->type==7)){ |
130 | for (i=0; i<avctx->height; i++) { |
131 | PutBitContext pb; |
132 | init_put_bits(&pb, ptr, linesize); |
133 | for(j=0; j<avctx->width * components; j++){ |
134 | unsigned int c=0; |
135 | int v=0; |
136 | if(s->type < 4) |
137 | while(s->bytestream < s->bytestream_end && (*s->bytestream < '0' || *s->bytestream > '9' )) |
138 | s->bytestream++; |
139 | if(s->bytestream >= s->bytestream_end) |
140 | return AVERROR_INVALIDDATA; |
141 | if (is_mono) { |
142 | /* read a single digit */ |
143 | v = (*s->bytestream++)&1; |
144 | } else { |
145 | /* read a sequence of digits */ |
146 | for (k = 0; k < 5 && c <= 9; k += 1) { |
147 | v = 10*v + c; |
148 | c = (*s->bytestream++) - '0'; |
149 | } |
150 | if (v > s->maxval) { |
151 | av_log(avctx, AV_LOG_ERROR, "value %d larger than maxval %d\n", v, s->maxval); |
152 | return AVERROR_INVALIDDATA; |
153 | } |
154 | } |
155 | if (sample_len == 16) { |
156 | ((uint16_t*)ptr)[j] = (((1<<sample_len)-1)*v + (s->maxval>>1))/s->maxval; |
157 | } else |
158 | put_bits(&pb, sample_len, (((1<<sample_len)-1)*v + (s->maxval>>1))/s->maxval); |
159 | } |
160 | if (sample_len != 16) |
161 | flush_put_bits(&pb); |
162 | ptr+= linesize; |
163 | } |
164 | }else{ |
165 | for (i = 0; i < avctx->height; i++) { |
166 | if (!upgrade) |
167 | samplecpy(ptr, s->bytestream, n, s->maxval); |
168 | else if (upgrade == 1) { |
169 | unsigned int j, f = (255 * 128 + s->maxval / 2) / s->maxval; |
170 | for (j = 0; j < n; j++) |
171 | ptr[j] = (s->bytestream[j] * f + 64) >> 7; |
172 | } else if (upgrade == 2) { |
173 | unsigned int j, v, f = (65535 * 32768 + s->maxval / 2) / s->maxval; |
174 | for (j = 0; j < n / 2; j++) { |
175 | v = av_be2ne16(((uint16_t *)s->bytestream)[j]); |
176 | ((uint16_t *)ptr)[j] = (v * f + 16384) >> 15; |
177 | } |
178 | } |
179 | s->bytestream += n; |
180 | ptr += linesize; |
181 | } |
182 | } |
183 | break; |
184 | case AV_PIX_FMT_YUV420P: |
185 | case AV_PIX_FMT_YUV420P9: |
186 | case AV_PIX_FMT_YUV420P10: |
187 | { |
188 | unsigned char *ptr1, *ptr2; |
189 | |
190 | n = avctx->width; |
191 | ptr = p->data[0]; |
192 | linesize = p->linesize[0]; |
193 | if (s->maxval >= 256) |
194 | n *= 2; |
195 | if (n * avctx->height * 3 / 2 > s->bytestream_end - s->bytestream) |
196 | return AVERROR_INVALIDDATA; |
197 | for (i = 0; i < avctx->height; i++) { |
198 | samplecpy(ptr, s->bytestream, n, s->maxval); |
199 | s->bytestream += n; |
200 | ptr += linesize; |
201 | } |
202 | ptr1 = p->data[1]; |
203 | ptr2 = p->data[2]; |
204 | n >>= 1; |
205 | h = avctx->height >> 1; |
206 | for (i = 0; i < h; i++) { |
207 | samplecpy(ptr1, s->bytestream, n, s->maxval); |
208 | s->bytestream += n; |
209 | samplecpy(ptr2, s->bytestream, n, s->maxval); |
210 | s->bytestream += n; |
211 | ptr1 += p->linesize[1]; |
212 | ptr2 += p->linesize[2]; |
213 | } |
214 | } |
215 | break; |
216 | case AV_PIX_FMT_YUV420P16: |
217 | { |
218 | uint16_t *ptr1, *ptr2; |
219 | const int f = (65535 * 32768 + s->maxval / 2) / s->maxval; |
220 | unsigned int j, v; |
221 | |
222 | n = avctx->width * 2; |
223 | ptr = p->data[0]; |
224 | linesize = p->linesize[0]; |
225 | if (n * avctx->height * 3 / 2 > s->bytestream_end - s->bytestream) |
226 | return AVERROR_INVALIDDATA; |
227 | for (i = 0; i < avctx->height; i++) { |
228 | for (j = 0; j < n / 2; j++) { |
229 | v = av_be2ne16(((uint16_t *)s->bytestream)[j]); |
230 | ((uint16_t *)ptr)[j] = (v * f + 16384) >> 15; |
231 | } |
232 | s->bytestream += n; |
233 | ptr += linesize; |
234 | } |
235 | ptr1 = (uint16_t*)p->data[1]; |
236 | ptr2 = (uint16_t*)p->data[2]; |
237 | n >>= 1; |
238 | h = avctx->height >> 1; |
239 | for (i = 0; i < h; i++) { |
240 | for (j = 0; j < n / 2; j++) { |
241 | v = av_be2ne16(((uint16_t *)s->bytestream)[j]); |
242 | ptr1[j] = (v * f + 16384) >> 15; |
243 | } |
244 | s->bytestream += n; |
245 | |
246 | for (j = 0; j < n / 2; j++) { |
247 | v = av_be2ne16(((uint16_t *)s->bytestream)[j]); |
248 | ptr2[j] = (v * f + 16384) >> 15; |
249 | } |
250 | s->bytestream += n; |
251 | |
252 | ptr1 += p->linesize[1] / 2; |
253 | ptr2 += p->linesize[2] / 2; |
254 | } |
255 | } |
256 | break; |
257 | } |
258 | *got_frame = 1; |
259 | |
260 | return s->bytestream - s->bytestream_start; |
261 | } |
262 | |
263 | |
264 | #if CONFIG_PGM_DECODER |
265 | AVCodec ff_pgm_decoder = { |
266 | .name = "pgm", |
267 | .long_name = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"), |
268 | .type = AVMEDIA_TYPE_VIDEO, |
269 | .id = AV_CODEC_ID_PGM, |
270 | .priv_data_size = sizeof(PNMContext), |
271 | .decode = pnm_decode_frame, |
272 | .capabilities = AV_CODEC_CAP_DR1, |
273 | }; |
274 | #endif |
275 | |
276 | #if CONFIG_PGMYUV_DECODER |
277 | AVCodec ff_pgmyuv_decoder = { |
278 | .name = "pgmyuv", |
279 | .long_name = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"), |
280 | .type = AVMEDIA_TYPE_VIDEO, |
281 | .id = AV_CODEC_ID_PGMYUV, |
282 | .priv_data_size = sizeof(PNMContext), |
283 | .decode = pnm_decode_frame, |
284 | .capabilities = AV_CODEC_CAP_DR1, |
285 | }; |
286 | #endif |
287 | |
288 | #if CONFIG_PPM_DECODER |
289 | AVCodec ff_ppm_decoder = { |
290 | .name = "ppm", |
291 | .long_name = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"), |
292 | .type = AVMEDIA_TYPE_VIDEO, |
293 | .id = AV_CODEC_ID_PPM, |
294 | .priv_data_size = sizeof(PNMContext), |
295 | .decode = pnm_decode_frame, |
296 | .capabilities = AV_CODEC_CAP_DR1, |
297 | }; |
298 | #endif |
299 | |
300 | #if CONFIG_PBM_DECODER |
301 | AVCodec ff_pbm_decoder = { |
302 | .name = "pbm", |
303 | .long_name = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"), |
304 | .type = AVMEDIA_TYPE_VIDEO, |
305 | .id = AV_CODEC_ID_PBM, |
306 | .priv_data_size = sizeof(PNMContext), |
307 | .decode = pnm_decode_frame, |
308 | .capabilities = AV_CODEC_CAP_DR1, |
309 | }; |
310 | #endif |
311 | |
312 | #if CONFIG_PAM_DECODER |
313 | AVCodec ff_pam_decoder = { |
314 | .name = "pam", |
315 | .long_name = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"), |
316 | .type = AVMEDIA_TYPE_VIDEO, |
317 | .id = AV_CODEC_ID_PAM, |
318 | .priv_data_size = sizeof(PNMContext), |
319 | .decode = pnm_decode_frame, |
320 | .capabilities = AV_CODEC_CAP_DR1, |
321 | }; |
322 | #endif |
323 |