static int alloc_buffer(InputStream *ist, FrameBuffer **pbuf)

{

    AVCodecContext *s = ist->st->codec;

    FrameBuffer  *buf = av_mallocz(sizeof(*buf));

    int ret;

    const int pixel_size = av_pix_fmt_descriptors[s->pix_fmt].comp[0].step_minus1+1;

    int h_chroma_shift, v_chroma_shift;

    int edge = 32; // XXX should be avcodec_get_edge_width(), but that fails on svq1

    int w = s->width, h = s->height;



    if (!buf)

        return AVERROR(ENOMEM);



    if (!(s->flags & CODEC_FLAG_EMU_EDGE)) {

        w += 2*edge;

        h += 2*edge;

    }



    avcodec_align_dimensions(s, &w, &h);

    if ((ret = av_image_alloc(buf->base, buf->linesize, w, h,

                              s->pix_fmt, 32)) < 0) {

        av_freep(&buf);

        return ret;

    }

    /* XXX this shouldn't be needed, but some tests break without this line

     * those decoders are buggy and need to be fixed.

     * the following tests fail:

     * bethsoft-vid, cdgraphics, ansi, aasc, fraps-v1, qtrle-1bit

     */

    memset(buf->base[0], 128, ret);



    avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);

    for (int i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {

        const int h_shift = i==0 ? 0 : h_chroma_shift;

        const int v_shift = i==0 ? 0 : v_chroma_shift;

        if (s->flags & CODEC_FLAG_EMU_EDGE)

            buf->data[i] = buf->base[i];

        else

            buf->data[i] = buf->base[i] +

                           FFALIGN((buf->linesize[i]*edge >> v_shift) +

                                   (pixel_size*edge >> h_shift), 32);

    }

    buf->w       = s->width;

    buf->h       = s->height;

    buf->pix_fmt = s->pix_fmt;

    buf->ist     = ist;



    *pbuf = buf;

    return 0;

}
