Commit message: Fix blur coefficient calculation buffer overflow

Found by fuzzer test case id:000082,sig:11,src:002579,op:havoc,rep:8.
Correctness should be checked, but this fixes the overflow for good.
CVE: CVE-2016-7970
CWE: CWE-119
Vulnerability description: Buffer overflow in the calc_coeff function in libass/ass_blur.c in libass before 0.13.4 allows remote attackers to cause a denial of service via unspecified vectors.

Project: libass
File: ass_blur.c

void ass_blur1235_vert_c(int16_t *dst, const int16_t *src,
                         uintptr_t src_width, uintptr_t src_height,
                         const int16_t *param)
{
    uintptr_t dst_height = src_height + 10;
    uintptr_t step = STRIPE_WIDTH * src_height;

    for (uintptr_t x = 0; x < src_width; x += STRIPE_WIDTH) {
        uintptr_t offs = 0;
        for (uintptr_t y = 0; y < dst_height; ++y) {
            const int16_t *p4 = get_line(src, offs - 10 * STRIPE_WIDTH, step);
            const int16_t *p3 = get_line(src, offs -  8 * STRIPE_WIDTH, step);
            const int16_t *p2 = get_line(src, offs -  7 * STRIPE_WIDTH, step);
            const int16_t *p1 = get_line(src, offs -  6 * STRIPE_WIDTH, step);
            const int16_t *z0 = get_line(src, offs -  5 * STRIPE_WIDTH, step);
            const int16_t *n1 = get_line(src, offs -  4 * STRIPE_WIDTH, step);
            const int16_t *n2 = get_line(src, offs -  3 * STRIPE_WIDTH, step);
            const int16_t *n3 = get_line(src, offs -  2 * STRIPE_WIDTH, step);
            const int16_t *n4 = get_line(src, offs -  0 * STRIPE_WIDTH, step);
            for (int k = 0; k < STRIPE_WIDTH; ++k)
                dst[k] = blur_func(p4[k], p3[k], p2[k], p1[k], z0[k],
                                   n1[k], n2[k], n3[k], n4[k], param);
            dst += STRIPE_WIDTH;
            offs += STRIPE_WIDTH;
        }
        src += step;
    }
}

Project: libass
File: ass_blur.c

void ass_pre_blur1_horz_c(int16_t *dst, const int16_t *src,
                          uintptr_t src_width, uintptr_t src_height)
{
    uintptr_t dst_width = src_width + 2;
    uintptr_t size = ((src_width + STRIPE_MASK) & ~STRIPE_MASK) * src_height;
    uintptr_t step = STRIPE_WIDTH * src_height;

    uintptr_t offs = 0;
    int16_t buf[2 * STRIPE_WIDTH];
    int16_t *ptr = buf + STRIPE_WIDTH;
    for (uintptr_t x = 0; x < dst_width; x += STRIPE_WIDTH) {
        for (uintptr_t y = 0; y < src_height; ++y) {
            copy_line(ptr - 1 * STRIPE_WIDTH, src, offs - 1 * step, size);
            copy_line(ptr - 0 * STRIPE_WIDTH, src, offs - 0 * step, size);
            for (int k = 0; k < STRIPE_WIDTH; ++k)
                dst[k] = pre_blur1_func(ptr[k - 2], ptr[k - 1], ptr[k]);
            dst += STRIPE_WIDTH;
            offs += STRIPE_WIDTH;
        }
    }
}

Project: libass

void ass_stripe_pack_c(uint8_t *dst, ptrdiff_t dst_stride, const int16_t *src,
                       uintptr_t width, uintptr_t height)
{
    for (uintptr_t x = 0; x < width; x += STRIPE_WIDTH) {
        uint8_t *ptr = dst;
        for (uintptr_t y = 0; y < height; ++y) {
            const int16_t *dither = dither_line + (y & 1) * STRIPE_WIDTH;
            for (int k = 0; k < STRIPE_WIDTH; ++k)
                ptr[k] = (uint16_t)(src[k] - (src[k] >> 8) + dither[k]) >> 6;
            ptr += dst_stride;
            src += STRIPE_WIDTH;
        }
        dst += STRIPE_WIDTH;
    }
    uintptr_t left = dst_stride - ((width + STRIPE_MASK) & ~STRIPE_MASK);
    for (uintptr_t y = 0; y < height; ++y) {
        for (uintptr_t x = 0; x < left; ++x)
            dst[x] = 0;
        dst += dst_stride;
    }
}

Project: libass
File: ass_blur.c

static inline void expand_func(int16_t *rp, int16_t *rn,
                               int16_t p1, int16_t z0, int16_t n1)
{
    /*
    *rp = (5 * p1 + 10 * z0 + 1 * n1 + 8) >> 4;
    *rn = (1 * p1 + 10 * z0 + 5 * n1 + 8) >> 4;
    */
    uint16_t r = (uint16_t)(((uint16_t)(p1 + n1) >> 1) + z0) >> 1;
    *rp = (uint16_t)(((uint16_t)(r + p1) >> 1) + z0 + 1) >> 1;
    *rn = (uint16_t)(((uint16_t)(r + n1) >> 1) + z0 + 1) >> 1;
}

Project: libass
File: ass_blur.c

inline static const int16_t *get_line(const int16_t *ptr, uintptr_t offs, uintptr_t size)
{
    return offs < size ? ptr + offs : zero_line;
}