/*
 * DPX parser
 * Copyright (c) 2013 Paul B Mahol
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * DPX parser
 */

#include "libavutil/bswap.h"
#include "parser.h"

typedef struct DPXParseContext {
    ParseContext pc;
    uint32_t index;
    uint32_t fsize;
    uint32_t remaining_size;
    int is_be;
} DPXParseContext;

static int dpx_parse(AVCodecParserContext *s, AVCodecContext *avctx,
                     const uint8_t **poutbuf, int *poutbuf_size,
                     const uint8_t *buf, int buf_size)
{
    DPXParseContext *d = s->priv_data;
    uint32_t state = d->pc.state;
    int next = END_NOT_FOUND;
    int i = 0;

    s->pict_type = AV_PICTURE_TYPE_I;

    *poutbuf_size = 0;
    if (buf_size == 0)
        return 0;

    if (!d->pc.frame_start_found) {
        for (; i < buf_size; i++) {
            state = (state << 8) | buf[i];
            if (state == MKBETAG('S','D','P','X') ||
                state == MKTAG('S','D','P','X')) {
                d->pc.frame_start_found = 1;
                d->is_be = state == MKBETAG('S','D','P','X');
                break;
            }
        }
        d->pc.state = state;
    } else {
        if (d->remaining_size) {
            i = FFMIN(d->remaining_size, buf_size);
            d->remaining_size -= i;
            if (d->remaining_size)
                goto flush;
            next = i;
        }
    }

    for (;d->pc.frame_start_found && i < buf_size; i++) {
        d->pc.state = (d->pc.state << 8) | buf[i];
        if (d->index == 16) {
            d->fsize = d->is_be ? d->pc.state : av_bswap32(d->pc.state);
            if (d->fsize <= 1664) {
                d->index = d->pc.frame_start_found = 0;
                goto flush;
            }
            d->index = 0;
            if (d->fsize > buf_size - i + 19)
                d->remaining_size = d->fsize - buf_size + i - 19;
            else
                next = d->fsize + i - 19;
            break;
        }
        d->index++;
    }

flush:
    if (ff_combine_frame(&d->pc, next, &buf, &buf_size) < 0)
        return buf_size;

    d->index = d->pc.frame_start_found = 0;

    *poutbuf      = buf;
    *poutbuf_size = buf_size;
    return next;
}

AVCodecParser ff_dpx_parser = {
    .codec_ids      = { AV_CODEC_ID_DPX },
    .priv_data_size = sizeof(DPXParseContext),
    .parser_parse   = dpx_parse,
    .parser_close   = ff_parse_close,
};
