FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pnmdec.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 "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;
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;
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:
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;
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),
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),
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),
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),
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),
320  .capabilities = AV_CODEC_CAP_DR1,
321 };
322 #endif
const char * s
Definition: avisynth_c.h:768
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
This structure describes decoded (raw) audio or video data.
Definition: frame.h:187
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition: j2kenc.c:206
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:64
#define AV_PIX_FMT_RGBA64
Definition: pixfmt.h:341
int maxval
maximum value of a pixel
Definition: pnm.h:31
int size
Definition: avcodec.h:1658
int av_log2(unsigned v)
Definition: intmath.c:26
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1960
uint8_t * bytestream
Definition: pnm.h:28
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:3133
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:87
#define src
Definition: vp8dsp.c:254
AVCodec.
Definition: avcodec.h:3681
uint8_t
uint8_t * data
Definition: avcodec.h:1657
#define av_log(a,...)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define AVERROR(e)
Definition: error.h:43
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:179
#define AV_PIX_FMT_YA16
Definition: pixfmt.h:336
#define AV_PIX_FMT_RGB48
Definition: pixfmt.h:337
uint8_t * bytestream_end
Definition: pnm.h:30
const char * name
Name of the codec implementation.
Definition: avcodec.h:3688
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:94
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:261
alias for AV_PIX_FMT_YA8
Definition: pixfmt.h:157
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:335
int width
picture width / height.
Definition: avcodec.h:1919
int n
Definition: avisynth_c.h:684
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:362
Definition: pnm.h:27
Libavcodec external API header.
int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext *const s)
Definition: pnm.c:61
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:218
main external API structure.
Definition: avcodec.h:1732
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: utils.c:953
void * buf
Definition: avisynth_c.h:690
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:351
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:348
static void samplecpy(uint8_t *dst, const uint8_t *src, int n, int maxval)
Definition: pnmdec.c:27
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:201
static int pnm_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: pnmdec.c:39
Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb...
Definition: pixfmt.h:72
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:62
Y , 8bpp.
Definition: pixfmt.h:70
common internal api header.
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition: put_bits.h:101
if(ret< 0)
Definition: vf_mcdeint.c:282
Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb...
Definition: pixfmt.h:71
static double c[64]
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition: put_bits.h:48
uint8_t * bytestream_start
Definition: pnm.h:29
void * priv_data
Definition: avcodec.h:1774
#define av_be2ne16(x)
Definition: bswap.h:92
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:256
static int decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt)
Definition: ffmpeg.c:2257
This structure stores compressed data.
Definition: avcodec.h:1634
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:994
for(j=16;j >0;--j)
int type
Definition: pnm.h:32
bitstream writer API