void avfilter_destroy(AVFilterContext *filter)

{

    int i;

    if(filter->filter->uninit)

        filter->filter->uninit(filter);

    for(i = 0; i < filter->input_count; i ++) {

        if(filter->inputs[i]) {

            filter->inputs[i]->src->outputs[filter->inputs[i]->srcpad] = NULL;

            avfilter_formats_unref(&filter->inputs[i]->in_formats);

            avfilter_formats_unref(&filter->inputs[i]->out_formats);

        }

        av_freep(&filter->inputs[i]);

    }

    for(i = 0; i < filter->output_count; i ++) {

        if(filter->outputs[i]) {

            if (filter->outputs[i]->dst)

            filter->outputs[i]->dst->inputs[filter->outputs[i]->dstpad] = NULL;

            avfilter_formats_unref(&filter->outputs[i]->in_formats);

            avfilter_formats_unref(&filter->outputs[i]->out_formats);

        }

        av_freep(&filter->outputs[i]);

    }

    av_freep(&filter->name);

    av_freep(&filter->input_pads);

    av_freep(&filter->output_pads);

    av_freep(&filter->inputs);

    av_freep(&filter->outputs);

    av_freep(&filter->priv);

    av_free(filter);

}


void usb_desc_create_serial(USBDevice *dev)

{

    DeviceState *hcd = dev->qdev.parent_bus->parent;

    const USBDesc *desc = usb_device_get_usb_desc(dev);

    int index = desc->id.iSerialNumber;

    char serial[64];

    char *path;

    int dst;

    if (dev->serial) {

        /* 'serial' usb bus property has priority if present */

        usb_desc_set_string(dev, index, dev->serial);

        return;

    }

    assert(index != 0 && desc->str[index] != NULL);

    dst = snprintf(serial, sizeof(serial), "%s", desc->str[index]);

    path = qdev_get_dev_path(hcd);

    if (path) {

        dst += snprintf(serial+dst, sizeof(serial)-dst, "-%s", path);

    }

    dst += snprintf(serial+dst, sizeof(serial)-dst, "-%s", dev->port->path);

    usb_desc_set_string(dev, index, serial);

}


const char *qdict_get_str(const QDict *qdict, const char *key)

{

    QObject *obj = qdict_get_obj(qdict, key, QTYPE_QSTRING);

    return qstring_get_str(qobject_to_qstring(obj));

}


static int get_coc(J2kDecoderContext *s, J2kCodingStyle *c, uint8_t *properties)

{

    int compno;

    if (s->buf_end - s->buf < 2)

        return AVERROR(EINVAL);

    compno = bytestream_get_byte(&s->buf);

    c += compno;

    c->csty = bytestream_get_byte(&s->buf);

    get_cox(s, c);

    properties[compno] |= HAD_COC;

    return 0;

}


static void FUNC(put_hevc_qpel_bi_w_hv)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,

                                        int16_t *src2,

                                        int height, int denom, int wx0, int wx1,

                                        int ox0, int ox1, intptr_t mx, intptr_t my, int width)

{

    int x, y;

    const int8_t *filter;

    pixel *src = (pixel*)_src;

    ptrdiff_t srcstride = _srcstride / sizeof(pixel);

    pixel *dst          = (pixel *)_dst;

    ptrdiff_t dststride = _dststride / sizeof(pixel);

    int16_t tmp_array[(MAX_PB_SIZE + QPEL_EXTRA) * MAX_PB_SIZE];

    int16_t *tmp = tmp_array;

    int shift = 14 + 1 - BIT_DEPTH;

    int log2Wd = denom + shift - 1;

    src   -= QPEL_EXTRA_BEFORE * srcstride;

    filter = ff_hevc_qpel_filters[mx - 1];

    for (y = 0; y < height + QPEL_EXTRA; y++) {

        for (x = 0; x < width; x++)

            tmp[x] = QPEL_FILTER(src, 1) >> (BIT_DEPTH - 8);

        src += srcstride;

        tmp += MAX_PB_SIZE;

    }

    tmp    = tmp_array + QPEL_EXTRA_BEFORE * MAX_PB_SIZE;

    filter = ff_hevc_qpel_filters[my - 1];

    ox0     = ox0 * (1 << (BIT_DEPTH - 8));

    ox1     = ox1 * (1 << (BIT_DEPTH - 8));

    for (y = 0; y < height; y++) {

        for (x = 0; x < width; x++)

            dst[x] = av_clip_pixel(((QPEL_FILTER(tmp, MAX_PB_SIZE) >> 6) * wx1 + src2[x] * wx0 +

                                    ((ox0 + ox1 + 1) << log2Wd)) >> (log2Wd + 1));

        tmp  += MAX_PB_SIZE;

        dst  += dststride;

        src2 += MAX_PB_SIZE;

    }

}


int bdrv_flush(BlockDriverState *bs)

{

    Coroutine *co;

    FlushCo flush_co = {

        .bs = bs,

        .ret = NOT_DONE,

    };

    if (qemu_in_coroutine()) {

        /* Fast-path if already in coroutine context */

        bdrv_flush_co_entry(&flush_co);

    } else {

        co = qemu_coroutine_create(bdrv_flush_co_entry, &flush_co);

        qemu_coroutine_enter(co);

        BDRV_POLL_WHILE(bs, flush_co.ret == NOT_DONE);

    }

    return flush_co.ret;

}


void scsi_req_complete(SCSIRequest *req)

{

    assert(req->status != -1);

    scsi_req_ref(req);

    scsi_req_dequeue(req);

    req->bus->ops->complete(req->bus, SCSI_REASON_DONE,

                            req->tag,

                            req->status);

    scsi_req_unref(req);

}


static void iv_Decode_Chunk(Indeo3DecodeContext *s,

        uint8_t *cur, uint8_t *ref, int width, int height,

        const uint8_t *buf1, long cb_offset, const uint8_t *hdr,

        const uint8_t *buf2, int min_width_160)

{

    uint8_t bit_buf;

    unsigned long bit_pos, lv, lv1, lv2;

    long *width_tbl, width_tbl_arr[10];

    const signed char *ref_vectors;

    uint8_t *cur_frm_pos, *ref_frm_pos, *cp, *cp2;

    uint32_t *cur_lp, *ref_lp;

    const uint32_t *correction_lp[2], *correctionloworder_lp[2], *correctionhighorder_lp[2];

    uint8_t *correction_type_sp[2];

    struct ustr strip_tbl[20], *strip;

    int i, j, k, lp1, lp2, flag1, cmd, blks_width, blks_height, region_160_width,

        rle_v1, rle_v2, rle_v3;

    unsigned short res;

    bit_buf = 0;

    ref_vectors = NULL;

    width_tbl = width_tbl_arr + 1;

    i = (width < 0 ? width + 3 : width)/4;

    for(j = -1; j < 8; j++)

        width_tbl[j] = i * j;

    strip = strip_tbl;

    for(region_160_width = 0; region_160_width < (width - min_width_160); region_160_width += min_width_160);

    strip->ypos = strip->xpos = 0;

    for(strip->width = min_width_160; width > strip->width; strip->width *= 2);

    strip->height = height;

    strip->split_direction = 0;

    strip->split_flag = 0;

    strip->usl7 = 0;

    bit_pos = 0;

    rle_v1 = rle_v2 = rle_v3 = 0;

    while(strip >= strip_tbl) {

        if(bit_pos <= 0) {

            bit_pos = 8;

            bit_buf = *buf1++;

        bit_pos -= 2;

        cmd = (bit_buf >> bit_pos) & 0x03;

        if(cmd == 0) {

            strip++;

            memcpy(strip, strip-1, sizeof(*strip));

            strip->split_flag = 1;

            strip->split_direction = 0;

            strip->height = (strip->height > 8 ? ((strip->height+8)>>4)<<3 : 4);

            continue;

        } else if(cmd == 1) {

            strip++;

            memcpy(strip, strip-1, sizeof(*strip));

            strip->split_flag = 1;

            strip->split_direction = 1;

            strip->width = (strip->width > 8 ? ((strip->width+8)>>4)<<3 : 4);

            continue;

        } else if(cmd == 2) {

            if(strip->usl7 == 0) {

                strip->usl7 = 1;

                ref_vectors = NULL;

                continue;

        } else if(cmd == 3) {

            if(strip->usl7 == 0) {

                strip->usl7 = 1;

                ref_vectors = (const signed char*)buf2 + (*buf1 * 2);

                buf1++;

                continue;

        cur_frm_pos = cur + width * strip->ypos + strip->xpos;

        if((blks_width = strip->width) < 0)

            blks_width += 3;

        blks_width >>= 2;

        blks_height = strip->height;

        if(ref_vectors != NULL) {

            ref_frm_pos = ref + (ref_vectors[0] + strip->ypos) * width +

                ref_vectors[1] + strip->xpos;

        } else

            ref_frm_pos = cur_frm_pos - width_tbl[4];

        if(cmd == 2) {

            if(bit_pos <= 0) {

                bit_pos = 8;

                bit_buf = *buf1++;

            bit_pos -= 2;

            cmd = (bit_buf >> bit_pos) & 0x03;

            if(cmd == 0 || ref_vectors != NULL) {

                for(lp1 = 0; lp1 < blks_width; lp1++) {

                    for(i = 0, j = 0; i < blks_height; i++, j += width_tbl[1])

                        ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)ref_frm_pos)[j];

                    cur_frm_pos += 4;

                    ref_frm_pos += 4;

            } else if(cmd != 1)

                return;

        } else {

            k = *buf1 >> 4;

            j = *buf1 & 0x0f;

            buf1++;

            lv = j + cb_offset;

            if((lv - 8) <= 7 && (k == 0 || k == 3 || k == 10)) {

                cp2 = s->ModPred + ((lv - 8) << 7);

                cp = ref_frm_pos;

                for(i = 0; i < blks_width << 2; i++) {

                    int v = *cp >> 1;

                    *(cp++) = cp2[v];

            if(k == 1 || k == 4) {

                lv = (hdr[j] & 0xf) + cb_offset;

                correction_type_sp[0] = s->corrector_type + (lv << 8);

                correction_lp[0] = correction + (lv << 8);

                lv = (hdr[j] >> 4) + cb_offset;

                correction_lp[1] = correction + (lv << 8);

                correction_type_sp[1] = s->corrector_type + (lv << 8);

            } else {

                correctionloworder_lp[0] = correctionloworder_lp[1] = correctionloworder + (lv << 8);

                correctionhighorder_lp[0] = correctionhighorder_lp[1] = correctionhighorder + (lv << 8);

                correction_type_sp[0] = correction_type_sp[1] = s->corrector_type + (lv << 8);

                correction_lp[0] = correction_lp[1] = correction + (lv << 8);

            switch(k) {

            case 1:

            case 0:                    /********** CASE 0 **********/

                for( ; blks_height > 0; blks_height -= 4) {

                    for(lp1 = 0; lp1 < blks_width; lp1++) {

                        for(lp2 = 0; lp2 < 4; ) {

                            k = *buf1++;

                            cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2];

                            ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2];

                            switch(correction_type_sp[0][k]) {

                            case 0:

                                *cur_lp = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);

                                lp2++;

                            case 1:

                                res = ((le2me_16(((unsigned short *)(ref_lp))[0]) >> 1) + correction_lp[lp2 & 0x01][*buf1]) << 1;

                                ((unsigned short *)cur_lp)[0] = le2me_16(res);

                                res = ((le2me_16(((unsigned short *)(ref_lp))[1]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1;

                                ((unsigned short *)cur_lp)[1] = le2me_16(res);

                                buf1++;

                                lp2++;

                            case 2:

                                if(lp2 == 0) {

                                    for(i = 0, j = 0; i < 2; i++, j += width_tbl[1])

                                        cur_lp[j] = ref_lp[j];

                                    lp2 += 2;

                            case 3:

                                if(lp2 < 2) {

                                    for(i = 0, j = 0; i < (3 - lp2); i++, j += width_tbl[1])

                                        cur_lp[j] = ref_lp[j];

                                    lp2 = 3;

                            case 8:

                                if(lp2 == 0) {

                                    RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)

                                    if(rle_v1 == 1 || ref_vectors != NULL) {

                                        for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])

                                            cur_lp[j] = ref_lp[j];

                                    RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)

                                } else {

                                    rle_v1 = 1;

                                    rle_v2 = *buf1 - 1;

                            case 5:

                                LP2_CHECK(buf1,rle_v3,lp2)

                            case 4:

                                for(i = 0, j = 0; i < (4 - lp2); i++, j += width_tbl[1])

                                    cur_lp[j] = ref_lp[j];

                                lp2 = 4;

                            case 7:

                                if(rle_v3 != 0)

                                    rle_v3 = 0;

                                else {

                                    buf1--;

                                    rle_v3 = 1;

                            case 6:

                                if(ref_vectors != NULL) {

                                    for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])

                                        cur_lp[j] = ref_lp[j];

                                lp2 = 4;

                            case 9:

                                lv1 = *buf1++;

                                lv = (lv1 & 0x7F) << 1;

                                lv += (lv << 8);

                                lv += (lv << 16);

                                for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])

                                    cur_lp[j] = lv;

                                LV1_CHECK(buf1,rle_v3,lv1,lp2)

                            default:

                                return;

                        cur_frm_pos += 4;

                        ref_frm_pos += 4;

                    cur_frm_pos += ((width - blks_width) * 4);

                    ref_frm_pos += ((width - blks_width) * 4);

            case 4:

            case 3:                    /********** CASE 3 **********/

                if(ref_vectors != NULL)

                    return;

                flag1 = 1;

                for( ; blks_height > 0; blks_height -= 8) {

                    for(lp1 = 0; lp1 < blks_width; lp1++) {

                        for(lp2 = 0; lp2 < 4; ) {

                            k = *buf1++;

                            cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];

                            ref_lp = ((uint32_t *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1];

                            switch(correction_type_sp[lp2 & 0x01][k]) {

                            case 0:

                                cur_lp[width_tbl[1]] = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);

                                if(lp2 > 0 || flag1 == 0 || strip->ypos != 0)

                                    cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;

                                else

                                    cur_lp[0] = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);

                                lp2++;

                            case 1:

                                res = ((le2me_16(((unsigned short *)ref_lp)[0]) >> 1) + correction_lp[lp2 & 0x01][*buf1]) << 1;

                                ((unsigned short *)cur_lp)[width_tbl[2]] = le2me_16(res);

                                res = ((le2me_16(((unsigned short *)ref_lp)[1]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1;

                                ((unsigned short *)cur_lp)[width_tbl[2]+1] = le2me_16(res);

                                if(lp2 > 0 || flag1 == 0 || strip->ypos != 0)

                                    cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;

                                else

                                    cur_lp[0] = cur_lp[width_tbl[1]];

                                buf1++;

                                lp2++;

                            case 2:

                                if(lp2 == 0) {

                                    for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])

                                        cur_lp[j] = *ref_lp;

                                    lp2 += 2;

                            case 3:

                                if(lp2 < 2) {

                                    for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1])

                                        cur_lp[j] = *ref_lp;

                                    lp2 = 3;

                            case 6:

                                lp2 = 4;

                            case 7:

                                if(rle_v3 != 0)

                                    rle_v3 = 0;

                                else {

                                    buf1--;

                                    rle_v3 = 1;

                                lp2 = 4;

                            case 8:

                                if(lp2 == 0) {

                                    RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)

                                    if(rle_v1 == 1) {

                                        for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])

                                            cur_lp[j] = ref_lp[j];

                                    RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)

                                } else {

                                    rle_v2 = (*buf1) - 1;

                                    rle_v1 = 1;

                            case 5:

                                LP2_CHECK(buf1,rle_v3,lp2)

                            case 4:

                                for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1])

                                    cur_lp[j] = *ref_lp;

                                lp2 = 4;

                            case 9:

                                av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");

                                lv1 = *buf1++;

                                lv = (lv1 & 0x7F) << 1;

                                lv += (lv << 8);

                                lv += (lv << 16);

                                for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])

                                    cur_lp[j] = lv;

                                LV1_CHECK(buf1,rle_v3,lv1,lp2)

                            default:

                                return;

                        cur_frm_pos += 4;

                    cur_frm_pos += (((width * 2) - blks_width) * 4);

                    flag1 = 0;

            case 10:                    /********** CASE 10 **********/

                if(ref_vectors == NULL) {

                    flag1 = 1;

                    for( ; blks_height > 0; blks_height -= 8) {

                        for(lp1 = 0; lp1 < blks_width; lp1 += 2) {

                            for(lp2 = 0; lp2 < 4; ) {

                                k = *buf1++;

                                cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];

                                ref_lp = ((uint32_t *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1];

                                lv1 = ref_lp[0];

                                lv2 = ref_lp[1];

                                if(lp2 == 0 && flag1 != 0) {

#ifdef WORDS_BIGENDIAN

                                    lv1 = lv1 & 0xFF00FF00;

                                    lv1 = (lv1 >> 8) | lv1;

                                    lv2 = lv2 & 0xFF00FF00;

                                    lv2 = (lv2 >> 8) | lv2;

#else

                                    lv1 = lv1 & 0x00FF00FF;

                                    lv1 = (lv1 << 8) | lv1;

                                    lv2 = lv2 & 0x00FF00FF;

                                    lv2 = (lv2 << 8) | lv2;

#endif

                                switch(correction_type_sp[lp2 & 0x01][k]) {

                                case 0:

                                    cur_lp[width_tbl[1]] = le2me_32(((le2me_32(lv1) >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1);

                                    cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(lv2) >> 1) + correctionhighorder_lp[lp2 & 0x01][k]) << 1);

                                    if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) {

                                        cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;

                                        cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;

                                    } else {

                                        cur_lp[0] = cur_lp[width_tbl[1]];

                                        cur_lp[1] = cur_lp[width_tbl[1]+1];

                                    lp2++;

                                case 1:

                                    cur_lp[width_tbl[1]] = le2me_32(((le2me_32(lv1) >> 1) + correctionloworder_lp[lp2 & 0x01][*buf1]) << 1);

                                    cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(lv2) >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1);

                                    if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) {

                                        cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;

                                        cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;

                                    } else {

                                        cur_lp[0] = cur_lp[width_tbl[1]];

                                        cur_lp[1] = cur_lp[width_tbl[1]+1];

                                    buf1++;

                                    lp2++;

                                case 2:

                                    if(lp2 == 0) {

                                        if(flag1 != 0) {

                                            for(i = 0, j = width_tbl[1]; i < 3; i++, j += width_tbl[1]) {

                                                cur_lp[j] = lv1;

                                                cur_lp[j+1] = lv2;

                                            cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;

                                            cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;

                                        } else {

                                            for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) {

                                                cur_lp[j] = lv1;

                                                cur_lp[j+1] = lv2;

                                        lp2 += 2;

                                case 3:

                                    if(lp2 < 2) {

                                        if(lp2 == 0 && flag1 != 0) {

                                            for(i = 0, j = width_tbl[1]; i < 5; i++, j += width_tbl[1]) {

                                                cur_lp[j] = lv1;

                                                cur_lp[j+1] = lv2;

                                            cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;

                                            cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;

                                        } else {

                                            for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) {

                                                cur_lp[j] = lv1;

                                                cur_lp[j+1] = lv2;

                                        lp2 = 3;

                                case 8:

                                    if(lp2 == 0) {

                                        RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)

                                        if(rle_v1 == 1) {

                                            if(flag1 != 0) {

                                                for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) {

                                                    cur_lp[j] = lv1;

                                                    cur_lp[j+1] = lv2;

                                                cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;

                                                cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;

                                            } else {

                                                for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) {

                                                    cur_lp[j] = lv1;

                                                    cur_lp[j+1] = lv2;

                                        RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)

                                    } else {

                                        rle_v1 = 1;

                                        rle_v2 = (*buf1) - 1;

                                case 5:

                                    LP2_CHECK(buf1,rle_v3,lp2)

                                case 4:

                                    if(lp2 == 0 && flag1 != 0) {

                                        for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) {

                                            cur_lp[j] = lv1;

                                            cur_lp[j+1] = lv2;

                                        cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;

                                        cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;

                                    } else {

                                        for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) {

                                            cur_lp[j] = lv1;

                                            cur_lp[j+1] = lv2;

                                    lp2 = 4;

                                case 6:

                                    lp2 = 4;

                                case 7:

                                    if(lp2 == 0) {

                                        if(rle_v3 != 0)

                                            rle_v3 = 0;

                                        else {

                                            buf1--;

                                            rle_v3 = 1;

                                        lp2 = 4;

                                case 9:

                                    av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");

                                    lv1 = *buf1;

                                    lv = (lv1 & 0x7F) << 1;

                                    lv += (lv << 8);

                                    lv += (lv << 16);

                                    for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])

                                        cur_lp[j] = lv;

                                    LV1_CHECK(buf1,rle_v3,lv1,lp2)

                                default:

                                    return;

                            cur_frm_pos += 8;

                        cur_frm_pos += (((width * 2) - blks_width) * 4);

                        flag1 = 0;

                } else {

                    for( ; blks_height > 0; blks_height -= 8) {

                        for(lp1 = 0; lp1 < blks_width; lp1 += 2) {

                            for(lp2 = 0; lp2 < 4; ) {

                                k = *buf1++;

                                cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];

                                ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2 * 2];

                                switch(correction_type_sp[lp2 & 0x01][k]) {

                                case 0:

                                    lv1 = correctionloworder_lp[lp2 & 0x01][k];

                                    lv2 = correctionhighorder_lp[lp2 & 0x01][k];

                                    cur_lp[0] = le2me_32(((le2me_32(ref_lp[0]) >> 1) + lv1) << 1);

                                    cur_lp[1] = le2me_32(((le2me_32(ref_lp[1]) >> 1) + lv2) << 1);

                                    cur_lp[width_tbl[1]] = le2me_32(((le2me_32(ref_lp[width_tbl[1]]) >> 1) + lv1) << 1);

                                    cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(ref_lp[width_tbl[1]+1]) >> 1) + lv2) << 1);

                                    lp2++;

                                case 1:

                                    lv1 = correctionloworder_lp[lp2 & 0x01][*buf1++];

                                    lv2 = correctionloworder_lp[lp2 & 0x01][k];

                                    cur_lp[0] = le2me_32(((le2me_32(ref_lp[0]) >> 1) + lv1) << 1);

                                    cur_lp[1] = le2me_32(((le2me_32(ref_lp[1]) >> 1) + lv2) << 1);

                                    cur_lp[width_tbl[1]] = le2me_32(((le2me_32(ref_lp[width_tbl[1]]) >> 1) + lv1) << 1);

                                    cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(ref_lp[width_tbl[1]+1]) >> 1) + lv2) << 1);

                                    lp2++;

                                case 2:

                                    if(lp2 == 0) {

                                        for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) {

                                            cur_lp[j] = ref_lp[j];

                                            cur_lp[j+1] = ref_lp[j+1];

                                        lp2 += 2;

                                case 3:

                                    if(lp2 < 2) {

                                        for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) {

                                            cur_lp[j] = ref_lp[j];

                                            cur_lp[j+1] = ref_lp[j+1];

                                        lp2 = 3;

                                case 8:

                                    if(lp2 == 0) {

                                        RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)

                                        for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) {

                                            ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)ref_frm_pos)[j];

                                            ((uint32_t *)cur_frm_pos)[j+1] = ((uint32_t *)ref_frm_pos)[j+1];

                                        RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)

                                    } else {

                                        rle_v1 = 1;

                                        rle_v2 = (*buf1) - 1;

                                case 5:

                                case 7:

                                    LP2_CHECK(buf1,rle_v3,lp2)

                                case 6:

                                case 4:

                                    for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) {

                                        cur_lp[j] = ref_lp[j];

                                        cur_lp[j+1] = ref_lp[j+1];

                                    lp2 = 4;

                                case 9:

                                    av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");

                                    lv1 = *buf1;

                                    lv = (lv1 & 0x7F) << 1;

                                    lv += (lv << 8);

                                    lv += (lv << 16);

                                    for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])

                                        ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)cur_frm_pos)[j+1] = lv;

                                    LV1_CHECK(buf1,rle_v3,lv1,lp2)

                                default:

                                    return;

                            cur_frm_pos += 8;

                            ref_frm_pos += 8;

                        cur_frm_pos += (((width * 2) - blks_width) * 4);

                        ref_frm_pos += (((width * 2) - blks_width) * 4);

            case 11:                    /********** CASE 11 **********/

                if(ref_vectors == NULL)

                    return;

                for( ; blks_height > 0; blks_height -= 8) {

                    for(lp1 = 0; lp1 < blks_width; lp1++) {

                        for(lp2 = 0; lp2 < 4; ) {

                            k = *buf1++;

                            cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];

                            ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2 * 2];

                            switch(correction_type_sp[lp2 & 0x01][k]) {

                            case 0:

                                cur_lp[0] = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);

                                cur_lp[width_tbl[1]] = le2me_32(((le2me_32(ref_lp[width_tbl[1]]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);

                                lp2++;

                            case 1:

                                lv1 = (unsigned short)(correction_lp[lp2 & 0x01][*buf1++]);

                                lv2 = (unsigned short)(correction_lp[lp2 & 0x01][k]);

                                res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[0]) >> 1) + lv1) << 1);

                                ((unsigned short *)cur_lp)[0] = le2me_16(res);

                                res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[1]) >> 1) + lv2) << 1);

                                ((unsigned short *)cur_lp)[1] = le2me_16(res);

                                res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[width_tbl[2]]) >> 1) + lv1) << 1);

                                ((unsigned short *)cur_lp)[width_tbl[2]] = le2me_16(res);

                                res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[width_tbl[2]+1]) >> 1) + lv2) << 1);

                                ((unsigned short *)cur_lp)[width_tbl[2]+1] = le2me_16(res);

                                lp2++;

                            case 2:

                                if(lp2 == 0) {

                                    for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])

                                        cur_lp[j] = ref_lp[j];

                                    lp2 += 2;

                            case 3:

                                if(lp2 < 2) {

                                    for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1])

                                        cur_lp[j] = ref_lp[j];

                                    lp2 = 3;

                            case 8:

                                if(lp2 == 0) {

                                    RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)

                                    for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])

                                        cur_lp[j] = ref_lp[j];

                                    RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)

                                } else {

                                    rle_v1 = 1;

                                    rle_v2 = (*buf1) - 1;

                            case 5:

                            case 7:

                                LP2_CHECK(buf1,rle_v3,lp2)

                            case 4:

                            case 6:

                                for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1])

                                    cur_lp[j] = ref_lp[j];

                                lp2 = 4;

                            case 9:

                                av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");

                                lv1 = *buf1++;

                                lv = (lv1 & 0x7F) << 1;

                                lv += (lv << 8);

                                lv += (lv << 16);

                                for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])

                                    cur_lp[j] = lv;

                                LV1_CHECK(buf1,rle_v3,lv1,lp2)

                            default:

                                return;

                        cur_frm_pos += 4;

                        ref_frm_pos += 4;

                    cur_frm_pos += (((width * 2) - blks_width) * 4);

                    ref_frm_pos += (((width * 2) - blks_width) * 4);

            default:

                return;

        if(strip < strip_tbl)

            return;

        for( ; strip >= strip_tbl; strip--) {

            if(strip->split_flag != 0) {

                strip->split_flag = 0;

                strip->usl7 = (strip-1)->usl7;

                if(strip->split_direction) {

                    strip->xpos += strip->width;

                    strip->width = (strip-1)->width - strip->width;

                    if(region_160_width <= strip->xpos && width < strip->width + strip->xpos)

                        strip->width = width - strip->xpos;

                } else {

                    strip->ypos += strip->height;

                    strip->height = (strip-1)->height - strip->height;


static av_always_inline void get_mvdata_interlaced(VC1Context *v, int *dmv_x,

                                                   int *dmv_y, int *pred_flag)

{

    int index, index1;

    int extend_x = 0, extend_y = 0;

    GetBitContext *gb = &v->s.gb;

    int bits, esc;

    int val, sign;

    const int* offs_tab;

    if (v->numref) {

        bits = VC1_2REF_MVDATA_VLC_BITS;

        esc  = 125;

    } else {

        bits = VC1_1REF_MVDATA_VLC_BITS;

        esc  = 71;

    }

    switch (v->dmvrange) {

    case 1:

        extend_x = 1;

        break;

    case 2:

        extend_y = 1;

        break;

    case 3:

        extend_x = extend_y = 1;

        break;

    }

    index = get_vlc2(gb, v->imv_vlc->table, bits, 3);

    if (index == esc) {

        *dmv_x = get_bits(gb, v->k_x);

        *dmv_y = get_bits(gb, v->k_y);

        if (v->numref) {

            *pred_flag = *dmv_y & 1;

            *dmv_y     = (*dmv_y + *pred_flag) >> 1;

        }

    }

    else {

        if (extend_x)

            offs_tab = offset_table2;

        else

            offs_tab = offset_table1;

        index1 = (index + 1) % 9;

        if (index1 != 0) {

            val    = get_bits(gb, index1 + extend_x);

            sign   = 0 -(val & 1);

            *dmv_x = (sign ^ ((val >> 1) + offs_tab[index1])) - sign;

        } else

            *dmv_x = 0;

        if (extend_y)

            offs_tab = offset_table2;

        else

            offs_tab = offset_table1;

        index1 = (index + 1) / 9;

        if (index1 > v->numref) {

            val    = get_bits(gb, (index1 + (extend_y << v->numref)) >> v->numref);

            sign   = 0 - (val & 1);

            *dmv_y = (sign ^ ((val >> 1) + offs_tab[index1 >> v->numref])) - sign;

        } else

            *dmv_y = 0;

        if (v->numref)

            *pred_flag = index1 & 1;

    }

}


static int alloc_buffers(AVCodecContext *avctx)

{

    CFHDContext *s = avctx->priv_data;

    int i, j, k, ret, planes;

    if ((ret = ff_set_dimensions(avctx, s->coded_width, s->coded_height)) < 0)

        return ret;

    avctx->pix_fmt = s->coded_format;

    avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift);

    planes = av_pix_fmt_count_planes(avctx->pix_fmt);

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

        int width = i ? avctx->width >> s->chroma_x_shift : avctx->width;

        int height = i ? avctx->height >> s->chroma_y_shift : avctx->height;

        int stride = FFALIGN(width / 8, 8) * 8;

        int w8, h8, w4, h4, w2, h2;

        height = FFALIGN(height / 8, 2) * 8;

        s->plane[i].width = width;

        s->plane[i].height = height;

        s->plane[i].stride = stride;

        w8 = FFALIGN(s->plane[i].width / 8, 8);

        h8 = FFALIGN(s->plane[i].height / 8, 2);

        w4 = w8 * 2;

        h4 = h8 * 2;

        w2 = w4 * 2;

        h2 = h4 * 2;

        s->plane[i].idwt_buf = av_malloc_array(height * stride, sizeof(*s->plane[i].idwt_buf));

        s->plane[i].idwt_tmp = av_malloc_array(height * stride, sizeof(*s->plane[i].idwt_tmp));

        if (!s->plane[i].idwt_buf || !s->plane[i].idwt_tmp) {

            return AVERROR(ENOMEM);

        }

        s->plane[i].subband[0] = s->plane[i].idwt_buf;

        s->plane[i].subband[1] = s->plane[i].idwt_buf + 2 * w8 * h8;

        s->plane[i].subband[2] = s->plane[i].idwt_buf + 1 * w8 * h8;

        s->plane[i].subband[3] = s->plane[i].idwt_buf + 3 * w8 * h8;

        s->plane[i].subband[4] = s->plane[i].idwt_buf + 2 * w4 * h4;

        s->plane[i].subband[5] = s->plane[i].idwt_buf + 1 * w4 * h4;

        s->plane[i].subband[6] = s->plane[i].idwt_buf + 3 * w4 * h4;

        s->plane[i].subband[7] = s->plane[i].idwt_buf + 2 * w2 * h2;

        s->plane[i].subband[8] = s->plane[i].idwt_buf + 1 * w2 * h2;

        s->plane[i].subband[9] = s->plane[i].idwt_buf + 3 * w2 * h2;

        for (j = 0; j < DWT_LEVELS; j++) {

            for(k = 0; k < 4; k++) {

                s->plane[i].band[j][k].a_width  = w8 << j;

                s->plane[i].band[j][k].a_height = h8 << j;

            }

        }

        /* ll2 and ll1 commented out because they are done in-place */

        s->plane[i].l_h[0] = s->plane[i].idwt_tmp;

        s->plane[i].l_h[1] = s->plane[i].idwt_tmp + 2 * w8 * h8;

        //s->plane[i].l_h[2] = ll2;

        s->plane[i].l_h[3] = s->plane[i].idwt_tmp;

        s->plane[i].l_h[4] = s->plane[i].idwt_tmp + 2 * w4 * h4;

        //s->plane[i].l_h[5] = ll1;

        s->plane[i].l_h[6] = s->plane[i].idwt_tmp;

        s->plane[i].l_h[7] = s->plane[i].idwt_tmp + 2 * w2 * h2;

    }

    s->a_height = s->coded_height;

    s->a_width  = s->coded_width;

    s->a_format = s->coded_format;

    return 0;

}


static int frame_start(MpegEncContext *s)

{

    int ret;

    /* mark & release old frames */

    if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr &&

        s->last_picture_ptr != s->next_picture_ptr &&

        s->last_picture_ptr->f.buf[0]) {

        ff_mpeg_unref_picture(s, s->last_picture_ptr);

    }

    s->current_picture_ptr->f.pict_type = s->pict_type;

    s->current_picture_ptr->f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;

    ff_mpeg_unref_picture(s, &s->current_picture);

    if ((ret = ff_mpeg_ref_picture(s, &s->current_picture,

                                   s->current_picture_ptr)) < 0)

        return ret;

    if (s->pict_type != AV_PICTURE_TYPE_B) {

        s->last_picture_ptr = s->next_picture_ptr;

        if (!s->droppable)

            s->next_picture_ptr = s->current_picture_ptr;

    }

    if (s->last_picture_ptr) {

        ff_mpeg_unref_picture(s, &s->last_picture);

        if (s->last_picture_ptr->f.buf[0] &&

            (ret = ff_mpeg_ref_picture(s, &s->last_picture,

                                       s->last_picture_ptr)) < 0)

            return ret;

    }

    if (s->next_picture_ptr) {

        ff_mpeg_unref_picture(s, &s->next_picture);

        if (s->next_picture_ptr->f.buf[0] &&

            (ret = ff_mpeg_ref_picture(s, &s->next_picture,

                                       s->next_picture_ptr)) < 0)

            return ret;

    }

    if (s->picture_structure!= PICT_FRAME) {

        int i;

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

            if (s->picture_structure == PICT_BOTTOM_FIELD) {

                s->current_picture.f.data[i] +=

                    s->current_picture.f.linesize[i];

            }

            s->current_picture.f.linesize[i] *= 2;

            s->last_picture.f.linesize[i]    *= 2;

            s->next_picture.f.linesize[i]    *= 2;

        }

    }

    if (s->mpeg_quant || s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {

        s->dct_unquantize_intra = s->dct_unquantize_mpeg2_intra;

        s->dct_unquantize_inter = s->dct_unquantize_mpeg2_inter;

    } else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) {

        s->dct_unquantize_intra = s->dct_unquantize_h263_intra;

        s->dct_unquantize_inter = s->dct_unquantize_h263_inter;

    } else {

        s->dct_unquantize_intra = s->dct_unquantize_mpeg1_intra;

        s->dct_unquantize_inter = s->dct_unquantize_mpeg1_inter;

    }

    if (s->dct_error_sum) {

        assert(s->avctx->noise_reduction && s->encoding);

        update_noise_reduction(s);

    }

    return 0;

}


static always_inline void mpeg_motion(MpegEncContext *s,

                               uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,

                               int field_based, int bottom_field, int field_select,

                               uint8_t **ref_picture, op_pixels_func (*pix_op)[4],

                               int motion_x, int motion_y, int h)

{

    uint8_t *ptr_y, *ptr_cb, *ptr_cr;

    int dxy, uvdxy, mx, my, src_x, src_y, uvsrc_x, uvsrc_y, v_edge_pos, uvlinesize, linesize;

#if 0

if(s->quarter_sample)

{

    motion_x>>=1;

    motion_y>>=1;

#endif

    v_edge_pos = s->v_edge_pos >> field_based;

    linesize   = s->current_picture.linesize[0] << field_based;

    uvlinesize = s->current_picture.linesize[1] << field_based;

    dxy = ((motion_y & 1) << 1) | (motion_x & 1);

    src_x = s->mb_x* 16               + (motion_x >> 1);

    src_y =(s->mb_y<<(4-field_based)) + (motion_y >> 1);

    if (s->out_format == FMT_H263) {

        if((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based){

            mx = (motion_x>>1)|(motion_x&1);

            my = motion_y >>1;

            uvdxy = ((my & 1) << 1) | (mx & 1);

            uvsrc_x = s->mb_x* 8               + (mx >> 1);

            uvsrc_y = (s->mb_y<<(3-field_based)) + (my >> 1);

        }else{

            uvdxy = dxy | (motion_y & 2) | ((motion_x & 2) >> 1);

            uvsrc_x = src_x>>1;

            uvsrc_y = src_y>>1;

    }else if(s->out_format == FMT_H261){//even chroma mv's are full pel in H261

        mx = motion_x / 4;

        my = motion_y / 4;

        uvdxy = 0;

        uvsrc_x = s->mb_x*8 + mx;

        uvsrc_y = s->mb_y*8 + my;

    } else {

        if(s->chroma_y_shift){

            mx = motion_x / 2;

            my = motion_y / 2;

            uvdxy = ((my & 1) << 1) | (mx & 1);

            uvsrc_x = s->mb_x* 8               + (mx >> 1);

            uvsrc_y = (s->mb_y<<(3-field_based)) + (my >> 1);

        } else {

            if(s->chroma_x_shift){

            //Chroma422

                mx = motion_x / 2;

                uvdxy = ((motion_y & 1) << 1) | (mx & 1);

                uvsrc_x = s->mb_x* 8           + (mx >> 1);

                uvsrc_y = src_y;

            } else {

            //Chroma444

                uvdxy = dxy;

                uvsrc_x = src_x;

                uvsrc_y = src_y;

    ptr_y  = ref_picture[0] + src_y * linesize + src_x;

    ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;

    ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;

    if(   (unsigned)src_x > s->h_edge_pos - (motion_x&1) - 16

       || (unsigned)src_y >    v_edge_pos - (motion_y&1) - h){

            if(s->codec_id == CODEC_ID_MPEG2VIDEO ||

               s->codec_id == CODEC_ID_MPEG1VIDEO){

                av_log(s->avctx,AV_LOG_DEBUG,"MPEG motion vector out of boundary\n");

                return ;

            ff_emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize, 17, 17+field_based,

                             src_x, src_y<<field_based, s->h_edge_pos, s->v_edge_pos);

            ptr_y = s->edge_emu_buffer;

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

                uint8_t *uvbuf= s->edge_emu_buffer+18*s->linesize;

                ff_emulated_edge_mc(uvbuf  , ptr_cb, s->uvlinesize, 9, 9+field_based,

                                 uvsrc_x, uvsrc_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1);

                ff_emulated_edge_mc(uvbuf+16, ptr_cr, s->uvlinesize, 9, 9+field_based,

                                 uvsrc_x, uvsrc_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1);

                ptr_cb= uvbuf;

                ptr_cr= uvbuf+16;

    if(bottom_field){ //FIXME use this for field pix too instead of the obnoxious hack which changes picture.data

        dest_y += s->linesize;

        dest_cb+= s->uvlinesize;

        dest_cr+= s->uvlinesize;

    if(field_select){

        ptr_y += s->linesize;

        ptr_cb+= s->uvlinesize;

        ptr_cr+= s->uvlinesize;

    pix_op[0][dxy](dest_y, ptr_y, linesize, h);

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

        pix_op[s->chroma_x_shift][uvdxy](dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift);

        pix_op[s->chroma_x_shift][uvdxy](dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift);


static int decode_user_data(MpegEncContext *s, GetBitContext *gb){

    char buf[256];

    int i;

    int e;

    int ver, build, ver2, ver3;

    char last;

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

        if(show_bits(gb, 23) == 0) break;

        buf[i]= get_bits(gb, 8);

    }

    buf[i]=0;

    /* divx detection */

    e=sscanf(buf, "DivX%dBuild%d%c", &ver, &build, &last);

    if(e<2)

        e=sscanf(buf, "DivX%db%d%c", &ver, &build, &last);

    if(e>=2){

        s->divx_version= ver;

        s->divx_build= build;

        s->divx_packed= e==3 && last=='p';

    }

    /* ffmpeg detection */

    e=sscanf(buf, "FFmpe%*[^b]b%d", &build)+3;

    if(e!=4)

        e=sscanf(buf, "FFmpeg v%d.%d.%d / libavcodec build: %d", &ver, &ver2, &ver3, &build);

    if(e!=4){

        e=sscanf(buf, "Lavc%d.%d.%d", &ver, &ver2, &ver3)+1;

        build= (ver<<16) + (ver2<<8) + ver3;

    }

    if(e!=4){

        if(strcmp(buf, "ffmpeg")==0){

            s->lavc_build= 4600;

        }

    }

    if(e==4){

        s->lavc_build= build;

    }

    /* xvid detection */

    e=sscanf(buf, "XviD%d", &build);

    if(e==1){

        s->xvid_build= build;

    }

//printf("User Data: %s\n", buf);

    return 0;

}


static void do_adaptive_prediction(struct G722Band *band, const int cur_diff)

{

    int sg[2], limit, cur_qtzd_reconst;

    const int cur_part_reconst = band->s_zero + cur_diff < 0;

    sg[0] = sign_lookup[cur_part_reconst != band->part_reconst_mem[0]];

    sg[1] = sign_lookup[cur_part_reconst == band->part_reconst_mem[1]];

    band->part_reconst_mem[1] = band->part_reconst_mem[0];

    band->part_reconst_mem[0] = cur_part_reconst;

    band->pole_mem[1] = av_clip((sg[0] * av_clip(band->pole_mem[0], -8191, 8191) >> 5) +

                                (sg[1] << 7) + (band->pole_mem[1] * 127 >> 7), -12288, 12288);

    limit = 15360 - band->pole_mem[1];

    band->pole_mem[0] = av_clip(-192 * sg[0] + (band->pole_mem[0] * 255 >> 8), -limit, limit);

    s_zero(cur_diff, band);

    cur_qtzd_reconst = av_clip_int16((band->s_predictor + cur_diff) << 1);

    band->s_predictor = av_clip_int16(band->s_zero +

                                      (band->pole_mem[0] * cur_qtzd_reconst >> 15) +

                                      (band->pole_mem[1] * band->prev_qtzd_reconst >> 15));

    band->prev_qtzd_reconst = cur_qtzd_reconst;

}


void helper_done(void)

{

    env->pc = env->tsptr->tpc;

    env->npc = env->tsptr->tnpc + 4;

    PUT_CCR(env, env->tsptr->tstate >> 32);

    env->asi = (env->tsptr->tstate >> 24) & 0xff;

    change_pstate((env->tsptr->tstate >> 8) & 0xf3f);

    PUT_CWP64(env, env->tsptr->tstate & 0xff);

    env->tl--;

    env->tsptr = &env->ts[env->tl & MAXTL_MASK];

}


static const AVClass *ff_avio_child_class_next(const AVClass *prev)

{

    return prev ? NULL : &ffurl_context_class;

}


static int decode_band(IVI5DecContext *ctx, int plane_num,

                       IVIBandDesc *band, AVCodecContext *avctx)

{

    int         result, i, t, idx1, idx2;

    IVITile     *tile;

    uint16_t    chksum;

    band->buf     = band->bufs[ctx->dst_buf];

    band->ref_buf = band->bufs[ctx->ref_buf];

    band->data_ptr = ctx->frame_data + (get_bits_count(&ctx->gb) >> 3);

    result = decode_band_hdr(ctx, band, avctx);

    if (result) {

        av_log(avctx, AV_LOG_ERROR, "Error while decoding band header: %d\n",

               result);

        return -1;

    }

    if (band->is_empty) {

        av_log(avctx, AV_LOG_ERROR, "Empty band encountered!\n");

        return -1;

    }

    band->rv_map = &ctx->rvmap_tabs[band->rvmap_sel];

    /* apply corrections to the selected rvmap table if present */

    for (i = 0; i < band->num_corr; i++) {

        idx1 = band->corr[i*2];

        idx2 = band->corr[i*2+1];

        FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);

        FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);

    }

    for (t = 0; t < band->num_tiles; t++) {

        tile = &band->tiles[t];

        tile->is_empty = get_bits1(&ctx->gb);

        if (tile->is_empty) {

            ff_ivi_process_empty_tile(avctx, band, tile,

                                      (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3));

            align_get_bits(&ctx->gb);

        } else {

            tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb);

            result = decode_mb_info(ctx, band, tile, avctx);

            if (result < 0)

                break;

            if (band->blk_size == 8) {

                band->intra_base  = &ivi5_base_quant_8x8_intra[band->quant_mat][0];

                band->inter_base  = &ivi5_base_quant_8x8_inter[band->quant_mat][0];

                band->intra_scale = &ivi5_scale_quant_8x8_intra[band->quant_mat][0];

                band->inter_scale = &ivi5_scale_quant_8x8_inter[band->quant_mat][0];

            } else {

                band->intra_base  = ivi5_base_quant_4x4_intra;

                band->inter_base  = ivi5_base_quant_4x4_inter;

                band->intra_scale = ivi5_scale_quant_4x4_intra;

                band->inter_scale = ivi5_scale_quant_4x4_inter;

            }

            result = ff_ivi_decode_blocks(&ctx->gb, band, tile);

            if (result < 0) {

                av_log(avctx, AV_LOG_ERROR, "Corrupted blocks data encountered!\n");

                break;

            }

        }

    }

    /* restore the selected rvmap table by applying its corrections in reverse order */

    for (i = band->num_corr-1; i >= 0; i--) {

        idx1 = band->corr[i*2];

        idx2 = band->corr[i*2+1];

        FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);

        FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);

    }

    if (IVI_DEBUG && band->checksum_present) {

        chksum = ivi_calc_band_checksum(band);

        if (chksum != band->checksum) {

            av_log(avctx, AV_LOG_ERROR,

                   "Band checksum mismatch! Plane %d, band %d, received: %x, calculated: %x\n",

                   band->plane, band->band_num, band->checksum, chksum);

        }

    }

    return result;

}


static void test_interface_impl(const char *type)

{

    Object *obj = object_new(type);

    TestIf *iobj = TEST_IF(obj);

    TestIfClass *ioc = TEST_IF_GET_CLASS(iobj);

    g_assert(iobj);

    g_assert(ioc->test == PATTERN);

}


uint32_t HELPER(shl_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)

{

    uint64_t result;

    shift &= 63;

    result = (uint64_t)val << shift;

    env->cc_c = (result >> 32) & 1;

    env->cc_n = result;

    env->cc_z = result;

    env->cc_v = 0;

    env->cc_x = shift ? env->cc_c : env->cc_x;

    return result;

}


static int inc_refcounts(BlockDriverState *bs,

                         BdrvCheckResult *res,

                         uint16_t **refcount_table,

                         int64_t *refcount_table_size,

                         int64_t offset, int64_t size)

{

    BDRVQcowState *s = bs->opaque;

    uint64_t start, last, cluster_offset, k;

    int ret;

    if (size <= 0) {

        return 0;

    }

    start = start_of_cluster(s, offset);

    last = start_of_cluster(s, offset + size - 1);

    for(cluster_offset = start; cluster_offset <= last;

        cluster_offset += s->cluster_size) {

        k = cluster_offset >> s->cluster_bits;

        if (k >= *refcount_table_size) {

            ret = realloc_refcount_array(s, refcount_table,

                                         refcount_table_size, k + 1);

            if (ret < 0) {

                res->check_errors++;

                return ret;

            }

        }

        if (++(*refcount_table)[k] == 0) {

            fprintf(stderr, "ERROR: overflow cluster offset=0x%" PRIx64

                    "\n", cluster_offset);

            res->corruptions++;

        }

    }

    return 0;

}


static void test_server_free(TestServer *server)

{

    int i;

    qemu_chr_delete(server->chr);

    for (i = 0; i < server->fds_num; i++) {

        close(server->fds[i]);

    }

    if (server->log_fd != -1) {

        close(server->log_fd);

    }

    unlink(server->socket_path);

    g_free(server->socket_path);

    g_free(server->chr_name);

    g_free(server);

}


int qcow2_discard_clusters(BlockDriverState *bs, uint64_t offset,

    int nb_sectors, enum qcow2_discard_type type, bool full_discard)

{

    BDRVQcow2State *s = bs->opaque;

    uint64_t end_offset;

    uint64_t nb_clusters;

    int ret;

    end_offset = offset + (nb_sectors << BDRV_SECTOR_BITS);

    /* Round start up and end down */

    offset = align_offset(offset, s->cluster_size);

    end_offset = start_of_cluster(s, end_offset);

    if (offset > end_offset) {

        return 0;

    }

    nb_clusters = size_to_clusters(s, end_offset - offset);

    s->cache_discards = true;

    /* Each L2 table is handled by its own loop iteration */

    while (nb_clusters > 0) {

        ret = discard_single_l2(bs, offset, nb_clusters, type, full_discard);

        if (ret < 0) {

            goto fail;

        }

        nb_clusters -= ret;

        offset += (ret * s->cluster_size);

    }

    ret = 0;

fail:

    s->cache_discards = false;

    qcow2_process_discards(bs, ret);

    return ret;

}


static void audio_init(qemu_irq *pic)

{

    struct soundhw *c;

    int audio_enabled = 0;

    for (c = soundhw; !audio_enabled && c->name; ++c) {

        audio_enabled = c->enabled;

    }

    if (audio_enabled) {

        AudioState *s;

        s = AUD_init();

        if (s) {

            for (c = soundhw; c->name; ++c) {

                if (c->enabled) {

                    if (c->isa) {

                        c->init.init_isa(s, pic);

                    }

                }

            }

        }

    }

}


static int gif_image_write_image(ByteIOContext *pb,

                                 int x1, int y1, int width, int height,

                                 const uint8_t *buf, int linesize, int pix_fmt)

{

    PutBitContext p;

    uint8_t buffer[200]; /* 100 * 9 / 8 = 113 */

    int i, left, w, v;

    const uint8_t *ptr;

    /* image block */

    put_byte(pb, 0x2c);

    put_le16(pb, x1);

    put_le16(pb, y1);

    put_le16(pb, width);

    put_le16(pb, height);

    put_byte(pb, 0x00); /* flags */

    /* no local clut */

    put_byte(pb, 0x08);

    left= width * height;

    init_put_bits(&p, buffer, 130);

/*

 * the thing here is the bitstream is written as little packets, with a size byte before

 * but it's still the same bitstream between packets (no flush !)

 */

    ptr = buf;

    w = width;

    while(left>0) {

        gif_put_bits_rev(&p, 9, 0x0100); /* clear code */

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

            if (pix_fmt == PIX_FMT_RGB24) {

                v = gif_clut_index(ptr[0], ptr[1], ptr[2]);

                ptr+=3;

            } else {

                v = *ptr++;

            }

            gif_put_bits_rev(&p, 9, v);

            if (--w == 0) {

                w = width;

                buf += linesize;

                ptr = buf;

            }

        }

        if(left<=GIF_CHUNKS) {

            gif_put_bits_rev(&p, 9, 0x101); /* end of stream */

            gif_flush_put_bits_rev(&p);

        }

        if(pbBufPtr(&p) - p.buf > 0) {

            put_byte(pb, pbBufPtr(&p) - p.buf); /* byte count of the packet */

            put_buffer(pb, p.buf, pbBufPtr(&p) - p.buf); /* the actual buffer */

            p.buf_ptr = p.buf; /* dequeue the bytes off the bitstream */

        }

        if(left<=GIF_CHUNKS) {

            put_byte(pb, 0x00); /* end of image block */

        }

        left-=GIF_CHUNKS;

    }

    return 0;

}


int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode, Error **err)

{

    FILE *fh;

    int fd;

    int64_t ret = -1, handle;

    if (!has_mode) {

        mode = "r";

    }

    slog("guest-file-open called, filepath: %s, mode: %s", path, mode);

    fh = fopen(path, mode);

    if (!fh) {

        error_setg_errno(err, errno, "failed to open file '%s' (mode: '%s')",

                         path, mode);

        return -1;

    }

    /* set fd non-blocking to avoid common use cases (like reading from a

     * named pipe) from hanging the agent

     */

    fd = fileno(fh);

    ret = fcntl(fd, F_GETFL);

    ret = fcntl(fd, F_SETFL, ret | O_NONBLOCK);

    if (ret == -1) {

        error_setg_errno(err, errno, "failed to make file '%s' non-blocking",

                         path);

        fclose(fh);

        return -1;

    }

    handle = guest_file_handle_add(fh, err);

    if (error_is_set(err)) {

        fclose(fh);

        return -1;

    }

    slog("guest-file-open, handle: %d", handle);

    return handle;

}


static void vp5_parse_coeff_models(VP56Context *s)

{

    VP56RangeCoder *c = &s->c;

    VP56Model *model = s->modelp;

    uint8_t def_prob[11];

    int node, cg, ctx;

    int ct;    /* code type */

    int pt;    /* plane type (0 for Y, 1 for U or V) */

    memset(def_prob, 0x80, sizeof(def_prob));

    for (pt=0; pt<2; pt++)

        for (node=0; node<11; node++)

            if (vp56_rac_get_prob(c, vp5_dccv_pct[pt][node])) {

                def_prob[node] = vp56_rac_gets_nn(c, 7);

                model->coeff_dccv[pt][node] = def_prob[node];

            } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) {

                model->coeff_dccv[pt][node] = def_prob[node];

            }

    for (ct=0; ct<3; ct++)

        for (pt=0; pt<2; pt++)

            for (cg=0; cg<6; cg++)

                for (node=0; node<11; node++)

                    if (vp56_rac_get_prob(c, vp5_ract_pct[ct][pt][cg][node])) {

                        def_prob[node] = vp56_rac_gets_nn(c, 7);

                        model->coeff_ract[pt][ct][cg][node] = def_prob[node];

                    } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) {

                        model->coeff_ract[pt][ct][cg][node] = def_prob[node];

                    }

    /* coeff_dcct is a linear combination of coeff_dccv */

    for (pt=0; pt<2; pt++)

        for (ctx=0; ctx<36; ctx++)

            for (node=0; node<5; node++)

                model->coeff_dcct[pt][ctx][node] = av_clip(((model->coeff_dccv[pt][node] * vp5_dccv_lc[node][ctx][0] + 128) >> 8) + vp5_dccv_lc[node][ctx][1], 1, 254);

    /* coeff_acct is a linear combination of coeff_ract */

    for (ct=0; ct<3; ct++)

        for (pt=0; pt<2; pt++)

            for (cg=0; cg<3; cg++)

                for (ctx=0; ctx<6; ctx++)

                    for (node=0; node<5; node++)

                        model->coeff_acct[pt][ct][cg][ctx][node] = av_clip(((model->coeff_ract[pt][ct][cg][node] * vp5_ract_lc[ct][cg][node][ctx][0] + 128) >> 8) + vp5_ract_lc[ct][cg][node][ctx][1], 1, 254);

}


static void qmp_input_get_next_type(Visitor *v, int *kind, const int *qobjects,

                                    const char *name, Error **errp)

{

    QmpInputVisitor *qiv = to_qiv(v);

    QObject *qobj = qmp_input_get_object(qiv, name, false);

    if (!qobj) {

        error_setg(errp, QERR_MISSING_PARAMETER, name ? name : "null");

        return;

    }

    *kind = qobjects[qobject_type(qobj)];

}


static void breakpoint_invalidate(CPUArchState *env, target_ulong pc)

{

    tb_invalidate_phys_addr(cpu_get_phys_page_debug(env, pc));

}


static void dump_data(const uint8_t *data, int len) {}


void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg)

{

    const uint8_t type_code[] = {

        [GDB_BREAKPOINT_HW] = 0x0,

        [GDB_WATCHPOINT_WRITE] = 0x1,

        [GDB_WATCHPOINT_ACCESS] = 0x3

    };

    const uint8_t len_code[] = {

        [1] = 0x0, [2] = 0x1, [4] = 0x3, [8] = 0x2

    };

    int n;

    if (kvm_sw_breakpoints_active(env))

        dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP;

    if (nb_hw_breakpoint > 0) {

        dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP;

        dbg->arch.debugreg[7] = 0x0600;

        for (n = 0; n < nb_hw_breakpoint; n++) {

            dbg->arch.debugreg[n] = hw_breakpoint[n].addr;

            dbg->arch.debugreg[7] |= (2 << (n * 2)) |

                (type_code[hw_breakpoint[n].type] << (16 + n*4)) |

                (len_code[hw_breakpoint[n].len] << (18 + n*4));

        }

    }

    /* Legal xcr0 for loading */

    env->xcr0 = 1;

}


static inline int cris_swap(const int mode, int x)

{

	switch (mode)

	{

		case N: asm ("swapn\t%0\n" : "+r" (x) : "0" (x)); break;

		case W: asm ("swapw\t%0\n" : "+r" (x) : "0" (x)); break;

		case B: asm ("swapb\t%0\n" : "+r" (x) : "0" (x)); break;

		case R: asm ("swapr\t%0\n" : "+r" (x) : "0" (x)); break;

		case B|R: asm ("swapbr\t%0\n" : "+r" (x) : "0" (x)); break;

		case W|R: asm ("swapwr\t%0\n" : "+r" (x) : "0" (x)); break;

		case W|B: asm ("swapwb\t%0\n" : "+r" (x) : "0" (x)); break;

		case W|B|R: asm ("swapwbr\t%0\n" : "+r" (x) : "0" (x)); break;

		case N|R: asm ("swapnr\t%0\n" : "+r" (x) : "0" (x)); break;

		case N|B: asm ("swapnb\t%0\n" : "+r" (x) : "0" (x)); break;

		case N|B|R: asm ("swapnbr\t%0\n" : "+r" (x) : "0" (x)); break;

		case N|W: asm ("swapnw\t%0\n" : "+r" (x) : "0" (x)); break;

		default:

			err();

			break;

	}

	return x;

}


static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos,

                              int *outFilterSize, int xInc, int srcW,

                              int dstW, int filterAlign, int one,

                              int flags, int cpu_flags,

                              SwsVector *srcFilter, SwsVector *dstFilter,

                              double param[2], int srcPos, int dstPos)

{

    int i;

    int filterSize;

    int filter2Size;

    int minFilterSize;

    int64_t *filter    = NULL;

    int64_t *filter2   = NULL;

    const int64_t fone = 1LL << (54 - FFMIN(av_log2(srcW/dstW), 8));

    int ret            = -1;

    emms_c(); // FIXME should not be required but IS (even for non-MMX versions)

    // NOTE: the +3 is for the MMX(+1) / SSE(+3) scaler which reads over the end

    FF_ALLOC_OR_GOTO(NULL, *filterPos, (dstW + 3) * sizeof(**filterPos), fail);

    if (FFABS(xInc - 0x10000) < 10 && srcPos == dstPos) { // unscaled

        int i;

        filterSize = 1;

        FF_ALLOCZ_OR_GOTO(NULL, filter,

                          dstW * sizeof(*filter) * filterSize, fail);

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

            filter[i * filterSize] = fone;

            (*filterPos)[i]        = i;

    } else if (flags & SWS_POINT) { // lame looking point sampling mode

        int i;

        int64_t xDstInSrc;

        filterSize = 1;

        FF_ALLOC_OR_GOTO(NULL, filter,

                         dstW * sizeof(*filter) * filterSize, fail);

        xDstInSrc = ((dstPos*(int64_t)xInc)>>8) - ((srcPos*0x8000LL)>>7);

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

            int xx = (xDstInSrc - ((filterSize - 1) << 15) + (1 << 15)) >> 16;

            (*filterPos)[i] = xx;

            filter[i]       = fone;

            xDstInSrc      += xInc;

    } else if ((xInc <= (1 << 16) && (flags & SWS_AREA)) ||

               (flags & SWS_FAST_BILINEAR)) { // bilinear upscale

        int i;

        int64_t xDstInSrc;

        filterSize = 2;

        FF_ALLOC_OR_GOTO(NULL, filter,

                         dstW * sizeof(*filter) * filterSize, fail);

        xDstInSrc = ((dstPos*(int64_t)xInc)>>8) - ((srcPos*0x8000LL)>>7);

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

            int xx = (xDstInSrc - ((filterSize - 1) << 15) + (1 << 15)) >> 16;

            int j;

            (*filterPos)[i] = xx;

            // bilinear upscale / linear interpolate / area averaging

            for (j = 0; j < filterSize; j++) {

                int64_t coeff= fone - FFABS(((int64_t)xx<<16) - xDstInSrc)*(fone>>16);

                if (coeff < 0)

                    coeff = 0;

                filter[i * filterSize + j] = coeff;

                xx++;

            xDstInSrc += xInc;

    } else {

        int64_t xDstInSrc;

        int sizeFactor;

        if (flags & SWS_BICUBIC)

            sizeFactor = 4;

        else if (flags & SWS_X)

            sizeFactor = 8;

        else if (flags & SWS_AREA)

            sizeFactor = 1;     // downscale only, for upscale it is bilinear

        else if (flags & SWS_GAUSS)

            sizeFactor = 8;     // infinite ;)

        else if (flags & SWS_LANCZOS)

            sizeFactor = param[0] != SWS_PARAM_DEFAULT ? ceil(2 * param[0]) : 6;

        else if (flags & SWS_SINC)

            sizeFactor = 20;    // infinite ;)

        else if (flags & SWS_SPLINE)

            sizeFactor = 20;    // infinite ;)

        else if (flags & SWS_BILINEAR)

            sizeFactor = 2;

        else {

            av_assert0(0);

        if (xInc <= 1 << 16)

            filterSize = 1 + sizeFactor;    // upscale

        else

            filterSize = 1 + (sizeFactor * srcW + dstW - 1) / dstW;

        filterSize = FFMIN(filterSize, srcW - 2);

        filterSize = FFMAX(filterSize, 1);

        FF_ALLOC_OR_GOTO(NULL, filter,

                         dstW * sizeof(*filter) * filterSize, fail);

        xDstInSrc = ((dstPos*(int64_t)xInc)>>7) - ((srcPos*0x10000LL)>>7);

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

            int xx = (xDstInSrc - ((filterSize - 2) << 16)) / (1 << 17);

            int j;

            (*filterPos)[i] = xx;

            for (j = 0; j < filterSize; j++) {

                int64_t d = (FFABS(((int64_t)xx << 17) - xDstInSrc)) << 13;

                double floatd;

                int64_t coeff;

                if (xInc > 1 << 16)

                    d = d * dstW / srcW;

                floatd = d * (1.0 / (1 << 30));

                if (flags & SWS_BICUBIC) {

                    int64_t B = (param[0] != SWS_PARAM_DEFAULT ? param[0] :   0) * (1 << 24);

                    int64_t C = (param[1] != SWS_PARAM_DEFAULT ? param[1] : 0.6) * (1 << 24);

                    if (d >= 1LL << 31) {

                        coeff = 0.0;

                    } else {

                        int64_t dd  = (d  * d) >> 30;

                        int64_t ddd = (dd * d) >> 30;

                        if (d < 1LL << 30)

                            coeff =  (12 * (1 << 24) -  9 * B - 6 * C) * ddd +

                                    (-18 * (1 << 24) + 12 * B + 6 * C) *  dd +

                                      (6 * (1 << 24) -  2 * B)         * (1 << 30);

                        else

                            coeff =      (-B -  6 * C) * ddd +

                                      (6 * B + 30 * C) * dd  +

                                    (-12 * B - 48 * C) * d   +

                                      (8 * B + 24 * C) * (1 << 30);

                    coeff /= (1LL<<54)/fone;

#if 0

                else if (flags & SWS_X) {

                    double p  = param ? param * 0.01 : 0.3;

                    coeff     = d ? sin(d * M_PI) / (d * M_PI) : 1.0;

                    coeff    *= pow(2.0, -p * d * d);

#endif

                else if (flags & SWS_X) {

                    double A = param[0] != SWS_PARAM_DEFAULT ? param[0] : 1.0;

                    double c;

                    if (floatd < 1.0)

                        c = cos(floatd * M_PI);

                    else

                        c = -1.0;

                    if (c < 0.0)

                        c = -pow(-c, A);

                    else

                        c = pow(c, A);

                    coeff = (c * 0.5 + 0.5) * fone;

                } else if (flags & SWS_AREA) {

                    int64_t d2 = d - (1 << 29);

                    if (d2 * xInc < -(1LL << (29 + 16)))

                        coeff = 1.0 * (1LL << (30 + 16));

                    else if (d2 * xInc < (1LL << (29 + 16)))

                        coeff = -d2 * xInc + (1LL << (29 + 16));

                    else

                        coeff = 0.0;

                    coeff *= fone >> (30 + 16);

                } else if (flags & SWS_GAUSS) {

                    double p = param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0;

                    coeff = (pow(2.0, -p * floatd * floatd)) * fone;

                } else if (flags & SWS_SINC) {

                    coeff = (d ? sin(floatd * M_PI) / (floatd * M_PI) : 1.0) * fone;

                } else if (flags & SWS_LANCZOS) {

                    double p = param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0;

                    coeff = (d ? sin(floatd * M_PI) * sin(floatd * M_PI / p) /

                             (floatd * floatd * M_PI * M_PI / p) : 1.0) * fone;

                    if (floatd > p)

                        coeff = 0;

                } else if (flags & SWS_BILINEAR) {

                    coeff = (1 << 30) - d;

                    if (coeff < 0)

                        coeff = 0;

                    coeff *= fone >> 30;

                } else if (flags & SWS_SPLINE) {

                    double p = -2.196152422706632;

                    coeff = getSplineCoeff(1.0, 0.0, p, -p - 1.0, floatd) * fone;

                } else {

                    av_assert0(0);

                filter[i * filterSize + j] = coeff;

                xx++;

            xDstInSrc += 2 * xInc;

    /* apply src & dst Filter to filter -> filter2

     * av_free(filter);

     */

    av_assert0(filterSize > 0);

    filter2Size = filterSize;

    if (srcFilter)

        filter2Size += srcFilter->length - 1;

    if (dstFilter)

        filter2Size += dstFilter->length - 1;

    av_assert0(filter2Size > 0);

    FF_ALLOCZ_OR_GOTO(NULL, filter2, filter2Size * dstW * sizeof(*filter2), fail);

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

        int j, k;

        if (srcFilter) {

            for (k = 0; k < srcFilter->length; k++) {

                for (j = 0; j < filterSize; j++)

                    filter2[i * filter2Size + k + j] +=

                        srcFilter->coeff[k] * filter[i * filterSize + j];

        } else {

            for (j = 0; j < filterSize; j++)

                filter2[i * filter2Size + j] = filter[i * filterSize + j];

        // FIXME dstFilter

        (*filterPos)[i] += (filterSize - 1) / 2 - (filter2Size - 1) / 2;

    av_freep(&filter);

    /* try to reduce the filter-size (step1 find size and shift left) */

    // Assume it is near normalized (*0.5 or *2.0 is OK but * 0.001 is not).

    minFilterSize = 0;

    for (i = dstW - 1; i >= 0; i--) {

        int min = filter2Size;

        int j;

        int64_t cutOff = 0.0;

        /* get rid of near zero elements on the left by shifting left */

        for (j = 0; j < filter2Size; j++) {

            int k;

            cutOff += FFABS(filter2[i * filter2Size]);

            if (cutOff > SWS_MAX_REDUCE_CUTOFF * fone)

                break;

            /* preserve monotonicity because the core can't handle the

             * filter otherwise */

            if (i < dstW - 1 && (*filterPos)[i] >= (*filterPos)[i + 1])

                break;

            // move filter coefficients left

            for (k = 1; k < filter2Size; k++)

                filter2[i * filter2Size + k - 1] = filter2[i * filter2Size + k];

            filter2[i * filter2Size + k - 1] = 0;

            (*filterPos)[i]++;

        cutOff = 0;

        /* count near zeros on the right */

        for (j = filter2Size - 1; j > 0; j--) {

            cutOff += FFABS(filter2[i * filter2Size + j]);

            if (cutOff > SWS_MAX_REDUCE_CUTOFF * fone)

                break;

            min--;

        if (min > minFilterSize)

            minFilterSize = min;

    if (PPC_ALTIVEC(cpu_flags)) {

        // we can handle the special case 4, so we don't want to go the full 8

        if (minFilterSize < 5)

            filterAlign = 4;

        /* We really don't want to waste our time doing useless computation, so

         * fall back on the scalar C code for very small filters.

         * Vectorizing is worth it only if you have a decent-sized vector. */

        if (minFilterSize < 3)

            filterAlign = 1;

    if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) {

        // special case for unscaled vertical filtering

        if (minFilterSize == 1 && filterAlign == 2)

            filterAlign = 1;

    av_assert0(minFilterSize > 0);

    filterSize = (minFilterSize + (filterAlign - 1)) & (~(filterAlign - 1));

    av_assert0(filterSize > 0);

    filter = av_malloc(filterSize * dstW * sizeof(*filter));

    if (filterSize >= MAX_FILTER_SIZE * 16 /

                      ((flags & SWS_ACCURATE_RND) ? APCK_SIZE : 16) || !filter) {

        av_log(NULL, AV_LOG_ERROR, "sws: filterSize %d is too large, try less extreem scaling or increase MAX_FILTER_SIZE and recompile\n", filterSize);

        goto fail;

    *outFilterSize = filterSize;

    if (flags & SWS_PRINT_INFO)

        av_log(NULL, AV_LOG_VERBOSE,

               "SwScaler: reducing / aligning filtersize %d -> %d\n",

               filter2Size, filterSize);

    /* try to reduce the filter-size (step2 reduce it) */

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

        int j;

        for (j = 0; j < filterSize; j++) {

            if (j >= filter2Size)

                filter[i * filterSize + j] = 0;

            else

                filter[i * filterSize + j] = filter2[i * filter2Size + j];

            if ((flags & SWS_BITEXACT) && j >= minFilterSize)

                filter[i * filterSize + j] = 0;

    // FIXME try to align filterPos if possible

    // fix borders

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

        int j;

        if ((*filterPos)[i] < 0) {

            // move filter coefficients left to compensate for filterPos

            for (j = 1; j < filterSize; j++) {

                int left = FFMAX(j + (*filterPos)[i], 0);

                filter[i * filterSize + left] += filter[i * filterSize + j];

                filter[i * filterSize + j]     = 0;

            (*filterPos)[i]= 0;

        if ((*filterPos)[i] + filterSize > srcW) {

            int shift = (*filterPos)[i] + filterSize - srcW;

            // move filter coefficients right to compensate for filterPos

            for (j = filterSize - 2; j >= 0; j--) {

                int right = FFMIN(j + shift, filterSize - 1);

                filter[i * filterSize + right] += filter[i * filterSize + j];

                filter[i * filterSize + j]      = 0;

            (*filterPos)[i]= srcW - filterSize;

    // Note the +1 is for the MMX scaler which reads over the end

    /* align at 16 for AltiVec (needed by hScale_altivec_real) */

    FF_ALLOCZ_OR_GOTO(NULL, *outFilter,

                      *outFilterSize * (dstW + 3) * sizeof(int16_t), fail);

    /* normalize & store in outFilter */

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

        int j;

        int64_t error = 0;

        int64_t sum   = 0;

        for (j = 0; j < filterSize; j++) {

            sum += filter[i * filterSize + j];

        sum = (sum + one / 2) / one;

        for (j = 0; j < *outFilterSize; j++) {

            int64_t v = filter[i * filterSize + j] + error;

            int intV  = ROUNDED_DIV(v, sum);

            (*outFilter)[i * (*outFilterSize) + j] = intV;

            error                                  = v - intV * sum;

    (*filterPos)[dstW + 0] =

    (*filterPos)[dstW + 1] =

    (*filterPos)[dstW + 2] = (*filterPos)[dstW - 1]; /* the MMX/SSE scaler will

                                                      * read over the end */

    for (i = 0; i < *outFilterSize; i++) {

        int k = (dstW - 1) * (*outFilterSize) + i;

        (*outFilter)[k + 1 * (*outFilterSize)] =

        (*outFilter)[k + 2 * (*outFilterSize)] =

        (*outFilter)[k + 3 * (*outFilterSize)] = (*outFilter)[k];

    ret = 0;

fail:

    if(ret < 0)

        av_log(NULL, AV_LOG_ERROR, "sws: initFilter failed\n");

    av_free(filter);

    av_free(filter2);

    return ret;


static uint64_t hb_count_between(HBitmap *hb, uint64_t start, uint64_t last)

{

    HBitmapIter hbi;

    uint64_t count = 0;

    uint64_t end = last + 1;

    unsigned long cur;

    size_t pos;

    hbitmap_iter_init(&hbi, hb, start << hb->granularity);

    for (;;) {

        pos = hbitmap_iter_next_word(&hbi, &cur);

        if (pos >= (end >> BITS_PER_LEVEL)) {

            break;

        }

        count += popcountl(cur);

    }

    if (pos == (end >> BITS_PER_LEVEL)) {

        /* Drop bits representing the END-th and subsequent items.  */

        int bit = end & (BITS_PER_LONG - 1);

        cur &= (1UL << bit) - 1;

        count += popcountl(cur);

    }

    return count;

}


static int img_convert(int argc, char **argv)

{

    int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;

    int progress = 0, flags;

    const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;

    BlockDriver *drv, *proto_drv;

    BlockDriverState **bs = NULL, *out_bs = NULL;

    int64_t total_sectors, nb_sectors, sector_num, bs_offset;

    uint64_t bs_sectors;

    uint8_t * buf = NULL;

    const uint8_t *buf1;

    BlockDriverInfo bdi;

    QEMUOptionParameter *param = NULL, *create_options = NULL;

    QEMUOptionParameter *out_baseimg_param;

    char *options = NULL;

    const char *snapshot_name = NULL;

    float local_progress;

    int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */

    fmt = NULL;

    out_fmt = "raw";

    cache = "unsafe";

    out_baseimg = NULL;

    compress = 0;

    for(;;) {

        c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:");

        if (c == -1) {

            break;

        }

        switch(c) {

        case '?':

        case 'h':

            help();

            break;

        case 'f':

            fmt = optarg;

            break;

        case 'O':

            out_fmt = optarg;

            break;

        case 'B':

            out_baseimg = optarg;

            break;

        case 'c':

            compress = 1;

            break;

        case 'e':

            error_report("option -e is deprecated, please use \'-o "

                  "encryption\' instead!");

            return 1;

        case '6':

            error_report("option -6 is deprecated, please use \'-o "

                  "compat6\' instead!");

            return 1;

        case 'o':

            options = optarg;

            break;

        case 's':

            snapshot_name = optarg;

            break;

        case 'S':

        {

            int64_t sval;

            char *end;

            sval = strtosz_suffix(optarg, &end, STRTOSZ_DEFSUFFIX_B);

            if (sval < 0 || *end) {

                error_report("Invalid minimum zero buffer size for sparse output specified");

                return 1;

            }

            min_sparse = sval / BDRV_SECTOR_SIZE;

            break;

        }

        case 'p':

            progress = 1;

            break;

        case 't':

            cache = optarg;

            break;

        }

    }

    bs_n = argc - optind - 1;

    if (bs_n < 1) {

        help();

    }

    out_filename = argv[argc - 1];

    /* Initialize before goto out */

    qemu_progress_init(progress, 2.0);

    if (options && !strcmp(options, "?")) {

        ret = print_block_option_help(out_filename, out_fmt);

        goto out;

    }

    if (bs_n > 1 && out_baseimg) {

        error_report("-B makes no sense when concatenating multiple input "

                     "images");

        ret = -1;

        goto out;

    }

    qemu_progress_print(0, 100);

    bs = g_malloc0(bs_n * sizeof(BlockDriverState *));

    total_sectors = 0;

    for (bs_i = 0; bs_i < bs_n; bs_i++) {

        bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS);

        if (!bs[bs_i]) {

            error_report("Could not open '%s'", argv[optind + bs_i]);

            ret = -1;

            goto out;

        }

        bdrv_get_geometry(bs[bs_i], &bs_sectors);

        total_sectors += bs_sectors;

    }

    if (snapshot_name != NULL) {

        if (bs_n > 1) {

            error_report("No support for concatenating multiple snapshot");

            ret = -1;

            goto out;

        }

        if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {

            error_report("Failed to load snapshot");

            ret = -1;

            goto out;

        }

    }

    /* Find driver and parse its options */

    drv = bdrv_find_format(out_fmt);

    if (!drv) {

        error_report("Unknown file format '%s'", out_fmt);

        ret = -1;

        goto out;

    }

    proto_drv = bdrv_find_protocol(out_filename);

    if (!proto_drv) {

        error_report("Unknown protocol '%s'", out_filename);

        ret = -1;

        goto out;

    }

    create_options = append_option_parameters(create_options,

                                              drv->create_options);

    create_options = append_option_parameters(create_options,

                                              proto_drv->create_options);

    if (options) {

        param = parse_option_parameters(options, create_options, param);

        if (param == NULL) {

            error_report("Invalid options for file format '%s'.", out_fmt);

            ret = -1;

            goto out;

        }

    } else {

        param = parse_option_parameters("", create_options, param);

    }

    set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);

    ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);

    if (ret < 0) {

        goto out;

    }

    /* Get backing file name if -o backing_file was used */

    out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);

    if (out_baseimg_param) {

        out_baseimg = out_baseimg_param->value.s;

    }

    /* Check if compression is supported */

    if (compress) {

        QEMUOptionParameter *encryption =

            get_option_parameter(param, BLOCK_OPT_ENCRYPT);

        QEMUOptionParameter *preallocation =

            get_option_parameter(param, BLOCK_OPT_PREALLOC);

        if (!drv->bdrv_write_compressed) {

            error_report("Compression not supported for this file format");

            ret = -1;

            goto out;

        }

        if (encryption && encryption->value.n) {

            error_report("Compression and encryption not supported at "

                         "the same time");

            ret = -1;

            goto out;

        }

        if (preallocation && preallocation->value.s

            && strcmp(preallocation->value.s, "off"))

        {

            error_report("Compression and preallocation not supported at "

                         "the same time");

            ret = -1;

            goto out;

        }

    }

    /* Create the new image */

    ret = bdrv_create(drv, out_filename, param);

    if (ret < 0) {

        if (ret == -ENOTSUP) {

            error_report("Formatting not supported for file format '%s'",

                         out_fmt);

        } else if (ret == -EFBIG) {

            error_report("The image size is too large for file format '%s'",

                         out_fmt);

        } else {

            error_report("%s: error while converting %s: %s",

                         out_filename, out_fmt, strerror(-ret));

        }

        goto out;

    }

    flags = BDRV_O_RDWR;

    ret = bdrv_parse_cache_flags(cache, &flags);

    if (ret < 0) {

        error_report("Invalid cache option: %s", cache);

        return -1;

    }

    out_bs = bdrv_new_open(out_filename, out_fmt, flags);

    if (!out_bs) {

        ret = -1;

        goto out;

    }

    bs_i = 0;

    bs_offset = 0;

    bdrv_get_geometry(bs[0], &bs_sectors);

    buf = qemu_blockalign(out_bs, IO_BUF_SIZE);

    if (compress) {

        ret = bdrv_get_info(out_bs, &bdi);

        if (ret < 0) {

            error_report("could not get block driver info");

            goto out;

        }

        cluster_size = bdi.cluster_size;

        if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {

            error_report("invalid cluster size");

            ret = -1;

            goto out;

        }

        cluster_sectors = cluster_size >> 9;

        sector_num = 0;

        nb_sectors = total_sectors;

        local_progress = (float)100 /

            (nb_sectors / MIN(nb_sectors, cluster_sectors));

        for(;;) {

            int64_t bs_num;

            int remainder;

            uint8_t *buf2;

            nb_sectors = total_sectors - sector_num;

            if (nb_sectors <= 0)

                break;

            if (nb_sectors >= cluster_sectors)

                n = cluster_sectors;

            else

                n = nb_sectors;

            bs_num = sector_num - bs_offset;

            assert (bs_num >= 0);

            remainder = n;

            buf2 = buf;

            while (remainder > 0) {

                int nlow;

                while (bs_num == bs_sectors) {

                    bs_i++;

                    assert (bs_i < bs_n);

                    bs_offset += bs_sectors;

                    bdrv_get_geometry(bs[bs_i], &bs_sectors);

                    bs_num = 0;

                    /* printf("changing part: sector_num=%" PRId64 ", "

                       "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64

                       "\n", sector_num, bs_i, bs_offset, bs_sectors); */

                }

                assert (bs_num < bs_sectors);

                nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;

                ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);

                if (ret < 0) {

                    error_report("error while reading sector %" PRId64 ": %s",

                                 bs_num, strerror(-ret));

                    goto out;

                }

                buf2 += nlow * 512;

                bs_num += nlow;

                remainder -= nlow;

            }

            assert (remainder == 0);

            if (n < cluster_sectors) {

                memset(buf + n * 512, 0, cluster_size - n * 512);

            }

            if (!buffer_is_zero(buf, cluster_size)) {

                ret = bdrv_write_compressed(out_bs, sector_num, buf,

                                            cluster_sectors);

                if (ret != 0) {

                    error_report("error while compressing sector %" PRId64

                                 ": %s", sector_num, strerror(-ret));

                    goto out;

                }

            }

            sector_num += n;

            qemu_progress_print(local_progress, 100);

        }

        /* signal EOF to align */

        bdrv_write_compressed(out_bs, 0, NULL, 0);

    } else {

        int has_zero_init = bdrv_has_zero_init(out_bs);

        sector_num = 0; // total number of sectors converted so far

        nb_sectors = total_sectors - sector_num;

        local_progress = (float)100 /

            (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512));

        for(;;) {

            nb_sectors = total_sectors - sector_num;

            if (nb_sectors <= 0) {

                break;

            }

            if (nb_sectors >= (IO_BUF_SIZE / 512)) {

                n = (IO_BUF_SIZE / 512);

            } else {

                n = nb_sectors;

            }

            while (sector_num - bs_offset >= bs_sectors) {

                bs_i ++;

                assert (bs_i < bs_n);

                bs_offset += bs_sectors;

                bdrv_get_geometry(bs[bs_i], &bs_sectors);

                /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "

                  "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",

                   sector_num, bs_i, bs_offset, bs_sectors); */

            }

            if (n > bs_offset + bs_sectors - sector_num) {

                n = bs_offset + bs_sectors - sector_num;

            }

            if (has_zero_init) {

                /* If the output image is being created as a copy on write image,

                   assume that sectors which are unallocated in the input image

                   are present in both the output's and input's base images (no

                   need to copy them). */

                if (out_baseimg) {

                    if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,

                                           n, &n1)) {

                        sector_num += n1;

                        continue;

                    }

                    /* The next 'n1' sectors are allocated in the input image. Copy

                       only those as they may be followed by unallocated sectors. */

                    n = n1;

                }

            } else {

                n1 = n;

            }

            ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);

            if (ret < 0) {

                error_report("error while reading sector %" PRId64 ": %s",

                             sector_num - bs_offset, strerror(-ret));

                goto out;

            }

            /* NOTE: at the same time we convert, we do not write zero

               sectors to have a chance to compress the image. Ideally, we

               should add a specific call to have the info to go faster */

            buf1 = buf;

            while (n > 0) {

                /* If the output image is being created as a copy on write image,

                   copy all sectors even the ones containing only NUL bytes,

                   because they may differ from the sectors in the base image.

                   If the output is to a host device, we also write out

                   sectors that are entirely 0, since whatever data was

                   already there is garbage, not 0s. */

                if (!has_zero_init || out_baseimg ||

                    is_allocated_sectors_min(buf1, n, &n1, min_sparse)) {

                    ret = bdrv_write(out_bs, sector_num, buf1, n1);

                    if (ret < 0) {

                        error_report("error while writing sector %" PRId64

                                     ": %s", sector_num, strerror(-ret));

                        goto out;

                    }

                }

                sector_num += n1;

                n -= n1;

                buf1 += n1 * 512;

            }

            qemu_progress_print(local_progress, 100);

        }

    }

out:

    qemu_progress_end();

    free_option_parameters(create_options);

    free_option_parameters(param);

    qemu_vfree(buf);

    if (out_bs) {

        bdrv_delete(out_bs);

    }

    if (bs) {

        for (bs_i = 0; bs_i < bs_n; bs_i++) {

            if (bs[bs_i]) {

                bdrv_delete(bs[bs_i]);

            }

        }

        g_free(bs);

    }

    if (ret) {

        return 1;

    }

    return 0;

}