static int iscsi_open(BlockDriverState *bs, const char *filename, int flags)

{

    IscsiLun *iscsilun = bs->opaque;

    struct iscsi_context *iscsi = NULL;

    struct iscsi_url *iscsi_url = NULL;

    struct IscsiTask task;

    char *initiator_name = NULL;

    int ret;

    if ((BDRV_SECTOR_SIZE % 512) != 0) {

        error_report("iSCSI: Invalid BDRV_SECTOR_SIZE. "

                     "BDRV_SECTOR_SIZE(%lld) is not a multiple "

                     "of 512", BDRV_SECTOR_SIZE);

        return -EINVAL;

    }

    iscsi_url = iscsi_parse_full_url(iscsi, filename);

    if (iscsi_url == NULL) {

        error_report("Failed to parse URL : %s %s", filename,

                     iscsi_get_error(iscsi));

        ret = -EINVAL;

        goto failed;

    }

    memset(iscsilun, 0, sizeof(IscsiLun));

    initiator_name = parse_initiator_name(iscsi_url->target);

    iscsi = iscsi_create_context(initiator_name);

    if (iscsi == NULL) {

        error_report("iSCSI: Failed to create iSCSI context.");

        ret = -ENOMEM;

        goto failed;

    }

    if (iscsi_set_targetname(iscsi, iscsi_url->target)) {

        error_report("iSCSI: Failed to set target name.");

        ret = -EINVAL;

        goto failed;

    }

    if (iscsi_url->user != NULL) {

        ret = iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user,

                                              iscsi_url->passwd);

        if (ret != 0) {

            error_report("Failed to set initiator username and password");

            ret = -EINVAL;

            goto failed;

        }

    }

    /* check if we got CHAP username/password via the options */

    if (parse_chap(iscsi, iscsi_url->target) != 0) {

        error_report("iSCSI: Failed to set CHAP user/password");

        ret = -EINVAL;

        goto failed;

    }

    if (iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL) != 0) {

        error_report("iSCSI: Failed to set session type to normal.");

        ret = -EINVAL;

        goto failed;

    }

    iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);

    /* check if we got HEADER_DIGEST via the options */

    parse_header_digest(iscsi, iscsi_url->target);

    task.iscsilun = iscsilun;

    task.status = 0;

    task.complete = 0;

    task.bs = bs;

    iscsilun->iscsi = iscsi;

    iscsilun->lun   = iscsi_url->lun;

    if (iscsi_full_connect_async(iscsi, iscsi_url->portal, iscsi_url->lun,

                                 iscsi_connect_cb, &task)

        != 0) {

        error_report("iSCSI: Failed to start async connect.");

        ret = -EINVAL;

        goto failed;

    }

    while (!task.complete) {

        iscsi_set_events(iscsilun);

        qemu_aio_wait();

    }

    if (task.status != 0) {

        error_report("iSCSI: Failed to connect to LUN : %s",

                     iscsi_get_error(iscsi));

        ret = -EINVAL;

        goto failed;

    }

    if (iscsi_url != NULL) {

        iscsi_destroy_url(iscsi_url);

    }

    /* Medium changer or tape. We dont have any emulation for this so this must

     * be sg ioctl compatible. We force it to be sg, otherwise qemu will try

     * to read from the device to guess the image format.

     */

    if (iscsilun->type == TYPE_MEDIUM_CHANGER ||

        iscsilun->type == TYPE_TAPE) {

        bs->sg = 1;

    }

    return 0;

failed:

    if (initiator_name != NULL) {

        g_free(initiator_name);

    }

    if (iscsi_url != NULL) {

        iscsi_destroy_url(iscsi_url);

    }

    if (iscsi != NULL) {

        iscsi_destroy_context(iscsi);

    }

    memset(iscsilun, 0, sizeof(IscsiLun));

    return ret;

}


static void vmxnet3_rx_need_csum_calculate(struct VmxnetRxPkt *pkt,

                                           const void *pkt_data,

                                           size_t pkt_len)

{

    struct virtio_net_hdr *vhdr;

    bool isip4, isip6, istcp, isudp;

    uint8_t *data;

    int len;

    if (!vmxnet_rx_pkt_has_virt_hdr(pkt)) {

        return;

    }

    vhdr = vmxnet_rx_pkt_get_vhdr(pkt);

    if (!VMXNET_FLAG_IS_SET(vhdr->flags, VIRTIO_NET_HDR_F_NEEDS_CSUM)) {

        return;

    }

    vmxnet_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp);

    if (!(isip4 || isip6) || !(istcp || isudp)) {

        return;

    }

    vmxnet3_dump_virt_hdr(vhdr);

    /* Validate packet len: csum_start + scum_offset + length of csum field */

    if (pkt_len < (vhdr->csum_start + vhdr->csum_offset + 2)) {

        VMW_PKPRN("packet len:%d < csum_start(%d) + csum_offset(%d) + 2, "

                  "cannot calculate checksum",

                  len, vhdr->csum_start, vhdr->csum_offset);

        return;

    }

    data = (uint8_t *)pkt_data + vhdr->csum_start;

    len = pkt_len - vhdr->csum_start;

    /* Put the checksum obtained into the packet */

    stw_be_p(data + vhdr->csum_offset, net_raw_checksum(data, len));

    vhdr->flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM;

    vhdr->flags |= VIRTIO_NET_HDR_F_DATA_VALID;

}


CommandInfoList *qmp_query_commands(Error **errp)

{

    CommandInfoList *list = NULL;

    qmp_for_each_command(&qmp_commands, query_commands_cb, &list);

    return list;

}


static int decode_blocks(ALSDecContext *ctx, unsigned int ra_frame,

                         unsigned int c, const unsigned int *div_blocks,

                         unsigned int *js_blocks)

{

    ALSSpecificConfig *sconf = &ctx->sconf;

    unsigned int offset = 0;

    unsigned int b;

    ALSBlockData bd[2] = { { 0 } };

    bd[0].ra_block         = ra_frame;

    bd[0].const_block      = ctx->const_block;

    bd[0].shift_lsbs       = ctx->shift_lsbs;

    bd[0].opt_order        = ctx->opt_order;

    bd[0].store_prev_samples = ctx->store_prev_samples;

    bd[0].use_ltp          = ctx->use_ltp;

    bd[0].ltp_lag          = ctx->ltp_lag;

    bd[0].ltp_gain         = ctx->ltp_gain[0];

    bd[0].quant_cof        = ctx->quant_cof[0];

    bd[0].lpc_cof          = ctx->lpc_cof[0];

    bd[0].prev_raw_samples = ctx->prev_raw_samples;

    bd[0].js_blocks        = *js_blocks;

    bd[1].ra_block         = ra_frame;

    bd[1].const_block      = ctx->const_block;

    bd[1].shift_lsbs       = ctx->shift_lsbs;

    bd[1].opt_order        = ctx->opt_order;

    bd[1].store_prev_samples = ctx->store_prev_samples;

    bd[1].use_ltp          = ctx->use_ltp;

    bd[1].ltp_lag          = ctx->ltp_lag;

    bd[1].ltp_gain         = ctx->ltp_gain[0];

    bd[1].quant_cof        = ctx->quant_cof[0];

    bd[1].lpc_cof          = ctx->lpc_cof[0];

    bd[1].prev_raw_samples = ctx->prev_raw_samples;

    bd[1].js_blocks        = *(js_blocks + 1);

    // decode all blocks

    for (b = 0; b < ctx->num_blocks; b++) {

        unsigned int s;

        bd[0].block_length = div_blocks[b];

        bd[1].block_length = div_blocks[b];

        bd[0].raw_samples  = ctx->raw_samples[c    ] + offset;

        bd[1].raw_samples  = ctx->raw_samples[c + 1] + offset;

        bd[0].raw_other    = bd[1].raw_samples;

        bd[1].raw_other    = bd[0].raw_samples;

        if(read_decode_block(ctx, &bd[0]) || read_decode_block(ctx, &bd[1])) {

            // damaged block, write zero for the rest of the frame

            zero_remaining(b, ctx->num_blocks, div_blocks, bd[0].raw_samples);

            zero_remaining(b, ctx->num_blocks, div_blocks, bd[1].raw_samples);

            return -1;

        }

        // reconstruct joint-stereo blocks

        if (bd[0].js_blocks) {

            if (bd[1].js_blocks)

                av_log(ctx->avctx, AV_LOG_WARNING, "Invalid channel pair!\n");

            for (s = 0; s < div_blocks[b]; s++)

                bd[0].raw_samples[s] = bd[1].raw_samples[s] - bd[0].raw_samples[s];

        } else if (bd[1].js_blocks) {

            for (s = 0; s < div_blocks[b]; s++)

                bd[1].raw_samples[s] = bd[1].raw_samples[s] + bd[0].raw_samples[s];

        }

        offset  += div_blocks[b];

        bd[0].ra_block = 0;

        bd[1].ra_block = 0;

    }

    // store carryover raw samples,

    // the others channel raw samples are stored by the calling function.

    memmove(ctx->raw_samples[c] - sconf->max_order,

            ctx->raw_samples[c] - sconf->max_order + sconf->frame_length,

            sizeof(*ctx->raw_samples[c]) * sconf->max_order);

    return 0;

}


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

{

    struct timeval t1, t2;

    int Cflag = 0, pflag = 0, qflag = 0, bflag = 0;

    int c, cnt;

    char *buf;

    int64_t offset;

    int count;

    /* Some compilers get confused and warn if this is not initialized.  */

    int total = 0;

    int pattern = 0xcd;

    while ((c = getopt(argc, argv, "bCpP:q")) != EOF) {

        switch (c) {

        case 'b':

            bflag = 1;

            break;

        case 'C':

            Cflag = 1;

            break;

        case 'p':

            pflag = 1;

            break;

        case 'P':

            pattern = parse_pattern(optarg);

            if (pattern < 0) {

                return 0;

            }

            break;

        case 'q':

            qflag = 1;

            break;

        default:

            return command_usage(&write_cmd);

        }

    }

    if (optind != argc - 2) {

        return command_usage(&write_cmd);

    }

    if (bflag && pflag) {

        printf("-b and -p cannot be specified at the same time\n");

        return 0;

    }

    offset = cvtnum(argv[optind]);

    if (offset < 0) {

        printf("non-numeric length argument -- %s\n", argv[optind]);

        return 0;

    }

    optind++;

    count = cvtnum(argv[optind]);

    if (count < 0) {

        printf("non-numeric length argument -- %s\n", argv[optind]);

        return 0;

    }

    if (!pflag) {

        if (offset & 0x1ff) {

            printf("offset %" PRId64 " is not sector aligned\n",

                   offset);

            return 0;

        }

        if (count & 0x1ff) {

            printf("count %d is not sector aligned\n",

                   count);

            return 0;

        }

    }

    buf = qemu_io_alloc(count, pattern);

    gettimeofday(&t1, NULL);

    if (pflag) {

        cnt = do_pwrite(buf, offset, count, &total);

    } else if (bflag) {

        cnt = do_save_vmstate(buf, offset, count, &total);

    } else {

        cnt = do_write(buf, offset, count, &total);

    }

    gettimeofday(&t2, NULL);

    if (cnt < 0) {

        printf("write failed: %s\n", strerror(-cnt));

        goto out;

    }

    if (qflag) {

        goto out;

    }

    /* Finally, report back -- -C gives a parsable format */

    t2 = tsub(t2, t1);

    print_report("wrote", &t2, offset, count, total, cnt, Cflag);

out:

    qemu_io_free(buf);

    return 0;

}


static int libopenjpeg_copy_packed12(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)

{

    int compno;

    int x, y;

    int *image_line;

    int frame_index;

    const int numcomps  = image->numcomps;

    uint16_t *frame_ptr = (uint16_t *)frame->data[0];

    for (compno = 0; compno < numcomps; ++compno) {

        if (image->comps[compno].w > frame->linesize[0] / numcomps) {

            av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");

            return 0;

        }

    }

    for (compno = 0; compno < numcomps; ++compno) {

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

            image_line = image->comps[compno].data + y * image->comps[compno].w;

            frame_index = y * (frame->linesize[0] / 2) + compno;

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

                image_line[x] = frame_ptr[frame_index] >> 4;

                frame_index += numcomps;

            }

            for (; x < image->comps[compno].w; ++x) {

                image_line[x] = image_line[x - 1];

            }

        }

        for (; y < image->comps[compno].h; ++y) {

            image_line = image->comps[compno].data + y * image->comps[compno].w;

            for (x = 0; x < image->comps[compno].w; ++x) {

                image_line[x] = image_line[x - image->comps[compno].w];

            }

        }

    }

    return 1;

}


static void build_feed_streams(void)

{

    FFStream *stream, *feed;

    int i;

    /* gather all streams */

    for(stream = first_stream; stream != NULL; stream = stream->next) {

        feed = stream->feed;

        if (feed) {

            if (!stream->is_feed) {

                /* we handle a stream coming from a feed */

                for(i=0;i<stream->nb_streams;i++)

                    stream->feed_streams[i] = add_av_stream(feed, stream->streams[i]);

            }

        }

    }

    /* gather all streams */

    for(stream = first_stream; stream != NULL; stream = stream->next) {

        feed = stream->feed;

        if (feed) {

            if (stream->is_feed) {

                for(i=0;i<stream->nb_streams;i++)

                    stream->feed_streams[i] = i;

            }

        }

    }

    /* create feed files if needed */

    for(feed = first_feed; feed != NULL; feed = feed->next_feed) {

        int fd;

        if (url_exist(feed->feed_filename)) {

            /* See if it matches */

            AVFormatContext *s;

            int matches = 0;

            if (av_open_input_file(&s, feed->feed_filename, NULL, FFM_PACKET_SIZE, NULL) >= 0) {

                /* Now see if it matches */

                if (s->nb_streams == feed->nb_streams) {

                    matches = 1;

                    for(i=0;i<s->nb_streams;i++) {

                        AVStream *sf, *ss;

                        sf = feed->streams[i];

                        ss = s->streams[i];

                        if (sf->index != ss->index ||

                            sf->id != ss->id) {

                            http_log("Index & Id do not match for stream %d (%s)\n",

                                   i, feed->feed_filename);

                            matches = 0;

                        } else {

                            AVCodecContext *ccf, *ccs;

                            ccf = sf->codec;

                            ccs = ss->codec;

#define CHECK_CODEC(x)  (ccf->x != ccs->x)

                            if (CHECK_CODEC(codec_id) || CHECK_CODEC(codec_type)) {

                                http_log("Codecs do not match for stream %d\n", i);

                                matches = 0;

                            } else if (CHECK_CODEC(bit_rate) || CHECK_CODEC(flags)) {

                                http_log("Codec bitrates do not match for stream %d\n", i);

                                matches = 0;

                            } else if (ccf->codec_type == AVMEDIA_TYPE_VIDEO) {

                                if (CHECK_CODEC(time_base.den) ||

                                    CHECK_CODEC(time_base.num) ||

                                    CHECK_CODEC(width) ||

                                    CHECK_CODEC(height)) {

                                    http_log("Codec width, height and framerate do not match for stream %d\n", i);

                                    matches = 0;

                                }

                            } else if (ccf->codec_type == AVMEDIA_TYPE_AUDIO) {

                                if (CHECK_CODEC(sample_rate) ||

                                    CHECK_CODEC(channels) ||

                                    CHECK_CODEC(frame_size)) {

                                    http_log("Codec sample_rate, channels, frame_size do not match for stream %d\n", i);

                                    matches = 0;

                                }

                            } else {

                                http_log("Unknown codec type\n");

                                matches = 0;

                            }

                        }

                        if (!matches)

                            break;

                    }

                } else

                    http_log("Deleting feed file '%s' as stream counts differ (%d != %d)\n",

                        feed->feed_filename, s->nb_streams, feed->nb_streams);

                av_close_input_file(s);

            } else

                http_log("Deleting feed file '%s' as it appears to be corrupt\n",

                        feed->feed_filename);

            if (!matches) {

                if (feed->readonly) {

                    http_log("Unable to delete feed file '%s' as it is marked readonly\n",

                        feed->feed_filename);

                    exit(1);

                }

                unlink(feed->feed_filename);

            }

        }

        if (!url_exist(feed->feed_filename)) {

            AVFormatContext s1 = {0}, *s = &s1;

            if (feed->readonly) {

                http_log("Unable to create feed file '%s' as it is marked readonly\n",

                    feed->feed_filename);

                exit(1);

            }

            /* only write the header of the ffm file */

            if (avio_open(&s->pb, feed->feed_filename, AVIO_FLAG_WRITE) < 0) {

                http_log("Could not open output feed file '%s'\n",

                         feed->feed_filename);

                exit(1);

            }

            s->oformat = feed->fmt;

            s->nb_streams = feed->nb_streams;

            for(i=0;i<s->nb_streams;i++) {

                AVStream *st;

                st = feed->streams[i];

                s->streams[i] = st;

            }

            av_set_parameters(s, NULL);

            if (av_write_header(s) < 0) {

                http_log("Container doesn't supports the required parameters\n");

                exit(1);

            }

            /* XXX: need better api */

            av_freep(&s->priv_data);

            avio_close(s->pb);

        }

        /* get feed size and write index */

        fd = open(feed->feed_filename, O_RDONLY);

        if (fd < 0) {

            http_log("Could not open output feed file '%s'\n",

                    feed->feed_filename);

            exit(1);

        }

        feed->feed_write_index = FFMAX(ffm_read_write_index(fd), FFM_PACKET_SIZE);

        feed->feed_size = lseek(fd, 0, SEEK_END);

        /* ensure that we do not wrap before the end of file */

        if (feed->feed_max_size && feed->feed_max_size < feed->feed_size)

            feed->feed_max_size = feed->feed_size;

        close(fd);

    }

}


static void do_interrupt64(CPUX86State *env, int intno, int is_int,

                           int error_code, target_ulong next_eip, int is_hw)

{

    SegmentCache *dt;

    target_ulong ptr;

    int type, dpl, selector, cpl, ist;

    int has_error_code, new_stack;

    uint32_t e1, e2, e3, ss;

    target_ulong old_eip, esp, offset;

    has_error_code = 0;

    if (!is_int && !is_hw) {

        has_error_code = exception_has_error_code(intno);

    }

    if (is_int) {

        old_eip = next_eip;

    } else {

        old_eip = env->eip;

    }

    dt = &env->idt;

    if (intno * 16 + 15 > dt->limit) {

        raise_exception_err(env, EXCP0D_GPF, intno * 16 + 2);

    }

    ptr = dt->base + intno * 16;

    e1 = cpu_ldl_kernel(env, ptr);

    e2 = cpu_ldl_kernel(env, ptr + 4);

    e3 = cpu_ldl_kernel(env, ptr + 8);

    /* check gate type */

    type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;

    switch (type) {

    case 14: /* 386 interrupt gate */

    case 15: /* 386 trap gate */

        break;

    default:

        raise_exception_err(env, EXCP0D_GPF, intno * 16 + 2);

        break;

    }

    dpl = (e2 >> DESC_DPL_SHIFT) & 3;

    cpl = env->hflags & HF_CPL_MASK;

    /* check privilege if software int */

    if (is_int && dpl < cpl) {

        raise_exception_err(env, EXCP0D_GPF, intno * 16 + 2);

    }

    /* check valid bit */

    if (!(e2 & DESC_P_MASK)) {

        raise_exception_err(env, EXCP0B_NOSEG, intno * 16 + 2);

    }

    selector = e1 >> 16;

    offset = ((target_ulong)e3 << 32) | (e2 & 0xffff0000) | (e1 & 0x0000ffff);

    ist = e2 & 7;

    if ((selector & 0xfffc) == 0) {

        raise_exception_err(env, EXCP0D_GPF, 0);

    }

    if (load_segment(env, &e1, &e2, selector) != 0) {

        raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);

    }

    if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) {

        raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);

    }

    dpl = (e2 >> DESC_DPL_SHIFT) & 3;

    if (dpl > cpl) {

        raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);

    }

    if (!(e2 & DESC_P_MASK)) {

        raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc);

    }

    if (!(e2 & DESC_L_MASK) || (e2 & DESC_B_MASK)) {

        raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);

    }

    if ((!(e2 & DESC_C_MASK) && dpl < cpl) || ist != 0) {

        /* to inner privilege */

        new_stack = 1;

        esp = get_rsp_from_tss(env, ist != 0 ? ist + 3 : dpl);

        ss = 0;

    } else if ((e2 & DESC_C_MASK) || dpl == cpl) {

        /* to same privilege */

        if (env->eflags & VM_MASK) {

            raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);

        }

        new_stack = 0;

        esp = env->regs[R_ESP];

        dpl = cpl;

    } else {

        raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);

        new_stack = 0; /* avoid warning */

        esp = 0; /* avoid warning */

    }

    esp &= ~0xfLL; /* align stack */

    PUSHQ(esp, env->segs[R_SS].selector);

    PUSHQ(esp, env->regs[R_ESP]);

    PUSHQ(esp, cpu_compute_eflags(env));

    PUSHQ(esp, env->segs[R_CS].selector);

    PUSHQ(esp, old_eip);

    if (has_error_code) {

        PUSHQ(esp, error_code);

    }

    /* interrupt gate clear IF mask */

    if ((type & 1) == 0) {

        env->eflags &= ~IF_MASK;

    }

    env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);

    if (new_stack) {

        ss = 0 | dpl;

        cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, 0);

    }

    env->regs[R_ESP] = esp;

    selector = (selector & ~3) | dpl;

    cpu_x86_load_seg_cache(env, R_CS, selector,

                   get_seg_base(e1, e2),

                   get_seg_limit(e1, e2),

                   e2);

    env->eip = offset;

}


void palette8tobgr24(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)

{

	long i;

/*

	writes 1 byte o much and might cause alignment issues on some architectures?

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

		((unsigned *)(&dst[i*3])) = ((unsigned *)palette)[ src[i] ];

*/

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

	{

		//FIXME slow?

		dst[0]= palette[ src[i]*4+0 ];

		dst[1]= palette[ src[i]*4+1 ];

		dst[2]= palette[ src[i]*4+2 ];

		dst+= 3;

	}

}


static inline void codeblock(DiracContext *s, SubBand *b,

                             GetBitContext *gb, DiracArith *c,

                             int left, int right, int top, int bottom,

                             int blockcnt_one, int is_arith)

{

    int x, y, zero_block;

    int qoffset, qfactor;

    IDWTELEM *buf;

    /* check for any coded coefficients in this codeblock */

    if (!blockcnt_one) {

        if (is_arith)

            zero_block = dirac_get_arith_bit(c, CTX_ZERO_BLOCK);

        else

            zero_block = get_bits1(gb);

        if (zero_block)

            return;

    }

    if (s->codeblock_mode && !(s->old_delta_quant && blockcnt_one)) {

        if (is_arith)

            b->quant += dirac_get_arith_int(c, CTX_DELTA_Q_F, CTX_DELTA_Q_DATA);

        else

            b->quant += dirac_get_se_golomb(gb);

    }

    b->quant = FFMIN(b->quant, MAX_QUANT);

    qfactor = qscale_tab[b->quant];

    /* TODO: context pointer? */

    if (!s->num_refs)

        qoffset = qoffset_intra_tab[b->quant];

    else

        qoffset = qoffset_inter_tab[b->quant];

    buf = b->ibuf + top * b->stride;

    for (y = top; y < bottom; y++) {

        for (x = left; x < right; x++) {

            /* [DIRAC_STD] 13.4.4 Subband coefficients. coeff_unpack() */

            if (is_arith)

                coeff_unpack_arith(c, qfactor, qoffset, b, buf+x, x, y);

            else

                buf[x] = coeff_unpack_golomb(gb, qfactor, qoffset);

        }

        buf += b->stride;

    }

}


static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){

    FFV1Context *f = avctx->priv_data;

    CABACContext * const c= &f->c;

    AVFrame *pict = data;

    const int width= f->width;

    const int height= f->height;

    AVFrame * const p= &f->picture;

    int used_count= 0;

    if(avctx->strict_std_compliance >= 0){

        av_log(avctx, AV_LOG_ERROR, "this codec is under development, files encoded with it wont be decodeable with future versions!!!\n"

               "use vstrict=-1 to use it anyway\n");

        return -1;

    }

    ff_init_cabac_encoder(c, buf, buf_size);

    ff_init_cabac_states(c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64);

    c->lps_state[2] = 1;

    c->lps_state[3] = 0;

    *p = *pict;

    p->pict_type= FF_I_TYPE;

    if(avctx->gop_size==0 || f->picture_number % avctx->gop_size == 0){

        put_cabac_bypass(c, 1);

        p->key_frame= 1;

        write_header(f);

        clear_state(f);

    }else{

        put_cabac_bypass(c, 0);

        p->key_frame= 0;

    }

    if(!f->ac){

        used_count += put_cabac_terminate(c, 1);

//printf("pos=%d\n", used_count);

        init_put_bits(&f->pb, buf + used_count, buf_size - used_count);

    }

    if(f->colorspace==0){

        const int chroma_width = -((-width )>>f->chroma_h_shift);

        const int chroma_height= -((-height)>>f->chroma_v_shift);

        encode_plane(f, p->data[0], width, height, p->linesize[0], 0);

        encode_plane(f, p->data[1], chroma_width, chroma_height, p->linesize[1], 1);

        encode_plane(f, p->data[2], chroma_width, chroma_height, p->linesize[2], 1);

    }else{

        encode_rgb_frame(f, (uint32_t*)(p->data[0]), width, height, p->linesize[0]/4);

    }

    emms_c();

    f->picture_number++;

    if(f->ac){

        return put_cabac_terminate(c, 1);

    }else{

        flush_put_bits(&f->pb); //nicer padding FIXME

        return used_count + (put_bits_count(&f->pb)+7)/8;

    }

}


static void qed_aio_read_data(void *opaque, int ret,

                              uint64_t offset, size_t len)

{

    QEDAIOCB *acb = opaque;

    BDRVQEDState *s = acb_to_s(acb);

    BlockDriverState *bs = acb->common.bs;

    /* Adjust offset into cluster */

    offset += qed_offset_into_cluster(s, acb->cur_pos);

    trace_qed_aio_read_data(s, acb, ret, offset, len);

    if (ret < 0) {

        goto err;

    }

    qemu_iovec_concat(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);

    /* Handle zero cluster and backing file reads */

    if (ret == QED_CLUSTER_ZERO) {

        qemu_iovec_memset(&acb->cur_qiov, 0, 0, acb->cur_qiov.size);

        qed_aio_next_io(acb, 0);

        return;

    } else if (ret != QED_CLUSTER_FOUND) {

        qed_read_backing_file(s, acb->cur_pos, &acb->cur_qiov,

                              qed_aio_next_io, acb);

        return;

    }

    BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);

    bdrv_aio_readv(bs->file, offset / BDRV_SECTOR_SIZE,

                   &acb->cur_qiov, acb->cur_qiov.size / BDRV_SECTOR_SIZE,

                   qed_aio_next_io, acb);

    return;

err:

    qed_aio_complete(acb, ret);

}


int qcow2_update_header(BlockDriverState *bs)

{

    BDRVQcowState *s = bs->opaque;

    QCowHeader *header;

    char *buf;

    size_t buflen = s->cluster_size;

    int ret;

    uint64_t total_size;

    uint32_t refcount_table_clusters;

    size_t header_length;

    Qcow2UnknownHeaderExtension *uext;

    buf = qemu_blockalign(bs, buflen);

    /* Header structure */

    header = (QCowHeader*) buf;

    if (buflen < sizeof(*header)) {

        ret = -ENOSPC;

        goto fail;

    }

    header_length = sizeof(*header) + s->unknown_header_fields_size;

    total_size = bs->total_sectors * BDRV_SECTOR_SIZE;

    refcount_table_clusters = s->refcount_table_size >> (s->cluster_bits - 3);

    *header = (QCowHeader) {

        /* Version 2 fields */

        .magic                  = cpu_to_be32(QCOW_MAGIC),

        .version                = cpu_to_be32(s->qcow_version),

        .backing_file_offset    = 0,

        .backing_file_size      = 0,

        .cluster_bits           = cpu_to_be32(s->cluster_bits),

        .size                   = cpu_to_be64(total_size),

        .crypt_method           = cpu_to_be32(s->crypt_method_header),

        .l1_size                = cpu_to_be32(s->l1_size),

        .l1_table_offset        = cpu_to_be64(s->l1_table_offset),

        .refcount_table_offset  = cpu_to_be64(s->refcount_table_offset),

        .refcount_table_clusters = cpu_to_be32(refcount_table_clusters),

        .nb_snapshots           = cpu_to_be32(s->nb_snapshots),

        .snapshots_offset       = cpu_to_be64(s->snapshots_offset),

        /* Version 3 fields */

        .incompatible_features  = cpu_to_be64(s->incompatible_features),

        .compatible_features    = cpu_to_be64(s->compatible_features),

        .autoclear_features     = cpu_to_be64(s->autoclear_features),

        .refcount_order         = cpu_to_be32(3 + REFCOUNT_SHIFT),

        .header_length          = cpu_to_be32(header_length),

    };

    /* For older versions, write a shorter header */

    switch (s->qcow_version) {

    case 2:

        ret = offsetof(QCowHeader, incompatible_features);

        break;

    case 3:

        ret = sizeof(*header);

        break;

    default:

        return -EINVAL;

    }

    buf += ret;

    buflen -= ret;

    memset(buf, 0, buflen);

    /* Preserve any unknown field in the header */

    if (s->unknown_header_fields_size) {

        if (buflen < s->unknown_header_fields_size) {

            ret = -ENOSPC;

            goto fail;

        }

        memcpy(buf, s->unknown_header_fields, s->unknown_header_fields_size);

        buf += s->unknown_header_fields_size;

        buflen -= s->unknown_header_fields_size;

    }

    /* Backing file format header extension */

    if (*bs->backing_format) {

        ret = header_ext_add(buf, QCOW2_EXT_MAGIC_BACKING_FORMAT,

                             bs->backing_format, strlen(bs->backing_format),

                             buflen);

        if (ret < 0) {

            goto fail;

        }

        buf += ret;

        buflen -= ret;

    }

    /* Feature table */

    Qcow2Feature features[] = {

        /* no feature defined yet */

    };

    ret = header_ext_add(buf, QCOW2_EXT_MAGIC_FEATURE_TABLE,

                         features, sizeof(features), buflen);

    if (ret < 0) {

        goto fail;

    }

    buf += ret;

    buflen -= ret;

    /* Keep unknown header extensions */

    QLIST_FOREACH(uext, &s->unknown_header_ext, next) {

        ret = header_ext_add(buf, uext->magic, uext->data, uext->len, buflen);

        if (ret < 0) {

            goto fail;

        }

        buf += ret;

        buflen -= ret;

    }

    /* End of header extensions */

    ret = header_ext_add(buf, QCOW2_EXT_MAGIC_END, NULL, 0, buflen);

    if (ret < 0) {

        goto fail;

    }

    buf += ret;

    buflen -= ret;

    /* Backing file name */

    if (*bs->backing_file) {

        size_t backing_file_len = strlen(bs->backing_file);

        if (buflen < backing_file_len) {

            ret = -ENOSPC;

            goto fail;

        }

        strncpy(buf, bs->backing_file, buflen);

        header->backing_file_offset = cpu_to_be64(buf - ((char*) header));

        header->backing_file_size   = cpu_to_be32(backing_file_len);

    }

    /* Write the new header */

    ret = bdrv_pwrite(bs->file, 0, header, s->cluster_size);

    if (ret < 0) {

        goto fail;

    }

    ret = 0;

fail:

    qemu_vfree(header);

    return ret;

}


void tcp_start_incoming_migration(const char *host_port, Error **errp)

{

    int s;

    s = inet_listen(host_port, NULL, 256, SOCK_STREAM, 0, errp);

    if (s < 0) {

        return;

    }

    qemu_set_fd_handler2(s, NULL, tcp_accept_incoming_migration, NULL,

                         (void *)(intptr_t)s);

}


static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset,

                                       sPAPRPHBState *sphb)

{

    ResourceProps rp;

    bool is_bridge = false;

    int pci_status, err;

    char *buf = NULL;

    uint32_t drc_index = spapr_phb_get_pci_drc_index(sphb, dev);

    uint32_t ccode = pci_default_read_config(dev, PCI_CLASS_PROG, 3);

    uint32_t max_msi, max_msix;

    if (pci_default_read_config(dev, PCI_HEADER_TYPE, 1) ==

        PCI_HEADER_TYPE_BRIDGE) {

        is_bridge = true;

    }

    /* in accordance with PAPR+ v2.7 13.6.3, Table 181 */

    _FDT(fdt_setprop_cell(fdt, offset, "vendor-id",

                          pci_default_read_config(dev, PCI_VENDOR_ID, 2)));

    _FDT(fdt_setprop_cell(fdt, offset, "device-id",

                          pci_default_read_config(dev, PCI_DEVICE_ID, 2)));

    _FDT(fdt_setprop_cell(fdt, offset, "revision-id",

                          pci_default_read_config(dev, PCI_REVISION_ID, 1)));

    _FDT(fdt_setprop_cell(fdt, offset, "class-code", ccode));

    if (pci_default_read_config(dev, PCI_INTERRUPT_PIN, 1)) {

        _FDT(fdt_setprop_cell(fdt, offset, "interrupts",

                 pci_default_read_config(dev, PCI_INTERRUPT_PIN, 1)));

    }

    if (!is_bridge) {

        _FDT(fdt_setprop_cell(fdt, offset, "min-grant",

            pci_default_read_config(dev, PCI_MIN_GNT, 1)));

        _FDT(fdt_setprop_cell(fdt, offset, "max-latency",

            pci_default_read_config(dev, PCI_MAX_LAT, 1)));

    }

    if (pci_default_read_config(dev, PCI_SUBSYSTEM_ID, 2)) {

        _FDT(fdt_setprop_cell(fdt, offset, "subsystem-id",

                 pci_default_read_config(dev, PCI_SUBSYSTEM_ID, 2)));

    }

    if (pci_default_read_config(dev, PCI_SUBSYSTEM_VENDOR_ID, 2)) {

        _FDT(fdt_setprop_cell(fdt, offset, "subsystem-vendor-id",

                 pci_default_read_config(dev, PCI_SUBSYSTEM_VENDOR_ID, 2)));

    }

    _FDT(fdt_setprop_cell(fdt, offset, "cache-line-size",

        pci_default_read_config(dev, PCI_CACHE_LINE_SIZE, 1)));

    /* the following fdt cells are masked off the pci status register */

    pci_status = pci_default_read_config(dev, PCI_STATUS, 2);

    _FDT(fdt_setprop_cell(fdt, offset, "devsel-speed",

                          PCI_STATUS_DEVSEL_MASK & pci_status));

    if (pci_status & PCI_STATUS_FAST_BACK) {

        _FDT(fdt_setprop(fdt, offset, "fast-back-to-back", NULL, 0));

    }

    if (pci_status & PCI_STATUS_66MHZ) {

        _FDT(fdt_setprop(fdt, offset, "66mhz-capable", NULL, 0));

    }

    if (pci_status & PCI_STATUS_UDF) {

        _FDT(fdt_setprop(fdt, offset, "udf-supported", NULL, 0));

    }

    _FDT(fdt_setprop_string(fdt, offset, "name",

                            pci_find_device_name((ccode >> 16) & 0xff,

                                                 (ccode >> 8) & 0xff,

                                                 ccode & 0xff)));

    buf = spapr_phb_get_loc_code(sphb, dev);

    if (!buf) {

        error_report("Failed setting the ibm,loc-code");

        return -1;

    }

    err = fdt_setprop_string(fdt, offset, "ibm,loc-code", buf);

    g_free(buf);

    if (err < 0) {

        return err;

    }

    if (drc_index) {

        _FDT(fdt_setprop_cell(fdt, offset, "ibm,my-drc-index", drc_index));

    }

    _FDT(fdt_setprop_cell(fdt, offset, "#address-cells",

                          RESOURCE_CELLS_ADDRESS));

    _FDT(fdt_setprop_cell(fdt, offset, "#size-cells",

                          RESOURCE_CELLS_SIZE));

    max_msi = msi_nr_vectors_allocated(dev);

    if (max_msi) {

        _FDT(fdt_setprop_cell(fdt, offset, "ibm,req#msi", max_msi));

    }

    max_msix = dev->msix_entries_nr;

    if (max_msix) {

        _FDT(fdt_setprop_cell(fdt, offset, "ibm,req#msi-x", max_msix));

    }

    populate_resource_props(dev, &rp);

    _FDT(fdt_setprop(fdt, offset, "reg", (uint8_t *)rp.reg, rp.reg_len));

    _FDT(fdt_setprop(fdt, offset, "assigned-addresses",

                     (uint8_t *)rp.assigned, rp.assigned_len));

    if (sphb->pcie_ecs && pci_is_express(dev)) {

        _FDT(fdt_setprop_cell(fdt, offset, "ibm,pci-config-space-type", 0x1));

    }

    return 0;

}


static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb)

{

    MLPHeaderInfo mh;

    int substr, ret;

    if ((ret = ff_mlp_read_major_sync(m->avctx, &mh, gb)) != 0)

        return ret;

    if (mh.group1_bits == 0) {

        av_log(m->avctx, AV_LOG_ERROR, "invalid/unknown bits per sample\n");

        return AVERROR_INVALIDDATA;

    if (mh.group2_bits > mh.group1_bits) {

        av_log(m->avctx, AV_LOG_ERROR,

               "Channel group 2 cannot have more bits per sample than group 1.\n");

        return AVERROR_INVALIDDATA;

    if (mh.group2_samplerate && mh.group2_samplerate != mh.group1_samplerate) {

        av_log(m->avctx, AV_LOG_ERROR,

               "Channel groups with differing sample rates are not currently supported.\n");

        return AVERROR_INVALIDDATA;

    if (mh.group1_samplerate == 0) {

        av_log(m->avctx, AV_LOG_ERROR, "invalid/unknown sampling rate\n");

        return AVERROR_INVALIDDATA;

    if (mh.group1_samplerate > MAX_SAMPLERATE) {

        av_log(m->avctx, AV_LOG_ERROR,

               "Sampling rate %d is greater than the supported maximum (%d).\n",

               mh.group1_samplerate, MAX_SAMPLERATE);

        return AVERROR_INVALIDDATA;

    if (mh.access_unit_size > MAX_BLOCKSIZE) {

        av_log(m->avctx, AV_LOG_ERROR,

               "Block size %d is greater than the supported maximum (%d).\n",

               mh.access_unit_size, MAX_BLOCKSIZE);

        return AVERROR_INVALIDDATA;

    if (mh.access_unit_size_pow2 > MAX_BLOCKSIZE_POW2) {

        av_log(m->avctx, AV_LOG_ERROR,

               "Block size pow2 %d is greater than the supported maximum (%d).\n",

               mh.access_unit_size_pow2, MAX_BLOCKSIZE_POW2);

        return AVERROR_INVALIDDATA;

    if (mh.num_substreams == 0)

        return AVERROR_INVALIDDATA;

    if (m->avctx->codec_id == AV_CODEC_ID_MLP && mh.num_substreams > 2) {

        av_log(m->avctx, AV_LOG_ERROR, "MLP only supports up to 2 substreams.\n");

        return AVERROR_INVALIDDATA;

    if (mh.num_substreams > MAX_SUBSTREAMS) {

                              "%d substreams (more than the "

                              "maximum supported by the decoder)",

                              mh.num_substreams);

    m->access_unit_size      = mh.access_unit_size;

    m->access_unit_size_pow2 = mh.access_unit_size_pow2;

    m->num_substreams        = mh.num_substreams;

    m->max_decoded_substream = m->num_substreams - 1;

    m->avctx->sample_rate    = mh.group1_samplerate;

    m->avctx->frame_size     = mh.access_unit_size;

    m->avctx->bits_per_raw_sample = mh.group1_bits;

    if (mh.group1_bits > 16)

        m->avctx->sample_fmt = AV_SAMPLE_FMT_S32;

    else

        m->avctx->sample_fmt = AV_SAMPLE_FMT_S16;

    m->params_valid = 1;

    for (substr = 0; substr < MAX_SUBSTREAMS; substr++)

        m->substream[substr].restart_seen = 0;

    /* Set the layout for each substream. When there's more than one, the first

     * substream is Stereo. Subsequent substreams' layouts are indicated in the

     * major sync. */

    if (m->avctx->codec_id == AV_CODEC_ID_MLP) {

        if ((substr = (mh.num_substreams > 1)))

            m->substream[0].ch_layout = AV_CH_LAYOUT_STEREO;

        m->substream[substr].ch_layout = mh.channel_layout_mlp;

    } else {

        if ((substr = (mh.num_substreams > 1)))

            m->substream[0].ch_layout = AV_CH_LAYOUT_STEREO;

        if (mh.num_substreams > 2)

            if (mh.channel_layout_thd_stream2)

                m->substream[2].ch_layout = mh.channel_layout_thd_stream2;

            else

                m->substream[2].ch_layout = mh.channel_layout_thd_stream1;

        m->substream[substr].ch_layout = mh.channel_layout_thd_stream1;

        if (m->avctx->channels<=2 && m->substream[substr].ch_layout == AV_CH_LAYOUT_MONO && m->max_decoded_substream == 1) {

            av_log(m->avctx, AV_LOG_DEBUG, "Mono stream with 2 substreams, ignoring 2nd\n");

            m->max_decoded_substream = 0;

            if (m->avctx->channels==2)

                m->avctx->channel_layout = AV_CH_LAYOUT_STEREO;

    m->needs_reordering = mh.channel_arrangement >= 18 && mh.channel_arrangement <= 20;

    return 0;


static AVStream * init_stream(AVFormatContext *s)

{

    BinDemuxContext *bin = s->priv_data;

    AVStream *st = avformat_new_stream(s, NULL);

    if (!st)

        return NULL;

    st->codec->codec_tag   = 0;

    st->codec->codec_type  = AVMEDIA_TYPE_VIDEO;

    if (!bin->width) {

        st->codec->width  = (80<<3);

        st->codec->height = (25<<4);

    }

    avpriv_set_pts_info(st, 60, bin->framerate.den, bin->framerate.num);

    /* simulate tty display speed */

    bin->chars_per_frame = FFMAX(av_q2d(st->time_base) * bin->chars_per_frame, 1);

    return st;

}


static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num,

                        int nb_sectors, QEMUIOVector *qiov)

{

    SheepdogAIOCB *acb;

    int ret;

    if (bs->growable && sector_num + nb_sectors > bs->total_sectors) {

        ret = sd_truncate(bs, (sector_num + nb_sectors) * BDRV_SECTOR_SIZE);

        if (ret < 0) {

            return ret;

        }

        bs->total_sectors = sector_num + nb_sectors;

    }

    acb = sd_aio_setup(bs, qiov, sector_num, nb_sectors);

    acb->aio_done_func = sd_write_done;

    acb->aiocb_type = AIOCB_WRITE_UDATA;

    ret = sd_co_rw_vector(acb);

    if (ret <= 0) {

        qemu_aio_release(acb);

        return ret;

    }

    qemu_coroutine_yield();

    return acb->ret;

}


static void sdl_send_mouse_event(int dx, int dy, int x, int y, int state)

{

    static uint32_t bmap[INPUT_BUTTON__MAX] = {

        [INPUT_BUTTON_LEFT]       = SDL_BUTTON(SDL_BUTTON_LEFT),

        [INPUT_BUTTON_MIDDLE]     = SDL_BUTTON(SDL_BUTTON_MIDDLE),

        [INPUT_BUTTON_RIGHT]      = SDL_BUTTON(SDL_BUTTON_RIGHT),

        [INPUT_BUTTON_WHEEL_UP]   = SDL_BUTTON(SDL_BUTTON_WHEELUP),

        [INPUT_BUTTON_WHEEL_DOWN] = SDL_BUTTON(SDL_BUTTON_WHEELDOWN),

    };

    static uint32_t prev_state;

    if (prev_state != state) {

        qemu_input_update_buttons(dcl->con, bmap, prev_state, state);

        prev_state = state;

    }

    if (qemu_input_is_absolute()) {

        qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, x,

                             real_screen->w);

        qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, y,

                             real_screen->h);

    } else {

        if (guest_cursor) {

            x -= guest_x;

            y -= guest_y;

            guest_x += x;

            guest_y += y;

            dx = x;

            dy = y;

        }

        qemu_input_queue_rel(dcl->con, INPUT_AXIS_X, dx);

        qemu_input_queue_rel(dcl->con, INPUT_AXIS_Y, dy);

    }

    qemu_input_event_sync();

}


static void device_initfn(Object *obj)

{

    DeviceState *dev = DEVICE(obj);

    Property *prop;

    if (qdev_hotplug) {

        dev->hotplugged = 1;

        qdev_hot_added = true;

    }

    dev->instance_id_alias = -1;

    dev->state = DEV_STATE_CREATED;

    qdev_prop_set_defaults(dev, qdev_get_props(dev));

    for (prop = qdev_get_props(dev); prop && prop->name; prop++) {

        qdev_property_add_legacy(dev, prop, NULL);

        qdev_property_add_static(dev, prop, NULL);

    }

    object_property_add_str(OBJECT(dev), "type", qdev_get_type, NULL, NULL);

}


static void scsi_write_data(SCSIRequest *req)

{

    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);

    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);

    uint32_t n;

    /* No data transfer may already be in progress */

    assert(r->req.aiocb == NULL);

    /* The request is used as the AIO opaque value, so add a ref.  */

    scsi_req_ref(&r->req);

    if (r->req.cmd.mode != SCSI_XFER_TO_DEV) {

        DPRINTF("Data transfer direction invalid\n");

        scsi_write_complete(r, -EINVAL);

        return;

    }

    if (!r->req.sg && !r->qiov.size) {

        /* Called for the first time.  Ask the driver to send us more data.  */

        r->started = true;

        scsi_write_complete(r, 0);

        return;

    }

    if (s->tray_open) {

        scsi_write_complete(r, -ENOMEDIUM);

        return;

    }

    if (r->req.cmd.buf[0] == VERIFY_10 || r->req.cmd.buf[0] == VERIFY_12 ||

        r->req.cmd.buf[0] == VERIFY_16) {

        if (r->req.sg) {

            scsi_dma_complete(r, 0);

        } else {

            scsi_write_complete(r, 0);

        }

        return;

    }

    if (r->req.sg) {

        dma_acct_start(s->qdev.conf.bs, &r->acct, r->req.sg, BDRV_ACCT_WRITE);

        r->req.resid -= r->req.sg->size;

        r->req.aiocb = dma_bdrv_write(s->qdev.conf.bs, r->req.sg, r->sector,

                                      scsi_dma_complete, r);

    } else {

        n = r->qiov.size / 512;

        bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE);

        r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, r->sector, &r->qiov, n,

                                       scsi_write_complete, r);

    }

}


static void idiv64(uint64_t *plow, uint64_t *phigh, int64_t b)

{

    int sa, sb;

    sa = ((int64_t)*phigh < 0);

    if (sa)

        neg128(plow, phigh);

    sb = (b < 0);

    if (sb)

        b = -b;

    div64(plow, phigh, b);

    if (sa ^ sb)

        *plow = - *plow;

    if (sa)

        *phigh = - *phigh;

}


void bios_linker_loader_alloc(GArray *linker,

                              const char *file,

                              uint32_t alloc_align,

                              bool alloc_fseg)

{

    BiosLinkerLoaderEntry entry;

    assert(!(alloc_align & (alloc_align - 1)));

    memset(&entry, 0, sizeof entry);

    strncpy(entry.alloc.file, file, sizeof entry.alloc.file - 1);

    entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ALLOCATE);

    entry.alloc.align = cpu_to_le32(alloc_align);

    entry.alloc.zone = cpu_to_le32(alloc_fseg ?

                                    BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG :

                                    BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH);

    /* Alloc entries must come first, so prepend them */

    g_array_prepend_vals(linker, &entry, sizeof entry);

}


static void iscsi_refresh_limits(BlockDriverState *bs, Error **errp)

{

    /* We don't actually refresh here, but just return data queried in

     * iscsi_open(): iscsi targets don't change their limits. */

    IscsiLun *iscsilun = bs->opaque;

    uint64_t max_xfer_len = iscsilun->use_16_for_rw ? 0xffffffff : 0xffff;

    bs->bl.request_alignment = iscsilun->block_size;

    if (iscsilun->bl.max_xfer_len) {

        max_xfer_len = MIN(max_xfer_len, iscsilun->bl.max_xfer_len);

    }

    if (max_xfer_len * iscsilun->block_size < INT_MAX) {

        bs->bl.max_transfer = max_xfer_len * iscsilun->block_size;

    }

    if (iscsilun->lbp.lbpu) {

        if (iscsilun->bl.max_unmap < 0xffffffff / iscsilun->block_size) {

            bs->bl.max_pdiscard =

                iscsilun->bl.max_unmap * iscsilun->block_size;

        }

        bs->bl.pdiscard_alignment =

            iscsilun->bl.opt_unmap_gran * iscsilun->block_size;

    } else {

        bs->bl.pdiscard_alignment = iscsilun->block_size;

    }

    if (iscsilun->bl.max_ws_len < 0xffffffff / iscsilun->block_size) {

        bs->bl.max_pwrite_zeroes =

            iscsilun->bl.max_ws_len * iscsilun->block_size;

    }

    if (iscsilun->lbp.lbpws) {

        bs->bl.pwrite_zeroes_alignment =

            iscsilun->bl.opt_unmap_gran * iscsilun->block_size;

    } else {

        bs->bl.pwrite_zeroes_alignment = iscsilun->block_size;

    }

    if (iscsilun->bl.opt_xfer_len &&

        iscsilun->bl.opt_xfer_len < INT_MAX / iscsilun->block_size) {

        bs->bl.opt_transfer = pow2floor(iscsilun->bl.opt_xfer_len *

                                        iscsilun->block_size);

    }

}


static void tap_receive(void *opaque, const uint8_t *buf, size_t size)

{

    TAPState *s = opaque;

    int ret;

    for(;;) {

        ret = write(s->fd, buf, size);

        if (ret < 0 && (errno == EINTR || errno == EAGAIN)) {

        } else {

            break;

        }

    }

}


static void scsi_disk_realize(SCSIDevice *dev, Error **errp)

{

    DriveInfo *dinfo;

    Error *local_err = NULL;

    if (!dev->conf.bs) {

        scsi_realize(dev, &local_err);

        assert(local_err);

        error_propagate(errp, local_err);

        return;

    }

    dinfo = drive_get_by_blockdev(dev->conf.bs);

    if (dinfo->media_cd) {

        scsi_cd_realize(dev, errp);

    } else {

        scsi_hd_realize(dev, errp);

    }

}


static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)

{

    BDRVSheepdogState *s = bs->opaque;

    int ret, fd;

    uint32_t new_vid;

    SheepdogInode *inode;

    unsigned int datalen;

    dprintf("sn_info: name %s id_str %s s: name %s vm_state_size %" PRId64 " "

            "is_snapshot %d\n", sn_info->name, sn_info->id_str,

            s->name, sn_info->vm_state_size, s->is_snapshot);

    if (s->is_snapshot) {

        error_report("You can't create a snapshot of a snapshot VDI, "

                     "%s (%" PRIu32 ").", s->name, s->inode.vdi_id);

        return -EINVAL;

    }

    dprintf("%s %s\n", sn_info->name, sn_info->id_str);

    s->inode.vm_state_size = sn_info->vm_state_size;

    s->inode.vm_clock_nsec = sn_info->vm_clock_nsec;

    /* It appears that inode.tag does not require a NUL terminator,

     * which means this use of strncpy is ok.

     */

    strncpy(s->inode.tag, sn_info->name, sizeof(s->inode.tag));

    /* we don't need to update entire object */

    datalen = SD_INODE_SIZE - sizeof(s->inode.data_vdi_id);

    /* refresh inode. */

    fd = connect_to_sdog(s->addr, s->port);

    if (fd < 0) {

        ret = fd;

        goto cleanup;

    }

    ret = write_object(fd, (char *)&s->inode, vid_to_vdi_oid(s->inode.vdi_id),

                       s->inode.nr_copies, datalen, 0, false, s->cache_enabled);

    if (ret < 0) {

        error_report("failed to write snapshot's inode.");

        goto cleanup;

    }

    ret = do_sd_create(s->name, s->inode.vdi_size, s->inode.vdi_id, &new_vid, 1,

                       s->addr, s->port);

    if (ret < 0) {

        error_report("failed to create inode for snapshot. %s",

                     strerror(errno));

        goto cleanup;

    }

    inode = (SheepdogInode *)g_malloc(datalen);

    ret = read_object(fd, (char *)inode, vid_to_vdi_oid(new_vid),

                      s->inode.nr_copies, datalen, 0, s->cache_enabled);

    if (ret < 0) {

        error_report("failed to read new inode info. %s", strerror(errno));

        goto cleanup;

    }

    memcpy(&s->inode, inode, datalen);

    dprintf("s->inode: name %s snap_id %x oid %x\n",

            s->inode.name, s->inode.snap_id, s->inode.vdi_id);

cleanup:

    closesocket(fd);

    return ret;

}


static int vnc_display_listen(VncDisplay *vd,

                              SocketAddress **saddr,

                              size_t nsaddr,

                              SocketAddress **wsaddr,

                              size_t nwsaddr,

                              Error **errp)

{

    size_t i;

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

        if (vnc_display_listen_addr(vd, saddr[i],

                                    "vnc-listen",

                                    &vd->lsock,

                                    &vd->lsock_tag,

                                    &vd->nlsock,

                                    errp) < 0) {

            return -1;

        }

    }

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

        if (vnc_display_listen_addr(vd, wsaddr[i],

                                    "vnc-ws-listen",

                                    &vd->lwebsock,

                                    &vd->lwebsock_tag,

                                    &vd->nlwebsock,

                                    errp) < 0) {

            return -1;

        }

    }

    return 0;

}


static char *enumerate_cpus(unsigned long *cpus, int max_cpus)

{

    int cpu;

    bool first = true;

    GString *s = g_string_new(NULL);

    for (cpu = find_first_bit(cpus, max_cpus);

        cpu < max_cpus;

        cpu = find_next_bit(cpus, max_cpus, cpu + 1)) {

        g_string_append_printf(s, "%s%d", first ? "" : " ", cpu);

        first = false;

    }

    return g_string_free(s, FALSE);

}


MigrationState *exec_start_outgoing_migration(const char *command,

                                             int64_t bandwidth_limit,

                                             int async)

{

    FdMigrationState *s;

    FILE *f;

    s = qemu_mallocz(sizeof(*s));

    if (s == NULL) {

        dprintf("Unable to allocate FdMigrationState\n");

        goto err;

    }

    f = popen(command, "w");

    if (f == NULL) {

        dprintf("Unable to popen exec target\n");

        goto err_after_alloc;

    }

    s->fd = fileno(f);

    if (s->fd == -1) {

        dprintf("Unable to retrieve file descriptor for popen'd handle\n");

        goto err_after_open;

    }

    if (fcntl(s->fd, F_SETFD, O_NONBLOCK) == -1) {

        dprintf("Unable to set nonblocking mode on file descriptor\n");

        goto err_after_open;

    }

    s->opaque = qemu_popen(f, "w");

    s->get_error = file_errno;

    s->write = file_write;

    s->mig_state.cancel = migrate_fd_cancel;

    s->mig_state.get_status = migrate_fd_get_status;

    s->mig_state.release = migrate_fd_release;

    s->state = MIG_STATE_ACTIVE;

    s->detach = !async;

    s->bandwidth_limit = bandwidth_limit;

    if (s->detach == 1) {

        dprintf("detaching from monitor\n");

        monitor_suspend();

        s->detach = 2;

    }

    migrate_fd_connect(s);

    return &s->mig_state;

err_after_open:

    pclose(f);

err_after_alloc:

    qemu_free(s);

err:

    return NULL;

}


static void register_core_rtas(void)

{

    spapr_rtas_register("display-character", rtas_display_character);

    spapr_rtas_register("get-time-of-day", rtas_get_time_of_day);

    spapr_rtas_register("power-off", rtas_power_off);

}


static target_ulong h_put_tce(CPUPPCState *env, sPAPREnvironment *spapr,

                              target_ulong opcode, target_ulong *args)

{

    target_ulong liobn = args[0];

    target_ulong ioba = args[1];

    target_ulong tce = args[2];

    VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, liobn);

    VIOsPAPR_RTCE *rtce;

    if (!dev) {

        hcall_dprintf("LIOBN 0x" TARGET_FMT_lx " does not exist\n", liobn);

        return H_PARAMETER;

    }

    ioba &= ~(SPAPR_VIO_TCE_PAGE_SIZE - 1);

#ifdef DEBUG_TCE

    fprintf(stderr, "spapr_vio_put_tce on %s  ioba 0x" TARGET_FMT_lx

            "  TCE 0x" TARGET_FMT_lx "\n", dev->qdev.id, ioba, tce);

#endif

    if (ioba >= dev->rtce_window_size) {

        hcall_dprintf("Out-of-bounds IOBA 0x" TARGET_FMT_lx "\n", ioba);

        return H_PARAMETER;

    }

    rtce = dev->rtce_table + (ioba >> SPAPR_VIO_TCE_PAGE_SHIFT);

    rtce->tce = tce;

    return H_SUCCESS;

}


static void nvme_get_bootindex(Object *obj, Visitor *v, void *opaque,

                                  const char *name, Error **errp)

{

    NvmeCtrl *s = NVME(obj);

    visit_type_int32(v, &s->conf.bootindex, name, errp);

}


ff_rm_parse_packet (AVFormatContext *s, AVIOContext *pb,

                    AVStream *st, RMStream *ast, int len, AVPacket *pkt,

                    int *seq, int flags, int64_t timestamp)

{

    RMDemuxContext *rm = s->priv_data;

    int ret;

    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {

        rm->current_stream= st->id;

        ret = rm_assemble_video_frame(s, pb, rm, ast, pkt, len, seq, &timestamp);

        if(ret)

            return ret < 0 ? ret : -1; //got partial frame or error

    } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {

        if ((ast->deint_id == DEINT_ID_GENR) ||

            (ast->deint_id == DEINT_ID_INT4) ||

            (ast->deint_id == DEINT_ID_SIPR)) {

            int x;

            int sps = ast->sub_packet_size;

            int cfs = ast->coded_framesize;

            int h = ast->sub_packet_h;

            int y = ast->sub_packet_cnt;

            int w = ast->audio_framesize;

            if (flags & 2)

                y = ast->sub_packet_cnt = 0;

            if (!y)

                ast->audiotimestamp = timestamp;

            switch (ast->deint_id) {

                case DEINT_ID_INT4:

                    for (x = 0; x < h/2; x++)

                        avio_read(pb, ast->pkt.data+x*2*w+y*cfs, cfs);

                    break;

                case DEINT_ID_GENR:

                    for (x = 0; x < w/sps; x++)

                        avio_read(pb, ast->pkt.data+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps);

                    break;

                case DEINT_ID_SIPR:

                    avio_read(pb, ast->pkt.data + y * w, w);

                    break;

            }

            if (++(ast->sub_packet_cnt) < h)

                return -1;

            if (ast->deint_id == DEINT_ID_SIPR)

                ff_rm_reorder_sipr_data(ast->pkt.data, h, w);

             ast->sub_packet_cnt = 0;

             rm->audio_stream_num = st->index;

             rm->audio_pkt_cnt = h * w / st->codec->block_align;

        } else if ((ast->deint_id == DEINT_ID_VBRF) ||

                   (ast->deint_id == DEINT_ID_VBRS)) {

            int x;

            rm->audio_stream_num = st->index;

            ast->sub_packet_cnt = (avio_rb16(pb) & 0xf0) >> 4;

            if (ast->sub_packet_cnt) {

                for (x = 0; x < ast->sub_packet_cnt; x++)

                    ast->sub_packet_lengths[x] = avio_rb16(pb);

                rm->audio_pkt_cnt = ast->sub_packet_cnt;

                ast->audiotimestamp = timestamp;

            } else

                return -1;

        } else {

            av_get_packet(pb, pkt, len);

            rm_ac3_swap_bytes(st, pkt);

        }

    } else

        av_get_packet(pb, pkt, len);

    pkt->stream_index = st->index;

#if 0

    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {

        if(st->codec->codec_id == AV_CODEC_ID_RV20){

            int seq= 128*(pkt->data[2]&0x7F) + (pkt->data[3]>>1);

            av_log(s, AV_LOG_DEBUG, "%d %"PRId64" %d\n", *timestamp, *timestamp*512LL/25, seq);

            seq |= (timestamp&~0x3FFF);

            if(seq - timestamp >  0x2000) seq -= 0x4000;

            if(seq - timestamp < -0x2000) seq += 0x4000;

        }

    }

#endif

    pkt->pts = timestamp;

    if (flags & 2)

        pkt->flags |= AV_PKT_FLAG_KEY;

    return st->codec->codec_type == AVMEDIA_TYPE_AUDIO ? rm->audio_pkt_cnt : 0;

}


Object *object_resolve_path_component(Object *parent, const gchar *part)

{

    ObjectProperty *prop = object_property_find(parent, part, NULL);

    if (prop == NULL) {

        return NULL;

    }

    if (object_property_is_link(prop)) {

        return *(Object **)prop->opaque;

    } else if (object_property_is_child(prop)) {

        return prop->opaque;

    } else {

        return NULL;

    }

}


static void vscsi_process_login(VSCSIState *s, vscsi_req *req)

{

    union viosrp_iu *iu = &req->iu;

    struct srp_login_rsp *rsp = &iu->srp.login_rsp;

    uint64_t tag = iu->srp.rsp.tag;

    trace_spapr_vscsi__process_login();

    /* TODO handle case that requested size is wrong and

     * buffer format is wrong

     */

    memset(iu, 0, sizeof(struct srp_login_rsp));

    rsp->opcode = SRP_LOGIN_RSP;

    /* Don't advertise quite as many request as we support to

     * keep room for management stuff etc...

     */

    rsp->req_lim_delta = cpu_to_be32(VSCSI_REQ_LIMIT-2);

    rsp->tag = tag;

    rsp->max_it_iu_len = cpu_to_be32(sizeof(union srp_iu));

    rsp->max_ti_iu_len = cpu_to_be32(sizeof(union srp_iu));

    /* direct and indirect */

    rsp->buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT);

    vscsi_send_iu(s, req, sizeof(*rsp), VIOSRP_SRP_FORMAT);

}


void cpu_tick_set_count(CPUTimer *timer, uint64_t count)

{

    uint64_t real_count = count & ~timer->disabled_mask;

    uint64_t disabled_bit = count & timer->disabled_mask;

    int64_t vm_clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -

                    cpu_to_timer_ticks(real_count, timer->frequency);

    TIMER_DPRINTF("%s set_count count=0x%016lx (%s) p=%p\n",

                  timer->name, real_count,

                  timer->disabled?"disabled":"enabled", timer);

    timer->disabled = disabled_bit ? 1 : 0;

    timer->clock_offset = vm_clock_offset;

}


void commit_start(const char *job_id, BlockDriverState *bs,

                  BlockDriverState *base, BlockDriverState *top, int64_t speed,

                  BlockdevOnError on_error, const char *backing_file_str,

                  const char *filter_node_name, Error **errp)

{

    CommitBlockJob *s;

    BlockReopenQueue *reopen_queue = NULL;

    int orig_overlay_flags;

    int orig_base_flags;

    BlockDriverState *iter;

    BlockDriverState *overlay_bs;

    BlockDriverState *commit_top_bs = NULL;

    Error *local_err = NULL;

    int ret;

    assert(top != bs);

    if (top == base) {

        error_setg(errp, "Invalid files for merge: top and base are the same");

        return;

    overlay_bs = bdrv_find_overlay(bs, top);

    if (overlay_bs == NULL) {

        error_setg(errp, "Could not find overlay image for %s:", top->filename);

        return;

    s = block_job_create(job_id, &commit_job_driver, bs, 0, BLK_PERM_ALL,

                         speed, BLOCK_JOB_DEFAULT, NULL, NULL, errp);

    if (!s) {

        return;

    orig_base_flags    = bdrv_get_flags(base);

    orig_overlay_flags = bdrv_get_flags(overlay_bs);

    /* convert base & overlay_bs to r/w, if necessary */

    if (!(orig_base_flags & BDRV_O_RDWR)) {

        reopen_queue = bdrv_reopen_queue(reopen_queue, base, NULL,

                                         orig_base_flags | BDRV_O_RDWR);

    if (!(orig_overlay_flags & BDRV_O_RDWR)) {

        reopen_queue = bdrv_reopen_queue(reopen_queue, overlay_bs, NULL,

                                         orig_overlay_flags | BDRV_O_RDWR);

    if (reopen_queue) {

        bdrv_reopen_multiple(bdrv_get_aio_context(bs), reopen_queue, &local_err);

        if (local_err != NULL) {

            error_propagate(errp, local_err);

            goto fail;

    /* Insert commit_top block node above top, so we can block consistent read

     * on the backing chain below it */

    commit_top_bs = bdrv_new_open_driver(&bdrv_commit_top, filter_node_name, 0,

                                         errp);

    if (commit_top_bs == NULL) {

        goto fail;

    commit_top_bs->total_sectors = top->total_sectors;

    bdrv_set_aio_context(commit_top_bs, bdrv_get_aio_context(top));

    bdrv_set_backing_hd(commit_top_bs, top, &local_err);

    if (local_err) {

        bdrv_unref(commit_top_bs);

        commit_top_bs = NULL;

        error_propagate(errp, local_err);

        goto fail;

    bdrv_set_backing_hd(overlay_bs, commit_top_bs, &local_err);

    if (local_err) {

        bdrv_unref(commit_top_bs);

        commit_top_bs = NULL;

        error_propagate(errp, local_err);

        goto fail;

    s->commit_top_bs = commit_top_bs;

    bdrv_unref(commit_top_bs);

    /* Block all nodes between top and base, because they will

     * disappear from the chain after this operation. */

    assert(bdrv_chain_contains(top, base));

    for (iter = top; iter != base; iter = backing_bs(iter)) {

        /* XXX BLK_PERM_WRITE needs to be allowed so we don't block ourselves

         * at s->base (if writes are blocked for a node, they are also blocked

         * for its backing file). The other options would be a second filter

         * driver above s->base. */

        ret = block_job_add_bdrv(&s->common, "intermediate node", iter, 0,

                                 BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE,

                                 errp);

        if (ret < 0) {

            goto fail;

    ret = block_job_add_bdrv(&s->common, "base", base, 0, BLK_PERM_ALL, errp);

    if (ret < 0) {

        goto fail;

    /* overlay_bs must be blocked because it needs to be modified to

     * update the backing image string. */

    ret = block_job_add_bdrv(&s->common, "overlay of top", overlay_bs,

                             BLK_PERM_GRAPH_MOD, BLK_PERM_ALL, errp);

    if (ret < 0) {

        goto fail;

    s->base = blk_new(BLK_PERM_CONSISTENT_READ

                      | BLK_PERM_WRITE

                      | BLK_PERM_RESIZE,

                      BLK_PERM_CONSISTENT_READ

                      | BLK_PERM_GRAPH_MOD

                      | BLK_PERM_WRITE_UNCHANGED);

    ret = blk_insert_bs(s->base, base, errp);

    if (ret < 0) {

        goto fail;

    /* Required permissions are already taken with block_job_add_bdrv() */

    s->top = blk_new(0, BLK_PERM_ALL);

    ret = blk_insert_bs(s->top, top, errp);

    if (ret < 0) {

        goto fail;

    s->active = bs;

    s->base_flags          = orig_base_flags;

    s->orig_overlay_flags  = orig_overlay_flags;

    s->backing_file_str = g_strdup(backing_file_str);

    s->on_error = on_error;

    trace_commit_start(bs, base, top, s);

    block_job_start(&s->common);

    return;

fail:

    if (s->base) {

        blk_unref(s->base);

    if (s->top) {

        blk_unref(s->top);

    if (commit_top_bs) {

        bdrv_set_backing_hd(overlay_bs, top, &error_abort);

    block_job_early_fail(&s->common);


int bdrv_is_removable(BlockDriverState *bs)

{

    return bs->removable;

}


static int null_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)

{

    return 0;

}


void qmp_blockdev_add(BlockdevOptions *options, Error **errp)

{

    QmpOutputVisitor *ov = qmp_output_visitor_new();

    QObject *obj;

    QDict *qdict;

    Error *local_err = NULL;

    /* Require an ID in the top level */

    if (!options->has_id) {

        error_setg(errp, "Block device needs an ID");

        goto fail;

    }

    /* TODO Sort it out in raw-posix and drive_init: Reject aio=native with

     * cache.direct=false instead of silently switching to aio=threads, except

     * if called from drive_init.

     *

     * For now, simply forbidding the combination for all drivers will do. */

    if (options->has_aio && options->aio == BLOCKDEV_AIO_OPTIONS_NATIVE) {

        bool direct = options->cache->has_direct && options->cache->direct;

        if (!options->has_cache && !direct) {

            error_setg(errp, "aio=native requires cache.direct=true");

            goto fail;

        }

    }

    visit_type_BlockdevOptions(qmp_output_get_visitor(ov),

                               &options, NULL, &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        goto fail;

    }

    obj = qmp_output_get_qobject(ov);

    qdict = qobject_to_qdict(obj);

    qdict_flatten(qdict);

    blockdev_init(NULL, qdict, &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        goto fail;

    }

fail:

    qmp_output_visitor_cleanup(ov);

}


void do_divwuo (void)

{

    if (likely((uint32_t)T1 != 0)) {

        xer_ov = 0;

        T0 = (uint32_t)T0 / (uint32_t)T1;

    } else {

        xer_so = 1;

        xer_ov = 1;

        T0 = 0;

    }

}


static void kvmclock_pre_save(void *opaque)

{

    KVMClockState *s = opaque;

    struct kvm_clock_data data;

    int ret;

    if (s->clock_valid) {

        return;

    }

    ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data);

    if (ret < 0) {

        fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret));

        data.clock = 0;

    }

    s->clock = data.clock;

    /*

     * If the VM is stopped, declare the clock state valid to avoid re-reading

     * it on next vmsave (which would return a different value). Will be reset

     * when the VM is continued.

     */

    s->clock_valid = !runstate_is_running();

}


static void handle_satn(ESPState *s)

{

    uint8_t buf[32];

    int len;

    if (s->dma && !s->dma_enabled) {

        s->dma_cb = handle_satn;

        return;

    }

    len = get_cmd(s, buf);

    if (len)

        do_cmd(s, buf);

}


static int check_checksum(ByteIOContext *bc){

    unsigned long checksum= get_checksum(bc);

//    return checksum != get_be32(bc);

    av_log(NULL, AV_LOG_ERROR, "%08X %08X\n", checksum, (int)get_be32(bc));

    return 0;

}


int ide_init_drive(IDEState *s, BlockBackend *blk, IDEDriveKind kind,

                   const char *version, const char *serial, const char *model,

                   uint64_t wwn,

                   uint32_t cylinders, uint32_t heads, uint32_t secs,

                   int chs_trans)

{

    uint64_t nb_sectors;

    s->blk = blk;

    s->drive_kind = kind;

    blk_get_geometry(blk, &nb_sectors);

    s->cylinders = cylinders;

    s->heads = heads;

    s->sectors = secs;

    s->chs_trans = chs_trans;

    s->nb_sectors = nb_sectors;

    s->wwn = wwn;

    /* The SMART values should be preserved across power cycles

       but they aren't.  */

    s->smart_enabled = 1;

    s->smart_autosave = 1;

    s->smart_errors = 0;

    s->smart_selftest_count = 0;

    if (kind == IDE_CD) {

        blk_set_dev_ops(blk, &ide_cd_block_ops, s);

        blk_set_guest_block_size(blk, 2048);

    } else {

        if (!blk_is_inserted(s->blk)) {

            error_report("Device needs media, but drive is empty");

            return -1;

        }

        if (blk_is_read_only(blk)) {

            error_report("Can't use a read-only drive");

            return -1;

        }

        blk_set_dev_ops(blk, &ide_hd_block_ops, s);

    }

    if (serial) {

        pstrcpy(s->drive_serial_str, sizeof(s->drive_serial_str), serial);

    } else {

        snprintf(s->drive_serial_str, sizeof(s->drive_serial_str),

                 "QM%05d", s->drive_serial);

    }

    if (model) {

        pstrcpy(s->drive_model_str, sizeof(s->drive_model_str), model);

    } else {

        switch (kind) {

        case IDE_CD:

            strcpy(s->drive_model_str, "QEMU DVD-ROM");

            break;

        case IDE_CFATA:

            strcpy(s->drive_model_str, "QEMU MICRODRIVE");

            break;

        default:

            strcpy(s->drive_model_str, "QEMU HARDDISK");

            break;

        }

    }

    if (version) {

        pstrcpy(s->version, sizeof(s->version), version);

    } else {

        pstrcpy(s->version, sizeof(s->version), qemu_get_version());

    }

    ide_reset(s);

    blk_iostatus_enable(blk);

    return 0;

}


int vhost_backend_invalidate_device_iotlb(struct vhost_dev *dev,

                                                 uint64_t iova, uint64_t len)

{

    struct vhost_iotlb_msg imsg;

    imsg.iova = iova;

    imsg.size = len;

    imsg.type = VHOST_IOTLB_INVALIDATE;

    return dev->vhost_ops->vhost_send_device_iotlb_msg(dev, &imsg);

}


static uint32_t gic_dist_readw(void *opaque, target_phys_addr_t offset)

{

    uint32_t val;

    val = gic_dist_readb(opaque, offset);

    val |= gic_dist_readb(opaque, offset + 1) << 8;

    return val;

}


static void test_qemu_strtoull_overflow(void)

{

    const char *str = "99999999999999999999999999999999999999999999";

    char f = 'X';

    const char *endptr = &f;

    uint64_t res = 999;

    int err;

    err = qemu_strtoull(str, &endptr, 0, &res);

    g_assert_cmpint(err, ==, -ERANGE);

    g_assert_cmpint(res, ==, ULLONG_MAX);

    g_assert(endptr == str + strlen(str));

}


PXA2xxState *pxa255_init(unsigned int sdram_size)

{

    PXA2xxState *s;

    int iomemtype, i;

    DriveInfo *dinfo;

    s = (PXA2xxState *) qemu_mallocz(sizeof(PXA2xxState));

    s->env = cpu_init("pxa255");

    if (!s->env) {

        fprintf(stderr, "Unable to find CPU definition\n");

        exit(1);

    }

    s->reset = qemu_allocate_irqs(pxa2xx_reset, s, 1)[0];

    /* SDRAM & Internal Memory Storage */

    cpu_register_physical_memory(PXA2XX_SDRAM_BASE, sdram_size,

                    qemu_ram_alloc(NULL, "pxa255.sdram",

                                   sdram_size) | IO_MEM_RAM);

    cpu_register_physical_memory(PXA2XX_INTERNAL_BASE, PXA2XX_INTERNAL_SIZE,

                    qemu_ram_alloc(NULL, "pxa255.internal",

                                   PXA2XX_INTERNAL_SIZE) | IO_MEM_RAM);

    s->pic = pxa2xx_pic_init(0x40d00000, s->env);

    s->dma = pxa255_dma_init(0x40000000, s->pic[PXA2XX_PIC_DMA]);

    pxa25x_timer_init(0x40a00000, &s->pic[PXA2XX_PIC_OST_0]);

    s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 85);

    dinfo = drive_get(IF_SD, 0, 0);

    if (!dinfo) {

        fprintf(stderr, "qemu: missing SecureDigital device\n");

        exit(1);

    }

    s->mmc = pxa2xx_mmci_init(0x41100000, dinfo->bdrv,

                              s->pic[PXA2XX_PIC_MMC], s->dma);

    for (i = 0; pxa255_serial[i].io_base; i ++)

        if (serial_hds[i]) {

#ifdef TARGET_WORDS_BIGENDIAN

            serial_mm_init(pxa255_serial[i].io_base, 2,

                           s->pic[pxa255_serial[i].irqn], 14745600/16,

                           serial_hds[i], 1, 1);

#else

            serial_mm_init(pxa255_serial[i].io_base, 2,

                           s->pic[pxa255_serial[i].irqn], 14745600/16,

                           serial_hds[i], 1, 0);

#endif

        } else {

            break;

        }

    if (serial_hds[i])

        s->fir = pxa2xx_fir_init(0x40800000, s->pic[PXA2XX_PIC_ICP],

                        s->dma, serial_hds[i]);

    s->lcd = pxa2xx_lcdc_init(0x44000000, s->pic[PXA2XX_PIC_LCD]);

    s->cm_base = 0x41300000;

    s->cm_regs[CCCR >> 2] = 0x02000210;	/* 416.0 MHz */

    s->clkcfg = 0x00000009;		/* Turbo mode active */

    iomemtype = cpu_register_io_memory(pxa2xx_cm_readfn,

                    pxa2xx_cm_writefn, s, DEVICE_NATIVE_ENDIAN);

    cpu_register_physical_memory(s->cm_base, 0x1000, iomemtype);

    register_savevm(NULL, "pxa2xx_cm", 0, 0, pxa2xx_cm_save, pxa2xx_cm_load, s);

    cpu_arm_set_cp_io(s->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s);

    s->mm_base = 0x48000000;

    s->mm_regs[MDMRS >> 2] = 0x00020002;

    s->mm_regs[MDREFR >> 2] = 0x03ca4000;

    s->mm_regs[MECR >> 2] = 0x00000001;	/* Two PC Card sockets */

    iomemtype = cpu_register_io_memory(pxa2xx_mm_readfn,

                    pxa2xx_mm_writefn, s, DEVICE_NATIVE_ENDIAN);

    cpu_register_physical_memory(s->mm_base, 0x1000, iomemtype);

    register_savevm(NULL, "pxa2xx_mm", 0, 0, pxa2xx_mm_save, pxa2xx_mm_load, s);

    s->pm_base = 0x40f00000;

    iomemtype = cpu_register_io_memory(pxa2xx_pm_readfn,

                    pxa2xx_pm_writefn, s, DEVICE_NATIVE_ENDIAN);

    cpu_register_physical_memory(s->pm_base, 0x100, iomemtype);

    register_savevm(NULL, "pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s);

    for (i = 0; pxa255_ssp[i].io_base; i ++);

    s->ssp = (SSIBus **)qemu_mallocz(sizeof(SSIBus *) * i);

    for (i = 0; pxa255_ssp[i].io_base; i ++) {

        DeviceState *dev;

        dev = sysbus_create_simple("pxa2xx-ssp", pxa255_ssp[i].io_base,

                                   s->pic[pxa255_ssp[i].irqn]);

        s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi");

    }

    if (usb_enabled) {

        sysbus_create_simple("sysbus-ohci", 0x4c000000,

                             s->pic[PXA2XX_PIC_USBH1]);

    }

    s->pcmcia[0] = pxa2xx_pcmcia_init(0x20000000);

    s->pcmcia[1] = pxa2xx_pcmcia_init(0x30000000);

    s->rtc_base = 0x40900000;

    iomemtype = cpu_register_io_memory(pxa2xx_rtc_readfn,

                    pxa2xx_rtc_writefn, s, DEVICE_NATIVE_ENDIAN);

    cpu_register_physical_memory(s->rtc_base, 0x1000, iomemtype);

    pxa2xx_rtc_init(s);

    register_savevm(NULL, "pxa2xx_rtc", 0, 0, pxa2xx_rtc_save,

                    pxa2xx_rtc_load, s);

    s->i2c[0] = pxa2xx_i2c_init(0x40301600, s->pic[PXA2XX_PIC_I2C], 0xffff);

    s->i2c[1] = pxa2xx_i2c_init(0x40f00100, s->pic[PXA2XX_PIC_PWRI2C], 0xff);

    s->i2s = pxa2xx_i2s_init(0x40400000, s->pic[PXA2XX_PIC_I2S], s->dma);

    /* GPIO1 resets the processor */

    /* The handler can be overridden by board-specific code */

    qdev_connect_gpio_out(s->gpio, 1, s->reset);

    return s;

}


int usb_device_delete_addr(int busnr, int addr)

{

    USBBus *bus;

    USBPort *port;

    USBDevice *dev;

    bus = usb_bus_find(busnr);

    if (!bus)

        return -1;

    TAILQ_FOREACH(port, &bus->used, next) {

        if (port->dev->addr == addr)

            break;

    }

    if (!port)

        return -1;

    dev = port->dev;

    TAILQ_REMOVE(&bus->used, port, next);

    bus->nused--;

    usb_attach(port, NULL);

    dev->info->handle_destroy(dev);

    TAILQ_INSERT_TAIL(&bus->free, port, next);

    bus->nfree++;

    return 0;

}


static void qmp_output_type_number(Visitor *v, const char *name, double *obj,

                                   Error **errp)

{

    QmpOutputVisitor *qov = to_qov(v);

    qmp_output_add(qov, name, qfloat_from_double(*obj));

}


static int aio_write_f(BlockBackend *blk, int argc, char **argv)

{

    int nr_iov, c;

    int pattern = 0xcd;

    struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);

    ctx->blk = blk;

    while ((c = getopt(argc, argv, "CqP:z")) != -1) {

        switch (c) {

        case 'C':

            ctx->Cflag = 1;

            break;

        case 'q':

            ctx->qflag = 1;

            break;

        case 'P':

            pattern = parse_pattern(optarg);

            if (pattern < 0) {

                return 0;

            }

            break;

        case 'z':

            ctx->zflag = 1;

            break;

        default:

            return qemuio_command_usage(&aio_write_cmd);

        }

    }

    if (optind > argc - 2) {

        return qemuio_command_usage(&aio_write_cmd);

    }

    if (ctx->zflag && optind != argc - 2) {

        printf("-z supports only a single length parameter\n");

        return 0;

    }

    if (ctx->zflag && ctx->Pflag) {

        printf("-z and -P cannot be specified at the same time\n");

        return 0;

    }

    ctx->offset = cvtnum(argv[optind]);

    if (ctx->offset < 0) {

        print_cvtnum_err(ctx->offset, argv[optind]);

        return 0;

    }

    optind++;

    if (ctx->offset & 0x1ff) {

        printf("offset %" PRId64 " is not sector aligned\n",

               ctx->offset);

        block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_WRITE);

        return 0;

    }

    if (ctx->zflag) {

        int64_t count = cvtnum(argv[optind]);

        if (count < 0) {

            print_cvtnum_err(count, argv[optind]);

            return 0;

        }

        ctx->qiov.size = count;

        blk_aio_write_zeroes(blk, ctx->offset >> 9, count >> 9, 0,

                             aio_write_done, ctx);

    } else {

        nr_iov = argc - optind;

        ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov,

                                pattern);

        if (ctx->buf == NULL) {

            block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_WRITE);

            return 0;

        }

        gettimeofday(&ctx->t1, NULL);

        block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size,

                         BLOCK_ACCT_WRITE);

        blk_aio_writev(blk, ctx->offset >> 9, &ctx->qiov,

                       ctx->qiov.size >> 9, aio_write_done, ctx);

    }

    return 0;

}


static int alloc_refcount_block(BlockDriverState *bs,

    int64_t cluster_index, uint16_t **refcount_block)

{

    BDRVQcowState *s = bs->opaque;

    unsigned int refcount_table_index;

    int ret;

    BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC);

    /* Find the refcount block for the given cluster */

    refcount_table_index = cluster_index >> s->refcount_block_bits;

    if (refcount_table_index < s->refcount_table_size) {

        uint64_t refcount_block_offset =

            s->refcount_table[refcount_table_index] & REFT_OFFSET_MASK;

        /* If it's already there, we're done */

        if (refcount_block_offset) {

            if (offset_into_cluster(s, refcount_block_offset)) {

                qcow2_signal_corruption(bs, true, -1, -1, "Refblock offset %#"

                                        PRIx64 " unaligned (reftable index: "

                                        "%#x)", refcount_block_offset,

                                        refcount_table_index);

                return -EIO;

            }

             return load_refcount_block(bs, refcount_block_offset,

                 (void**) refcount_block);

        }

    }

    /*

     * If we came here, we need to allocate something. Something is at least

     * a cluster for the new refcount block. It may also include a new refcount

     * table if the old refcount table is too small.

     *

     * Note that allocating clusters here needs some special care:

     *

     * - We can't use the normal qcow2_alloc_clusters(), it would try to

     *   increase the refcount and very likely we would end up with an endless

     *   recursion. Instead we must place the refcount blocks in a way that

     *   they can describe them themselves.

     *

     * - We need to consider that at this point we are inside update_refcounts

     *   and potentially doing an initial refcount increase. This means that

     *   some clusters have already been allocated by the caller, but their

     *   refcount isn't accurate yet. If we allocate clusters for metadata, we

     *   need to return -EAGAIN to signal the caller that it needs to restart

     *   the search for free clusters.

     *

     * - alloc_clusters_noref and qcow2_free_clusters may load a different

     *   refcount block into the cache

     */

    *refcount_block = NULL;

    /* We write to the refcount table, so we might depend on L2 tables */

    ret = qcow2_cache_flush(bs, s->l2_table_cache);

    if (ret < 0) {

        return ret;

    }

    /* Allocate the refcount block itself and mark it as used */

    int64_t new_block = alloc_clusters_noref(bs, s->cluster_size);

    if (new_block < 0) {

        return new_block;

    }

#ifdef DEBUG_ALLOC2

    fprintf(stderr, "qcow2: Allocate refcount block %d for %" PRIx64

        " at %" PRIx64 "\n",

        refcount_table_index, cluster_index << s->cluster_bits, new_block);

#endif

    if (in_same_refcount_block(s, new_block, cluster_index << s->cluster_bits)) {

        /* Zero the new refcount block before updating it */

        ret = qcow2_cache_get_empty(bs, s->refcount_block_cache, new_block,

            (void**) refcount_block);

        if (ret < 0) {

            goto fail_block;

        }

        memset(*refcount_block, 0, s->cluster_size);

        /* The block describes itself, need to update the cache */

        int block_index = (new_block >> s->cluster_bits) &

            (s->refcount_block_size - 1);

        (*refcount_block)[block_index] = cpu_to_be16(1);

    } else {

        /* Described somewhere else. This can recurse at most twice before we

         * arrive at a block that describes itself. */

        ret = update_refcount(bs, new_block, s->cluster_size, 1, false,

                              QCOW2_DISCARD_NEVER);

        if (ret < 0) {

            goto fail_block;

        }

        ret = qcow2_cache_flush(bs, s->refcount_block_cache);

        if (ret < 0) {

            goto fail_block;

        }

        /* Initialize the new refcount block only after updating its refcount,

         * update_refcount uses the refcount cache itself */

        ret = qcow2_cache_get_empty(bs, s->refcount_block_cache, new_block,

            (void**) refcount_block);

        if (ret < 0) {

            goto fail_block;

        }

        memset(*refcount_block, 0, s->cluster_size);

    }

    /* Now the new refcount block needs to be written to disk */

    BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE);

    qcow2_cache_entry_mark_dirty(s->refcount_block_cache, *refcount_block);

    ret = qcow2_cache_flush(bs, s->refcount_block_cache);

    if (ret < 0) {

        goto fail_block;

    }

    /* If the refcount table is big enough, just hook the block up there */

    if (refcount_table_index < s->refcount_table_size) {

        uint64_t data64 = cpu_to_be64(new_block);

        BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_HOOKUP);

        ret = bdrv_pwrite_sync(bs->file,

            s->refcount_table_offset + refcount_table_index * sizeof(uint64_t),

            &data64, sizeof(data64));

        if (ret < 0) {

            goto fail_block;

        }

        s->refcount_table[refcount_table_index] = new_block;

        /* The new refcount block may be where the caller intended to put its

         * data, so let it restart the search. */

        return -EAGAIN;

    }

    ret = qcow2_cache_put(bs, s->refcount_block_cache, (void**) refcount_block);

    if (ret < 0) {

        goto fail_block;

    }

    /*

     * If we come here, we need to grow the refcount table. Again, a new

     * refcount table needs some space and we can't simply allocate to avoid

     * endless recursion.

     *

     * Therefore let's grab new refcount blocks at the end of the image, which

     * will describe themselves and the new refcount table. This way we can

     * reference them only in the new table and do the switch to the new

     * refcount table at once without producing an inconsistent state in

     * between.

     */

    BLKDBG_EVENT(bs->file, BLKDBG_REFTABLE_GROW);

    /* Calculate the number of refcount blocks needed so far */

    uint64_t blocks_used = DIV_ROUND_UP(cluster_index, s->refcount_block_size);

    if (blocks_used > QCOW_MAX_REFTABLE_SIZE / sizeof(uint64_t)) {

        return -EFBIG;

    }

    /* And now we need at least one block more for the new metadata */

    uint64_t table_size = next_refcount_table_size(s, blocks_used + 1);

    uint64_t last_table_size;

    uint64_t blocks_clusters;

    do {

        uint64_t table_clusters =

            size_to_clusters(s, table_size * sizeof(uint64_t));

        blocks_clusters = 1 +

            ((table_clusters + s->refcount_block_size - 1)

            / s->refcount_block_size);

        uint64_t meta_clusters = table_clusters + blocks_clusters;

        last_table_size = table_size;

        table_size = next_refcount_table_size(s, blocks_used +

            ((meta_clusters + s->refcount_block_size - 1)

            / s->refcount_block_size));

    } while (last_table_size != table_size);

#ifdef DEBUG_ALLOC2

    fprintf(stderr, "qcow2: Grow refcount table %" PRId32 " => %" PRId64 "\n",

        s->refcount_table_size, table_size);

#endif

    /* Create the new refcount table and blocks */

    uint64_t meta_offset = (blocks_used * s->refcount_block_size) *

        s->cluster_size;

    uint64_t table_offset = meta_offset + blocks_clusters * s->cluster_size;

    uint64_t *new_table = g_try_new0(uint64_t, table_size);

    uint16_t *new_blocks = g_try_malloc0(blocks_clusters * s->cluster_size);

    assert(table_size > 0 && blocks_clusters > 0);

    if (new_table == NULL || new_blocks == NULL) {

        ret = -ENOMEM;

        goto fail_table;

    }

    /* Fill the new refcount table */

    memcpy(new_table, s->refcount_table,

        s->refcount_table_size * sizeof(uint64_t));

    new_table[refcount_table_index] = new_block;

    int i;

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

        new_table[blocks_used + i] = meta_offset + (i * s->cluster_size);

    }

    /* Fill the refcount blocks */

    uint64_t table_clusters = size_to_clusters(s, table_size * sizeof(uint64_t));

    int block = 0;

    for (i = 0; i < table_clusters + blocks_clusters; i++) {

        new_blocks[block++] = cpu_to_be16(1);

    }

    /* Write refcount blocks to disk */

    BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS);

    ret = bdrv_pwrite_sync(bs->file, meta_offset, new_blocks,

        blocks_clusters * s->cluster_size);

    g_free(new_blocks);

    new_blocks = NULL;

    if (ret < 0) {

        goto fail_table;

    }

    /* Write refcount table to disk */

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

        cpu_to_be64s(&new_table[i]);

    }

    BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE);

    ret = bdrv_pwrite_sync(bs->file, table_offset, new_table,

        table_size * sizeof(uint64_t));

    if (ret < 0) {

        goto fail_table;

    }

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

        be64_to_cpus(&new_table[i]);

    }

    /* Hook up the new refcount table in the qcow2 header */

    uint8_t data[12];

    cpu_to_be64w((uint64_t*)data, table_offset);

    cpu_to_be32w((uint32_t*)(data + 8), table_clusters);

    BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE);

    ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, refcount_table_offset),

        data, sizeof(data));

    if (ret < 0) {

        goto fail_table;

    }

    /* And switch it in memory */

    uint64_t old_table_offset = s->refcount_table_offset;

    uint64_t old_table_size = s->refcount_table_size;

    g_free(s->refcount_table);

    s->refcount_table = new_table;

    s->refcount_table_size = table_size;

    s->refcount_table_offset = table_offset;

    /* Free old table. */

    qcow2_free_clusters(bs, old_table_offset, old_table_size * sizeof(uint64_t),

                        QCOW2_DISCARD_OTHER);

    ret = load_refcount_block(bs, new_block, (void**) refcount_block);

    if (ret < 0) {

        return ret;

    }

    /* If we were trying to do the initial refcount update for some cluster

     * allocation, we might have used the same clusters to store newly

     * allocated metadata. Make the caller search some new space. */

    return -EAGAIN;

fail_table:

    g_free(new_blocks);

    g_free(new_table);

fail_block:

    if (*refcount_block != NULL) {

        qcow2_cache_put(bs, s->refcount_block_cache, (void**) refcount_block);

    }

    return ret;

}


static int alac_decode_frame(AVCodecContext *avctx,

                             void *outbuffer, int *outputsize,

                             const uint8_t *inbuffer, int input_buffer_size)

{

    ALACContext *alac = avctx->priv_data;

    int channels;

    unsigned int outputsamples;

    int hassize;

    int readsamplesize;

    int wasted_bytes;

    int isnotcompressed;

    uint8_t interlacing_shift;

    uint8_t interlacing_leftweight;

    /* short-circuit null buffers */

    if (!inbuffer || !input_buffer_size)

        return input_buffer_size;

    /* initialize from the extradata */

    if (!alac->context_initialized) {

        if (alac->avctx->extradata_size != ALAC_EXTRADATA_SIZE) {

            av_log(avctx, AV_LOG_ERROR, "alac: expected %d extradata bytes\n",

                ALAC_EXTRADATA_SIZE);

            return input_buffer_size;

        }

        if (alac_set_info(alac)) {

            av_log(avctx, AV_LOG_ERROR, "alac: set_info failed\n");

            return input_buffer_size;

        }

        alac->context_initialized = 1;

    }

    init_get_bits(&alac->gb, inbuffer, input_buffer_size * 8);

    channels = get_bits(&alac->gb, 3) + 1;

    if (channels > MAX_CHANNELS) {

        av_log(avctx, AV_LOG_ERROR, "channels > %d not supported\n",

               MAX_CHANNELS);

        return input_buffer_size;

    }

    /* 2^result = something to do with output waiting.

     * perhaps matters if we read > 1 frame in a pass?

     */

    skip_bits(&alac->gb, 4);

    skip_bits(&alac->gb, 12); /* unknown, skip 12 bits */

    /* the output sample size is stored soon */

    hassize = get_bits1(&alac->gb);

    wasted_bytes = get_bits(&alac->gb, 2); /* unknown ? */

    /* whether the frame is compressed */

    isnotcompressed = get_bits1(&alac->gb);

    if (hassize) {

        /* now read the number of samples as a 32bit integer */

        outputsamples = get_bits_long(&alac->gb, 32);

        if(outputsamples > alac->setinfo_max_samples_per_frame){

            av_log(avctx, AV_LOG_ERROR, "outputsamples %d > %d\n", outputsamples, alac->setinfo_max_samples_per_frame);

            return -1;

        }

    } else

        outputsamples = alac->setinfo_max_samples_per_frame;

    if(outputsamples > *outputsize / alac->bytespersample){

        av_log(avctx, AV_LOG_ERROR, "sample buffer too small\n");

        return -1;

    }

    *outputsize = outputsamples * alac->bytespersample;

    readsamplesize = alac->setinfo_sample_size - (wasted_bytes * 8) + channels - 1;

    if (!isnotcompressed) {

        /* so it is compressed */

        int16_t predictor_coef_table[channels][32];

        int predictor_coef_num[channels];

        int prediction_type[channels];

        int prediction_quantitization[channels];

        int ricemodifier[channels];

        int i, chan;

        interlacing_shift = get_bits(&alac->gb, 8);

        interlacing_leftweight = get_bits(&alac->gb, 8);

        for (chan = 0; chan < channels; chan++) {

            prediction_type[chan] = get_bits(&alac->gb, 4);

            prediction_quantitization[chan] = get_bits(&alac->gb, 4);

            ricemodifier[chan] = get_bits(&alac->gb, 3);

            predictor_coef_num[chan] = get_bits(&alac->gb, 5);

            /* read the predictor table */

            for (i = 0; i < predictor_coef_num[chan]; i++)

                predictor_coef_table[chan][i] = (int16_t)get_bits(&alac->gb, 16);

        }

        if (wasted_bytes)

            av_log(avctx, AV_LOG_ERROR, "FIXME: unimplemented, unhandling of wasted_bytes\n");

        for (chan = 0; chan < channels; chan++) {

            bastardized_rice_decompress(alac,

                                        alac->predicterror_buffer[chan],

                                        outputsamples,

                                        readsamplesize,

                                        alac->setinfo_rice_initialhistory,

                                        alac->setinfo_rice_kmodifier,

                                        ricemodifier[chan] * alac->setinfo_rice_historymult / 4,

                                        (1 << alac->setinfo_rice_kmodifier) - 1);

            if (prediction_type[chan] == 0) {

                /* adaptive fir */

                predictor_decompress_fir_adapt(alac->predicterror_buffer[chan],

                                               alac->outputsamples_buffer[chan],

                                               outputsamples,

                                               readsamplesize,

                                               predictor_coef_table[chan],

                                               predictor_coef_num[chan],

                                               prediction_quantitization[chan]);

            } else {

                av_log(avctx, AV_LOG_ERROR, "FIXME: unhandled prediction type: %i\n", prediction_type[chan]);

                /* I think the only other prediction type (or perhaps this is

                 * just a boolean?) runs adaptive fir twice.. like:

                 * predictor_decompress_fir_adapt(predictor_error, tempout, ...)

                 * predictor_decompress_fir_adapt(predictor_error, outputsamples ...)

                 * little strange..

                 */

            }

        }

    } else {

        /* not compressed, easy case */

        int i, chan;

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

            for (chan = 0; chan < channels; chan++) {

                int32_t audiobits;

                audiobits = get_bits_long(&alac->gb, alac->setinfo_sample_size);

                audiobits = extend_sign32(audiobits, alac->setinfo_sample_size);

                alac->outputsamples_buffer[chan][i] = audiobits;

            }

        /* wasted_bytes = 0; */

        interlacing_shift = 0;

        interlacing_leftweight = 0;

    }

    if (get_bits(&alac->gb, 3) != 7)

        av_log(avctx, AV_LOG_ERROR, "Error : Wrong End Of Frame\n");

    switch(alac->setinfo_sample_size) {

    case 16:

        if (channels == 2) {

            reconstruct_stereo_16(alac->outputsamples_buffer,

                                  (int16_t*)outbuffer,

                                  alac->numchannels,

                                  outputsamples,

                                  interlacing_shift,

                                  interlacing_leftweight);

        } else {

            int i;

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

                int16_t sample = alac->outputsamples_buffer[0][i];

                ((int16_t*)outbuffer)[i * alac->numchannels] = sample;

            }

        }

        break;

    case 20:

    case 24:

        // It is not clear if there exist any encoder that creates 24 bit ALAC

        // files. iTunes convert 24 bit raw files to 16 bit before encoding.

    case 32:

        av_log(avctx, AV_LOG_ERROR, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size);

        break;

    default:

        break;

    }

    if (input_buffer_size * 8 - get_bits_count(&alac->gb) > 8)

        av_log(avctx, AV_LOG_ERROR, "Error : %d bits left\n", input_buffer_size * 8 - get_bits_count(&alac->gb));

    return input_buffer_size;

}


static int getopt(int argc, char *argv[], char *opts)

{

    static int sp = 1;

    int c;

    char *cp;

    if (sp == 1)

        if (optind >= argc ||

            argv[optind][0] != '-' || argv[optind][1] == '\0')

            return EOF;

        else if (!strcmp(argv[optind], "--")) {

            optind++;

            return EOF;

        }

    optopt = c = argv[optind][sp];

    if (c == ':' || (cp = strchr(opts, c)) == NULL) {

        fprintf(stderr, ": illegal option -- %c\n", c);

        if (argv[optind][++sp] == '\0') {

            optind++;

            sp = 1;

        }

        return '?';

    }

    if (*++cp == ':') {

        if (argv[optind][sp+1] != '\0')

            optarg = &argv[optind++][sp+1];

        else if(++optind >= argc) {

            fprintf(stderr, ": option requires an argument -- %c\n", c);

            sp = 1;

            return '?';

        } else

            optarg = argv[optind++];

        sp = 1;

    } else {

        if (argv[optind][++sp] == '\0') {

            sp = 1;

            optind++;

        }

        optarg = NULL;

    }

    return c;

}