static int xpm_decode_frame(AVCodecContext *avctx, void *data,

                            int *got_frame, AVPacket *avpkt)

{

    XPMDecContext *x = avctx->priv_data;

    AVFrame *p=data;

    const uint8_t *end, *ptr = avpkt->data;

    int ncolors, cpp, ret, i, j;

    int64_t size;

    uint32_t *dst;



    avctx->pix_fmt = AV_PIX_FMT_BGRA;



    end = avpkt->data + avpkt->size;

    while (memcmp(ptr, "/* XPM */\n", 10) && ptr < end - 10)

        ptr++;



    if (ptr >= end) {

        av_log(avctx, AV_LOG_ERROR, "missing signature\n");

        return AVERROR_INVALIDDATA;

    }



    ptr += mod_strcspn(ptr, "\"");

    if (sscanf(ptr, "\"%u %u %u %u\",",

               &avctx->width, &avctx->height, &ncolors, &cpp) != 4) {

        av_log(avctx, AV_LOG_ERROR, "missing image parameters\n");

        return AVERROR_INVALIDDATA;

    }



    if ((ret = ff_set_dimensions(avctx, avctx->width, avctx->height)) < 0)

        return ret;



    if ((ret = ff_get_buffer(avctx, p, 0)) < 0)

        return ret;



    if (cpp <= 0 || cpp >= 5) {

        av_log(avctx, AV_LOG_ERROR, "unsupported/invalid number of chars per pixel: %d\n", cpp);

        return AVERROR_INVALIDDATA;

    }



    size = 1;

    for (i = 0; i < cpp; i++)

        size *= 94;



    if (ncolors <= 0 || ncolors > size) {

        av_log(avctx, AV_LOG_ERROR, "invalid number of colors: %d\n", ncolors);

        return AVERROR_INVALIDDATA;

    }



    size *= 4;



    av_fast_padded_malloc(&x->pixels, &x->pixels_size, size);

    if (!x->pixels)

        return AVERROR(ENOMEM);



    ptr += mod_strcspn(ptr, ",") + 1;

    for (i = 0; i < ncolors; i++) {

        const uint8_t *index;

        int len;



        ptr += mod_strcspn(ptr, "\"") + 1;

        if (ptr + cpp > end)

            return AVERROR_INVALIDDATA;

        index = ptr;

        ptr += cpp;



        ptr = strstr(ptr, "c ");

        if (ptr) {

            ptr += 2;

        } else {

            return AVERROR_INVALIDDATA;

        }



        len = strcspn(ptr, "\" ");



        if ((ret = ascii2index(index, cpp)) < 0)

            return ret;



        x->pixels[ret] = color_string_to_rgba(ptr, len);

        ptr += mod_strcspn(ptr, ",") + 1;

    }



    for (i = 0; i < avctx->height; i++) {

        dst = (uint32_t *)(p->data[0] + i * p->linesize[0]);

        ptr += mod_strcspn(ptr, "\"") + 1;



        for (j = 0; j < avctx->width; j++) {

            if (ptr + cpp > end)

                return AVERROR_INVALIDDATA;



            if ((ret = ascii2index(ptr, cpp)) < 0)

                return ret;



            *dst++ = x->pixels[ret];

            ptr += cpp;

        }

        ptr += mod_strcspn(ptr, ",") + 1;

    }



    p->key_frame = 1;

    p->pict_type = AV_PICTURE_TYPE_I;



    *got_frame = 1;



    return avpkt->size;

}
