Libav
|
00001 /* 00002 * PNM image parser 00003 * Copyright (c) 2002, 2003 Fabrice Bellard 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 #include "parser.h" //for ParseContext 00023 #include "pnm.h" 00024 00025 00026 static int pnm_parse(AVCodecParserContext *s, AVCodecContext *avctx, 00027 const uint8_t **poutbuf, int *poutbuf_size, 00028 const uint8_t *buf, int buf_size) 00029 { 00030 ParseContext *pc = s->priv_data; 00031 PNMContext pnmctx; 00032 int next; 00033 00034 for (; pc->overread > 0; pc->overread--) { 00035 pc->buffer[pc->index++]= pc->buffer[pc->overread_index++]; 00036 } 00037 retry: 00038 if (pc->index) { 00039 pnmctx.bytestream_start = 00040 pnmctx.bytestream = pc->buffer; 00041 pnmctx.bytestream_end = pc->buffer + pc->index; 00042 } else { 00043 pnmctx.bytestream_start = 00044 pnmctx.bytestream = (uint8_t *) buf; /* casts avoid warnings */ 00045 pnmctx.bytestream_end = (uint8_t *) buf + buf_size; 00046 } 00047 if (ff_pnm_decode_header(avctx, &pnmctx) < 0) { 00048 if (pnmctx.bytestream < pnmctx.bytestream_end) { 00049 if (pc->index) { 00050 pc->index = 0; 00051 } else { 00052 buf++; 00053 buf_size--; 00054 } 00055 goto retry; 00056 } 00057 #if 0 00058 if (pc->index && pc->index * 2 + FF_INPUT_BUFFER_PADDING_SIZE < pc->buffer_size && buf_size > pc->index) { 00059 memcpy(pc->buffer + pc->index, buf, pc->index); 00060 pc->index += pc->index; 00061 buf += pc->index; 00062 buf_size -= pc->index; 00063 goto retry; 00064 } 00065 #endif 00066 next = END_NOT_FOUND; 00067 } else { 00068 next = pnmctx.bytestream - pnmctx.bytestream_start 00069 + avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); 00070 if (pnmctx.bytestream_start != buf) 00071 next -= pc->index; 00072 if (next > buf_size) 00073 next = END_NOT_FOUND; 00074 } 00075 00076 if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { 00077 *poutbuf = NULL; 00078 *poutbuf_size = 0; 00079 return buf_size; 00080 } 00081 *poutbuf = buf; 00082 *poutbuf_size = buf_size; 00083 return next; 00084 } 00085 00086 AVCodecParser pnm_parser = { 00087 { CODEC_ID_PGM, CODEC_ID_PGMYUV, CODEC_ID_PPM, CODEC_ID_PBM, CODEC_ID_PAM}, 00088 sizeof(ParseContext), 00089 NULL, 00090 pnm_parse, 00091 ff_parse_close, 00092 };