Mercurial > libavcodec.hg
comparison pnm.c @ 2348:d02fb928ca44 libavcodec
pnm parser
author | michael |
---|---|
date | Fri, 12 Nov 2004 22:55:29 +0000 |
parents | f09680c5e8f4 |
children | f7f4f06a55c9 |
comparison
equal
deleted
inserted
replaced
2347:c6280d48be02 | 2348:d02fb928ca44 |
---|---|
15 * You should have received a copy of the GNU Lesser General Public | 15 * You should have received a copy of the GNU Lesser General Public |
16 * License along with this library; if not, write to the Free Software | 16 * License along with this library; if not, write to the Free Software |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 */ | 18 */ |
19 #include "avcodec.h" | 19 #include "avcodec.h" |
20 #include "mpegvideo.h" //only for ParseContext | |
20 | 21 |
21 typedef struct PNMContext { | 22 typedef struct PNMContext { |
22 uint8_t *bytestream; | 23 uint8_t *bytestream; |
23 uint8_t *bytestream_start; | 24 uint8_t *bytestream_start; |
24 uint8_t *bytestream_end; | 25 uint8_t *bytestream_end; |
63 avctx->coded_frame= (AVFrame*)&s->picture; | 64 avctx->coded_frame= (AVFrame*)&s->picture; |
64 | 65 |
65 return 0; | 66 return 0; |
66 } | 67 } |
67 | 68 |
68 static int pnm_decode_frame(AVCodecContext *avctx, | 69 static int pnm_decode_header(AVCodecContext *avctx, PNMContext * const s){ |
69 void *data, int *data_size, | |
70 uint8_t *buf, int buf_size) | |
71 { | |
72 PNMContext * const s = avctx->priv_data; | |
73 AVFrame *picture = data; | |
74 AVFrame * const p= (AVFrame*)&s->picture; | |
75 int i, n, linesize, h; | |
76 char buf1[32]; | 70 char buf1[32]; |
77 unsigned char *ptr; | 71 int h; |
78 | |
79 /* special case for last picture */ | |
80 if (buf_size == 0) { | |
81 return 0; | |
82 } | |
83 | |
84 s->bytestream_start= | |
85 s->bytestream= buf; | |
86 s->bytestream_end= buf + buf_size; | |
87 | 72 |
88 pnm_get(s, buf1, sizeof(buf1)); | 73 pnm_get(s, buf1, sizeof(buf1)); |
89 if (!strcmp(buf1, "P4")) { | 74 if (!strcmp(buf1, "P4")) { |
90 avctx->pix_fmt = PIX_FMT_MONOWHITE; | 75 avctx->pix_fmt = PIX_FMT_MONOWHITE; |
91 } else if (!strcmp(buf1, "P5")) { | 76 } else if (!strcmp(buf1, "P5")) { |
118 if ((h % 3) != 0) | 103 if ((h % 3) != 0) |
119 return -1; | 104 return -1; |
120 h /= 3; | 105 h /= 3; |
121 avctx->height = h; | 106 avctx->height = h; |
122 } | 107 } |
108 return 0; | |
109 } | |
110 | |
111 static int pnm_decode_frame(AVCodecContext *avctx, | |
112 void *data, int *data_size, | |
113 uint8_t *buf, int buf_size) | |
114 { | |
115 PNMContext * const s = avctx->priv_data; | |
116 AVFrame *picture = data; | |
117 AVFrame * const p= (AVFrame*)&s->picture; | |
118 int i, n, linesize, h; | |
119 unsigned char *ptr; | |
120 | |
121 /* special case for last picture */ | |
122 if (buf_size == 0) { | |
123 return 0; | |
124 } | |
125 | |
126 s->bytestream_start= | |
127 s->bytestream= buf; | |
128 s->bytestream_end= buf + buf_size; | |
129 | |
130 if(pnm_decode_header(avctx, s) < 0) | |
131 return h; | |
123 | 132 |
124 if(p->data[0]) | 133 if(p->data[0]) |
125 avctx->release_buffer(avctx, p); | 134 avctx->release_buffer(avctx, p); |
126 | 135 |
127 p->reference= 0; | 136 p->reference= 0; |
490 else | 499 else |
491 return 0; | 500 return 0; |
492 } | 501 } |
493 #endif | 502 #endif |
494 | 503 |
504 static int pnm_parse(AVCodecParserContext *s, | |
505 AVCodecContext *avctx, | |
506 uint8_t **poutbuf, int *poutbuf_size, | |
507 const uint8_t *buf, int buf_size) | |
508 { | |
509 ParseContext *pc = s->priv_data; | |
510 PNMContext pnmctx; | |
511 int next; | |
512 | |
513 for(; pc->overread>0; pc->overread--){ | |
514 pc->buffer[pc->index++]= pc->buffer[pc->overread_index++]; | |
515 } | |
516 retry: | |
517 if(pc->index){ | |
518 pnmctx.bytestream_start= | |
519 pnmctx.bytestream= pc->buffer; | |
520 pnmctx.bytestream_end= pc->buffer + pc->index; | |
521 }else{ | |
522 pnmctx.bytestream_start= | |
523 pnmctx.bytestream= buf; | |
524 pnmctx.bytestream_end= buf + buf_size; | |
525 } | |
526 if(pnm_decode_header(avctx, &pnmctx) < 0){ | |
527 if(pnmctx.bytestream < pnmctx.bytestream_end){ | |
528 if(pc->index){ | |
529 pc->index=0; | |
530 }else{ | |
531 buf++; | |
532 buf_size--; | |
533 } | |
534 goto retry; | |
535 } | |
536 #if 0 | |
537 if(pc->index && pc->index*2 + FF_INPUT_BUFFER_PADDING_SIZE < pc->buffer_size && buf_size > pc->index){ | |
538 memcpy(pc->buffer + pc->index, buf, pc->index); | |
539 pc->index += pc->index; | |
540 buf += pc->index; | |
541 buf_size -= pc->index; | |
542 goto retry; | |
543 } | |
544 #endif | |
545 next= END_NOT_FOUND; | |
546 }else{ | |
547 next= pnmctx.bytestream - pnmctx.bytestream_start | |
548 + avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); | |
549 if(pnmctx.bytestream_start!=buf) | |
550 next-= pc->index; | |
551 if(next > buf_size) | |
552 next= END_NOT_FOUND; | |
553 } | |
554 | |
555 if(ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size)<0){ | |
556 *poutbuf = NULL; | |
557 *poutbuf_size = 0; | |
558 return buf_size; | |
559 } | |
560 *poutbuf = (uint8_t *)buf; | |
561 *poutbuf_size = buf_size; | |
562 return next; | |
563 } | |
564 | |
565 AVCodecParser pnm_parser = { | |
566 { CODEC_ID_PGM, CODEC_ID_PGMYUV, CODEC_ID_PPM, CODEC_ID_PBM}, | |
567 sizeof(ParseContext), | |
568 NULL, | |
569 pnm_parse, | |
570 ff_parse_close, | |
571 }; | |
572 | |
495 AVCodec pgm_encoder = { | 573 AVCodec pgm_encoder = { |
496 "pgm", | 574 "pgm", |
497 CODEC_TYPE_VIDEO, | 575 CODEC_TYPE_VIDEO, |
498 CODEC_ID_PGM, | 576 CODEC_ID_PGM, |
499 sizeof(PNMContext), | 577 sizeof(PNMContext), |