pnm.c
Go to the documentation of this file.
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 <stdlib.h>
23 #include <string.h>
24 
25 #include "libavutil/imgutils.h"
26 #include "avcodec.h"
27 #include "pnm.h"
28 
29 static inline int pnm_space(int c)
30 {
31  return c == ' ' || c == '\n' || c == '\r' || c == '\t';
32 }
33 
34 static void pnm_get(PNMContext *sc, char *str, int buf_size)
35 {
36  char *s;
37  int c;
38 
39  /* skip spaces and comments */
40  while (sc->bytestream < sc->bytestream_end) {
41  c = *sc->bytestream++;
42  if (c == '#') {
43  while (c != '\n' && sc->bytestream < sc->bytestream_end) {
44  c = *sc->bytestream++;
45  }
46  } else if (!pnm_space(c)) {
47  break;
48  }
49  }
50 
51  s = str;
52  while (sc->bytestream < sc->bytestream_end && !pnm_space(c)) {
53  if ((s - str) < buf_size - 1)
54  *s++ = c;
55  c = *sc->bytestream++;
56  }
57  *s = '\0';
58 }
59 
61 {
62  char buf1[32], tuple_type[32];
63  int h, w, depth, maxval;
64 
65  pnm_get(s, buf1, sizeof(buf1));
66  s->type= buf1[1]-'0';
67  if(buf1[0] != 'P')
68  return AVERROR_INVALIDDATA;
69 
70  if (s->type==1 || s->type==4) {
72  } else if (s->type==2 || s->type==5) {
73  if (avctx->codec_id == AV_CODEC_ID_PGMYUV)
74  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
75  else
76  avctx->pix_fmt = AV_PIX_FMT_GRAY8;
77  } else if (s->type==3 || s->type==6) {
78  avctx->pix_fmt = AV_PIX_FMT_RGB24;
79  } else if (s->type==7) {
80  w = -1;
81  h = -1;
82  maxval = -1;
83  depth = -1;
84  tuple_type[0] = '\0';
85  for (;;) {
86  pnm_get(s, buf1, sizeof(buf1));
87  if (!strcmp(buf1, "WIDTH")) {
88  pnm_get(s, buf1, sizeof(buf1));
89  w = strtol(buf1, NULL, 10);
90  } else if (!strcmp(buf1, "HEIGHT")) {
91  pnm_get(s, buf1, sizeof(buf1));
92  h = strtol(buf1, NULL, 10);
93  } else if (!strcmp(buf1, "DEPTH")) {
94  pnm_get(s, buf1, sizeof(buf1));
95  depth = strtol(buf1, NULL, 10);
96  } else if (!strcmp(buf1, "MAXVAL")) {
97  pnm_get(s, buf1, sizeof(buf1));
98  maxval = strtol(buf1, NULL, 10);
99  } else if (!strcmp(buf1, "TUPLTYPE") ||
100  /* libavcodec used to write invalid files */
101  !strcmp(buf1, "TUPLETYPE")) {
102  pnm_get(s, tuple_type, sizeof(tuple_type));
103  } else if (!strcmp(buf1, "ENDHDR")) {
104  break;
105  } else {
106  return AVERROR_INVALIDDATA;
107  }
108  }
109  /* check that all tags are present */
110  if (w <= 0 || h <= 0 || maxval <= 0 || depth <= 0 || tuple_type[0] == '\0' || av_image_check_size(w, h, 0, avctx) || s->bytestream >= s->bytestream_end)
111  return AVERROR_INVALIDDATA;
112 
113  avctx->width = w;
114  avctx->height = h;
115  s->maxval = maxval;
116  if (depth == 1) {
117  if (maxval == 1) {
118  avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;
119  } else if (maxval == 255) {
120  avctx->pix_fmt = AV_PIX_FMT_GRAY8;
121  } else {
122  avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
123  }
124  } else if (depth == 2) {
125  if (maxval == 255)
126  avctx->pix_fmt = AV_PIX_FMT_GRAY8A;
127  } else if (depth == 3) {
128  if (maxval < 256) {
129  avctx->pix_fmt = AV_PIX_FMT_RGB24;
130  } else {
131  avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
132  }
133  } else if (depth == 4) {
134  if (maxval < 256) {
135  avctx->pix_fmt = AV_PIX_FMT_RGBA;
136  } else {
137  avctx->pix_fmt = AV_PIX_FMT_RGBA64BE;
138  }
139  } else {
140  return AVERROR_INVALIDDATA;
141  }
142  return 0;
143  } else {
144  return AVERROR_INVALIDDATA;
145  }
146  pnm_get(s, buf1, sizeof(buf1));
147  w = atoi(buf1);
148  pnm_get(s, buf1, sizeof(buf1));
149  h = atoi(buf1);
150  if(w <= 0 || h <= 0 || av_image_check_size(w, h, 0, avctx) || s->bytestream >= s->bytestream_end)
151  return AVERROR_INVALIDDATA;
152 
153  avctx->width = w;
154  avctx->height = h;
155 
156  if (avctx->pix_fmt != AV_PIX_FMT_MONOWHITE && avctx->pix_fmt != AV_PIX_FMT_MONOBLACK) {
157  pnm_get(s, buf1, sizeof(buf1));
158  s->maxval = atoi(buf1);
159  if (s->maxval <= 0) {
160  av_log(avctx, AV_LOG_ERROR, "Invalid maxval: %d\n", s->maxval);
161  s->maxval = 255;
162  }
163  if (s->maxval >= 256) {
164  if (avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
165  avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
166  } else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) {
167  avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
168  } else if (avctx->pix_fmt == AV_PIX_FMT_YUV420P && s->maxval < 65536) {
169  if (s->maxval < 512)
171  else if (s->maxval < 1024)
173  else
174  avctx->pix_fmt = AV_PIX_FMT_YUV420P16;
175  } else {
176  av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format\n");
177  avctx->pix_fmt = AV_PIX_FMT_NONE;
178  return AVERROR_INVALIDDATA;
179  }
180  }
181  }else
182  s->maxval=1;
183  /* more check if YUV420 */
185  if ((avctx->width & 1) != 0)
186  return AVERROR_INVALIDDATA;
187  h = (avctx->height * 2);
188  if ((h % 3) != 0)
189  return AVERROR_INVALIDDATA;
190  h /= 3;
191  avctx->height = h;
192  }
193  return 0;
194 }
195 
197 {
198  PNMContext *s = avctx->priv_data;
199 
201  avctx->coded_frame = &s->picture;
202 
203  return 0;
204 }
const char * s
Definition: avisynth_c.h:668
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:1778
static int pnm_space(int c)
Definition: pnm.c:29
misc image utilities
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:70
AVFrame * coded_frame
the picture in the bitstream
int maxval
maximum value of a pixel
Definition: pnm.h:32
AVFrame picture
Definition: pnm.h:31
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
uint8_t * bytestream
Definition: pnm.h:28
planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
Definition: pixfmt.h:148
output residual component w
#define av_cold
Definition: attributes.h:78
packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is st...
Definition: pixfmt.h:209
static void pnm_get(PNMContext *sc, char *str, int buf_size)
Definition: pnm.c:34
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
uint8_t * bytestream_end
Definition: pnm.h:30
external API header
int depth
Definition: v4l.c:62
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:97
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
Definition: imgutils.c:231
8bit gray, 8bit alpha
Definition: pixfmt.h:141
int width
picture width / height.
planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
Definition: pixfmt.h:150
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:288
Definition: pnm.h:27
NULL
Definition: eval.c:55
enum AVCodecID codec_id
int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext *const s)
Definition: pnm.c:60
#define PIX_FMT_PLANAR
At least one pixel component is not in the first data plane.
Definition: pixdesc.h:93
uint8_t flags
Definition: pixdesc.h:76
main external API structure.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
void avcodec_get_frame_defaults(AVFrame *frame)
Set the fields of the given AVFrame to default values.
Y , 16bpp, big-endian.
Definition: pixfmt.h:101
Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb...
Definition: pixfmt.h:78
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:68
Y , 8bpp.
Definition: pixfmt.h:76
Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb...
Definition: pixfmt.h:77
static double c[64]
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big...
Definition: pixfmt.h:111
av_cold int ff_pnm_init(AVCodecContext *avctx)
Definition: pnm.c:196
int type
Definition: pnm.h:33