Mercurial > libavcodec.hg
changeset 10612:d6860312274c libavcodec
Support ASCII pnms.
Implements issue1452.
author | michael |
---|---|
date | Tue, 01 Dec 2009 16:56:13 +0000 |
parents | eb37707704e4 |
children | 2ae4eb19665a |
files | pnm.c pnm.h pnmdec.c |
diffstat | 3 files changed, 46 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/pnm.c Tue Dec 01 11:38:37 2009 +0000 +++ b/pnm.c Tue Dec 01 16:56:13 2009 +0000 @@ -59,16 +59,20 @@ int h, w, depth, maxval; pnm_get(s, buf1, sizeof(buf1)); - if (!strcmp(buf1, "P4")) { + s->type= buf1[1]-'0'; + if(buf1[0] != 'P') + return -1; + + if (s->type==1 || s->type==4) { avctx->pix_fmt = PIX_FMT_MONOWHITE; - } else if (!strcmp(buf1, "P5")) { + } else if (s->type==2 || s->type==5) { if (avctx->codec_id == CODEC_ID_PGMYUV) avctx->pix_fmt = PIX_FMT_YUV420P; else avctx->pix_fmt = PIX_FMT_GRAY8; - } else if (!strcmp(buf1, "P6")) { + } else if (s->type==3 || s->type==6) { avctx->pix_fmt = PIX_FMT_RGB24; - } else if (!strcmp(buf1, "P7")) { + } else if (s->type==7) { w = -1; h = -1; maxval = -1; @@ -149,7 +153,8 @@ return -1; } } - } + }else + s->maxval=1; /* more check if YUV420 */ if (avctx->pix_fmt == PIX_FMT_YUV420P) { if ((avctx->width & 1) != 0)
--- a/pnm.h Tue Dec 01 11:38:37 2009 +0000 +++ b/pnm.h Tue Dec 01 16:56:13 2009 +0000 @@ -30,6 +30,7 @@ uint8_t *bytestream_end; AVFrame picture; int maxval; ///< maximum value of a pixel + int type; } PNMContext; int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s);
--- a/pnmdec.c Tue Dec 01 11:38:37 2009 +0000 +++ b/pnmdec.c Tue Dec 01 16:56:13 2009 +0000 @@ -21,6 +21,7 @@ #include "avcodec.h" #include "bytestream.h" +#include "put_bits.h" #include "pnm.h" @@ -32,8 +33,9 @@ PNMContext * const s = avctx->priv_data; AVFrame *picture = data; AVFrame * const p = (AVFrame*)&s->picture; - int i, n, linesize, h, upgrade = 0; + int i, j, n, linesize, h, upgrade = 0; unsigned char *ptr; + int components, sample_len; s->bytestream_start = s->bytestream = buf; @@ -58,29 +60,60 @@ return -1; case PIX_FMT_RGB48BE: n = avctx->width * 6; + components=3; + sample_len=16; goto do_read; case PIX_FMT_RGB24: n = avctx->width * 3; + components=3; + sample_len=8; goto do_read; case PIX_FMT_GRAY8: n = avctx->width; + components=1; + sample_len=8; if (s->maxval < 255) upgrade = 1; goto do_read; case PIX_FMT_GRAY16BE: case PIX_FMT_GRAY16LE: n = avctx->width * 2; + components=1; + sample_len=16; if (s->maxval < 65535) upgrade = 2; goto do_read; case PIX_FMT_MONOWHITE: case PIX_FMT_MONOBLACK: n = (avctx->width + 7) >> 3; + components=1; + sample_len=1; do_read: ptr = p->data[0]; linesize = p->linesize[0]; if (s->bytestream + n * avctx->height > s->bytestream_end) return -1; + if(s->type < 4){ + for (i=0; i<avctx->height; i++) { + PutBitContext pb; + init_put_bits(&pb, ptr, linesize); + for(j=0; j<avctx->width * components; j++){ + unsigned int c=0; + int v=0; + while(s->bytestream < s->bytestream_end && (*s->bytestream < '0' || *s->bytestream > '9' )) + s->bytestream++; + if(s->bytestream >= s->bytestream_end) + return -1; + do{ + v= 10*v + c; + c= (*s->bytestream++) - '0'; + }while(c <= 9); + put_bits(&pb, sample_len, (((1<<sample_len)-1)*v + (s->maxval>>1))/s->maxval); + } + flush_put_bits(&pb); + ptr+= linesize; + } + }else{ for (i = 0; i < avctx->height; i++) { if (!upgrade) memcpy(ptr, s->bytestream, n); @@ -98,6 +131,7 @@ s->bytestream += n; ptr += linesize; } + } break; case PIX_FMT_YUV420P: {