• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
samplecpy(uint8_t * dst,const uint8_t * src,int n,int maxval)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 
pnm_decode_frame(AVCodecContext * avctx,void * data,int * got_frame,AVPacket * avpkt)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     float scale;
50 
51     s->bytestream_start =
52     s->bytestream       = (uint8_t *)buf;
53     s->bytestream_end   = (uint8_t *)buf + buf_size;
54 
55     if ((ret = ff_pnm_decode_header(avctx, s)) < 0)
56         return ret;
57 
58     if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
59         return ret;
60     p->pict_type = AV_PICTURE_TYPE_I;
61     p->key_frame = 1;
62     avctx->bits_per_raw_sample = av_log2(s->maxval) + 1;
63 
64     switch (avctx->pix_fmt) {
65     default:
66         return AVERROR(EINVAL);
67     case AV_PIX_FMT_RGBA64:
68         n = avctx->width * 8;
69         components=4;
70         sample_len=16;
71         if (s->maxval < 65535)
72             upgrade = 2;
73         goto do_read;
74     case AV_PIX_FMT_RGB48:
75         n = avctx->width * 6;
76         components=3;
77         sample_len=16;
78         if (s->maxval < 65535)
79             upgrade = 2;
80         goto do_read;
81     case AV_PIX_FMT_RGBA:
82         n = avctx->width * 4;
83         components=4;
84         sample_len=8;
85         goto do_read;
86     case AV_PIX_FMT_RGB24:
87         n = avctx->width * 3;
88         components=3;
89         sample_len=8;
90         if (s->maxval < 255)
91             upgrade = 1;
92         goto do_read;
93     case AV_PIX_FMT_GRAY8:
94         n = avctx->width;
95         components=1;
96         sample_len=8;
97         if (s->maxval < 255)
98             upgrade = 1;
99         goto do_read;
100     case AV_PIX_FMT_GRAY8A:
101         n = avctx->width * 2;
102         components=2;
103         sample_len=8;
104         goto do_read;
105     case AV_PIX_FMT_GRAY16:
106         n = avctx->width * 2;
107         components=1;
108         sample_len=16;
109         if (s->maxval < 65535)
110             upgrade = 2;
111         goto do_read;
112     case AV_PIX_FMT_YA16:
113         n =  avctx->width * 4;
114         components=2;
115         sample_len=16;
116         if (s->maxval < 65535)
117             upgrade = 2;
118         goto do_read;
119     case AV_PIX_FMT_MONOWHITE:
120     case AV_PIX_FMT_MONOBLACK:
121         n = (avctx->width + 7) >> 3;
122         components=1;
123         sample_len=1;
124         is_mono = 1;
125     do_read:
126         ptr      = p->data[0];
127         linesize = p->linesize[0];
128         if (n * avctx->height > s->bytestream_end - s->bytestream)
129             return AVERROR_INVALIDDATA;
130         if(s->type < 4 || (is_mono && s->type==7)){
131             for (i=0; i<avctx->height; i++) {
132                 PutBitContext pb;
133                 init_put_bits(&pb, ptr, linesize);
134                 for(j=0; j<avctx->width * components; j++){
135                     unsigned int c=0;
136                     unsigned v=0;
137                     if(s->type < 4)
138                     while(s->bytestream < s->bytestream_end && (*s->bytestream < '0' || *s->bytestream > '9' ))
139                         s->bytestream++;
140                     if(s->bytestream >= s->bytestream_end)
141                         return AVERROR_INVALIDDATA;
142                     if (is_mono) {
143                         /* read a single digit */
144                         v = (*s->bytestream++)&1;
145                     } else {
146                         /* read a sequence of digits */
147                         for (k = 0; k < 6 && c <= 9; k += 1) {
148                             v = 10*v + c;
149                             c = (*s->bytestream++) - '0';
150                         }
151                         if (v > s->maxval) {
152                             av_log(avctx, AV_LOG_ERROR, "value %d larger than maxval %d\n", v, s->maxval);
153                             return AVERROR_INVALIDDATA;
154                         }
155                     }
156                     if (sample_len == 16) {
157                         ((uint16_t*)ptr)[j] = (((1<<sample_len)-1)*v + (s->maxval>>1))/s->maxval;
158                     } else
159                         put_bits(&pb, sample_len, (((1<<sample_len)-1)*v + (s->maxval>>1))/s->maxval);
160                 }
161                 if (sample_len != 16)
162                     flush_put_bits(&pb);
163                 ptr+= linesize;
164             }
165         }else{
166         for (i = 0; i < avctx->height; i++) {
167             if (!upgrade)
168                 samplecpy(ptr, s->bytestream, n, s->maxval);
169             else if (upgrade == 1) {
170                 unsigned int j, f = (255 * 128 + s->maxval / 2) / s->maxval;
171                 for (j = 0; j < n; j++)
172                     ptr[j] = (s->bytestream[j] * f + 64) >> 7;
173             } else if (upgrade == 2) {
174                 unsigned int j, v, f = (65535 * 32768 + s->maxval / 2) / s->maxval;
175                 for (j = 0; j < n / 2; j++) {
176                     v = AV_RB16(s->bytestream + 2*j);
177                     ((uint16_t *)ptr)[j] = (v * f + 16384) >> 15;
178                 }
179             }
180             s->bytestream += n;
181             ptr           += linesize;
182         }
183         }
184         break;
185     case AV_PIX_FMT_YUV420P:
186     case AV_PIX_FMT_YUV420P9:
187     case AV_PIX_FMT_YUV420P10:
188         {
189             unsigned char *ptr1, *ptr2;
190 
191             n        = avctx->width;
192             ptr      = p->data[0];
193             linesize = p->linesize[0];
194             if (s->maxval >= 256)
195                 n *= 2;
196             if (n * avctx->height * 3 / 2 > s->bytestream_end - s->bytestream)
197                 return AVERROR_INVALIDDATA;
198             for (i = 0; i < avctx->height; i++) {
199                 samplecpy(ptr, s->bytestream, n, s->maxval);
200                 s->bytestream += n;
201                 ptr           += linesize;
202             }
203             ptr1 = p->data[1];
204             ptr2 = p->data[2];
205             n >>= 1;
206             h = avctx->height >> 1;
207             for (i = 0; i < h; i++) {
208                 samplecpy(ptr1, s->bytestream, n, s->maxval);
209                 s->bytestream += n;
210                 samplecpy(ptr2, s->bytestream, n, s->maxval);
211                 s->bytestream += n;
212                 ptr1 += p->linesize[1];
213                 ptr2 += p->linesize[2];
214             }
215         }
216         break;
217     case AV_PIX_FMT_YUV420P16:
218         {
219             uint16_t *ptr1, *ptr2;
220             const int f = (65535 * 32768 + s->maxval / 2) / s->maxval;
221             unsigned int j, v;
222 
223             n        = avctx->width * 2;
224             ptr      = p->data[0];
225             linesize = p->linesize[0];
226             if (n * avctx->height * 3 / 2 > s->bytestream_end - s->bytestream)
227                 return AVERROR_INVALIDDATA;
228             for (i = 0; i < avctx->height; i++) {
229                 for (j = 0; j < n / 2; j++) {
230                     v = AV_RB16(s->bytestream + 2*j);
231                     ((uint16_t *)ptr)[j] = (v * f + 16384) >> 15;
232                 }
233                 s->bytestream += n;
234                 ptr           += linesize;
235             }
236             ptr1 = (uint16_t*)p->data[1];
237             ptr2 = (uint16_t*)p->data[2];
238             n >>= 1;
239             h = avctx->height >> 1;
240             for (i = 0; i < h; i++) {
241                 for (j = 0; j < n / 2; j++) {
242                     v = AV_RB16(s->bytestream + 2*j);
243                     ptr1[j] = (v * f + 16384) >> 15;
244                 }
245                 s->bytestream += n;
246 
247                 for (j = 0; j < n / 2; j++) {
248                     v = AV_RB16(s->bytestream + 2*j);
249                     ptr2[j] = (v * f + 16384) >> 15;
250                 }
251                 s->bytestream += n;
252 
253                 ptr1 += p->linesize[1] / 2;
254                 ptr2 += p->linesize[2] / 2;
255             }
256         }
257         break;
258     case AV_PIX_FMT_GBRPF32:
259         if (avctx->width * avctx->height * 12 > s->bytestream_end - s->bytestream)
260             return AVERROR_INVALIDDATA;
261         scale = 1.f / s->scale;
262         if (s->endian) {
263             float *r, *g, *b;
264 
265             r = (float *)p->data[2];
266             g = (float *)p->data[0];
267             b = (float *)p->data[1];
268             for (int i = 0; i < avctx->height; i++) {
269                 for (int j = 0; j < avctx->width; j++) {
270                     r[j] = av_int2float(AV_RL32(s->bytestream+0)) * scale;
271                     g[j] = av_int2float(AV_RL32(s->bytestream+4)) * scale;
272                     b[j] = av_int2float(AV_RL32(s->bytestream+8)) * scale;
273                     s->bytestream += 12;
274                 }
275 
276                 r += p->linesize[2] / 4;
277                 g += p->linesize[0] / 4;
278                 b += p->linesize[1] / 4;
279             }
280         } else {
281             float *r, *g, *b;
282 
283             r = (float *)p->data[2];
284             g = (float *)p->data[0];
285             b = (float *)p->data[1];
286             for (int i = 0; i < avctx->height; i++) {
287                 for (int j = 0; j < avctx->width; j++) {
288                     r[j] = av_int2float(AV_RB32(s->bytestream+0)) * scale;
289                     g[j] = av_int2float(AV_RB32(s->bytestream+4)) * scale;
290                     b[j] = av_int2float(AV_RB32(s->bytestream+8)) * scale;
291                     s->bytestream += 12;
292                 }
293 
294                 r += p->linesize[2] / 4;
295                 g += p->linesize[0] / 4;
296                 b += p->linesize[1] / 4;
297             }
298         }
299         break;
300     case AV_PIX_FMT_GRAYF32:
301         if (avctx->width * avctx->height * 4 > s->bytestream_end - s->bytestream)
302             return AVERROR_INVALIDDATA;
303         scale = 1.f / s->scale;
304         if (s->endian) {
305             float *g = (float *)p->data[0];
306             for (int i = 0; i < avctx->height; i++) {
307                 for (int j = 0; j < avctx->width; j++) {
308                     g[j] = av_int2float(AV_RL32(s->bytestream)) * scale;
309                     s->bytestream += 4;
310                 }
311                 g += p->linesize[0] / 4;
312             }
313         } else {
314             float *g = (float *)p->data[0];
315             for (int i = 0; i < avctx->height; i++) {
316                 for (int j = 0; j < avctx->width; j++) {
317                     g[j] = av_int2float(AV_RB32(s->bytestream)) * scale;
318                     s->bytestream += 4;
319                 }
320                 g += p->linesize[0] / 4;
321             }
322         }
323         break;
324     }
325     *got_frame = 1;
326 
327     return s->bytestream - s->bytestream_start;
328 }
329 
330 
331 #if CONFIG_PGM_DECODER
332 AVCodec ff_pgm_decoder = {
333     .name           = "pgm",
334     .long_name      = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"),
335     .type           = AVMEDIA_TYPE_VIDEO,
336     .id             = AV_CODEC_ID_PGM,
337     .priv_data_size = sizeof(PNMContext),
338     .decode         = pnm_decode_frame,
339     .capabilities   = AV_CODEC_CAP_DR1,
340 };
341 #endif
342 
343 #if CONFIG_PGMYUV_DECODER
344 AVCodec ff_pgmyuv_decoder = {
345     .name           = "pgmyuv",
346     .long_name      = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"),
347     .type           = AVMEDIA_TYPE_VIDEO,
348     .id             = AV_CODEC_ID_PGMYUV,
349     .priv_data_size = sizeof(PNMContext),
350     .decode         = pnm_decode_frame,
351     .capabilities   = AV_CODEC_CAP_DR1,
352 };
353 #endif
354 
355 #if CONFIG_PPM_DECODER
356 AVCodec ff_ppm_decoder = {
357     .name           = "ppm",
358     .long_name      = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"),
359     .type           = AVMEDIA_TYPE_VIDEO,
360     .id             = AV_CODEC_ID_PPM,
361     .priv_data_size = sizeof(PNMContext),
362     .decode         = pnm_decode_frame,
363     .capabilities   = AV_CODEC_CAP_DR1,
364 };
365 #endif
366 
367 #if CONFIG_PBM_DECODER
368 AVCodec ff_pbm_decoder = {
369     .name           = "pbm",
370     .long_name      = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"),
371     .type           = AVMEDIA_TYPE_VIDEO,
372     .id             = AV_CODEC_ID_PBM,
373     .priv_data_size = sizeof(PNMContext),
374     .decode         = pnm_decode_frame,
375     .capabilities   = AV_CODEC_CAP_DR1,
376 };
377 #endif
378 
379 #if CONFIG_PAM_DECODER
380 AVCodec ff_pam_decoder = {
381     .name           = "pam",
382     .long_name      = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"),
383     .type           = AVMEDIA_TYPE_VIDEO,
384     .id             = AV_CODEC_ID_PAM,
385     .priv_data_size = sizeof(PNMContext),
386     .decode         = pnm_decode_frame,
387     .capabilities   = AV_CODEC_CAP_DR1,
388 };
389 #endif
390 
391 #if CONFIG_PFM_DECODER
392 AVCodec ff_pfm_decoder = {
393     .name           = "pfm",
394     .long_name      = NULL_IF_CONFIG_SMALL("PFM (Portable FloatMap) image"),
395     .type           = AVMEDIA_TYPE_VIDEO,
396     .id             = AV_CODEC_ID_PFM,
397     .priv_data_size = sizeof(PNMContext),
398     .decode         = pnm_decode_frame,
399     .capabilities   = AV_CODEC_CAP_DR1,
400 };
401 #endif
402