Commit 63538a96 authored by Michael Niedermayer's avatar Michael Niedermayer

Support ASCII pnms.

Implements issue1452.

Originally committed as revision 20687 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 817d967d
...@@ -59,16 +59,20 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) ...@@ -59,16 +59,20 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s)
int h, w, depth, maxval; int h, w, depth, maxval;
pnm_get(s, buf1, sizeof(buf1)); 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; 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) if (avctx->codec_id == CODEC_ID_PGMYUV)
avctx->pix_fmt = PIX_FMT_YUV420P; avctx->pix_fmt = PIX_FMT_YUV420P;
else else
avctx->pix_fmt = PIX_FMT_GRAY8; 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; avctx->pix_fmt = PIX_FMT_RGB24;
} else if (!strcmp(buf1, "P7")) { } else if (s->type==7) {
w = -1; w = -1;
h = -1; h = -1;
maxval = -1; maxval = -1;
...@@ -149,7 +153,8 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) ...@@ -149,7 +153,8 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s)
return -1; return -1;
} }
} }
} }else
s->maxval=1;
/* more check if YUV420 */ /* more check if YUV420 */
if (avctx->pix_fmt == PIX_FMT_YUV420P) { if (avctx->pix_fmt == PIX_FMT_YUV420P) {
if ((avctx->width & 1) != 0) if ((avctx->width & 1) != 0)
......
...@@ -30,6 +30,7 @@ typedef struct PNMContext { ...@@ -30,6 +30,7 @@ typedef struct PNMContext {
uint8_t *bytestream_end; uint8_t *bytestream_end;
AVFrame picture; AVFrame picture;
int maxval; ///< maximum value of a pixel int maxval; ///< maximum value of a pixel
int type;
} PNMContext; } PNMContext;
int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s); int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s);
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "avcodec.h" #include "avcodec.h"
#include "bytestream.h" #include "bytestream.h"
#include "put_bits.h"
#include "pnm.h" #include "pnm.h"
...@@ -32,8 +33,9 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, ...@@ -32,8 +33,9 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data,
PNMContext * const s = avctx->priv_data; PNMContext * const s = avctx->priv_data;
AVFrame *picture = data; AVFrame *picture = data;
AVFrame * const p = (AVFrame*)&s->picture; AVFrame * const p = (AVFrame*)&s->picture;
int i, n, linesize, h, upgrade = 0; int i, j, n, linesize, h, upgrade = 0;
unsigned char *ptr; unsigned char *ptr;
int components, sample_len;
s->bytestream_start = s->bytestream_start =
s->bytestream = buf; s->bytestream = buf;
...@@ -58,29 +60,60 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, ...@@ -58,29 +60,60 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data,
return -1; return -1;
case PIX_FMT_RGB48BE: case PIX_FMT_RGB48BE:
n = avctx->width * 6; n = avctx->width * 6;
components=3;
sample_len=16;
goto do_read; goto do_read;
case PIX_FMT_RGB24: case PIX_FMT_RGB24:
n = avctx->width * 3; n = avctx->width * 3;
components=3;
sample_len=8;
goto do_read; goto do_read;
case PIX_FMT_GRAY8: case PIX_FMT_GRAY8:
n = avctx->width; n = avctx->width;
components=1;
sample_len=8;
if (s->maxval < 255) if (s->maxval < 255)
upgrade = 1; upgrade = 1;
goto do_read; goto do_read;
case PIX_FMT_GRAY16BE: case PIX_FMT_GRAY16BE:
case PIX_FMT_GRAY16LE: case PIX_FMT_GRAY16LE:
n = avctx->width * 2; n = avctx->width * 2;
components=1;
sample_len=16;
if (s->maxval < 65535) if (s->maxval < 65535)
upgrade = 2; upgrade = 2;
goto do_read; goto do_read;
case PIX_FMT_MONOWHITE: case PIX_FMT_MONOWHITE:
case PIX_FMT_MONOBLACK: case PIX_FMT_MONOBLACK:
n = (avctx->width + 7) >> 3; n = (avctx->width + 7) >> 3;
components=1;
sample_len=1;
do_read: do_read:
ptr = p->data[0]; ptr = p->data[0];
linesize = p->linesize[0]; linesize = p->linesize[0];
if (s->bytestream + n * avctx->height > s->bytestream_end) if (s->bytestream + n * avctx->height > s->bytestream_end)
return -1; 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++) { for (i = 0; i < avctx->height; i++) {
if (!upgrade) if (!upgrade)
memcpy(ptr, s->bytestream, n); memcpy(ptr, s->bytestream, n);
...@@ -98,6 +131,7 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, ...@@ -98,6 +131,7 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data,
s->bytestream += n; s->bytestream += n;
ptr += linesize; ptr += linesize;
} }
}
break; break;
case PIX_FMT_YUV420P: case PIX_FMT_YUV420P:
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment