static int dmg_open(BlockDriverState *bs, int flags)

{

    BDRVDMGState *s = bs->opaque;

    off_t info_begin,info_end,last_in_offset,last_out_offset;

    uint32_t count;

    uint32_t max_compressed_size=1,max_sectors_per_chunk=1,i;

    int64_t offset;



    bs->read_only = 1;

    s->n_chunks = 0;

    s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;



    /* read offset of info blocks */

    offset = bdrv_getlength(bs->file);

    if (offset < 0) {

        goto fail;

    }

    offset -= 0x1d8;



    info_begin = read_off(bs, offset);

    if (info_begin == 0) {

	goto fail;

    }



    if (read_uint32(bs, info_begin) != 0x100) {

        goto fail;

    }



    count = read_uint32(bs, info_begin + 4);

    if (count == 0) {

        goto fail;

    }

    info_end = info_begin + count;



    offset = info_begin + 0x100;



    /* read offsets */

    last_in_offset = last_out_offset = 0;

    while (offset < info_end) {

        uint32_t type;



	count = read_uint32(bs, offset);

	if(count==0)

	    goto fail;

        offset += 4;



	type = read_uint32(bs, offset);

	if (type == 0x6d697368 && count >= 244) {

	    int new_size, chunk_count;



            offset += 4;

            offset += 200;



	    chunk_count = (count-204)/40;

	    new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count);

	    s->types = g_realloc(s->types, new_size/2);

	    s->offsets = g_realloc(s->offsets, new_size);

	    s->lengths = g_realloc(s->lengths, new_size);

	    s->sectors = g_realloc(s->sectors, new_size);

	    s->sectorcounts = g_realloc(s->sectorcounts, new_size);



	    for(i=s->n_chunks;i<s->n_chunks+chunk_count;i++) {

		s->types[i] = read_uint32(bs, offset);

		offset += 4;

		if(s->types[i]!=0x80000005 && s->types[i]!=1 && s->types[i]!=2) {

		    if(s->types[i]==0xffffffff) {

			last_in_offset = s->offsets[i-1]+s->lengths[i-1];

			last_out_offset = s->sectors[i-1]+s->sectorcounts[i-1];

		    }

		    chunk_count--;

		    i--;

		    offset += 36;

		    continue;

		}

		offset += 4;



		s->sectors[i] = last_out_offset+read_off(bs, offset);

		offset += 8;



		s->sectorcounts[i] = read_off(bs, offset);

		offset += 8;



		s->offsets[i] = last_in_offset+read_off(bs, offset);

		offset += 8;



		s->lengths[i] = read_off(bs, offset);

		offset += 8;



		if(s->lengths[i]>max_compressed_size)

		    max_compressed_size = s->lengths[i];

		if(s->sectorcounts[i]>max_sectors_per_chunk)

		    max_sectors_per_chunk = s->sectorcounts[i];

	    }

	    s->n_chunks+=chunk_count;

	}

    }



    /* initialize zlib engine */

    s->compressed_chunk = g_malloc(max_compressed_size+1);

    s->uncompressed_chunk = g_malloc(512*max_sectors_per_chunk);

    if(inflateInit(&s->zstream) != Z_OK)

	goto fail;



    s->current_chunk = s->n_chunks;



    qemu_co_mutex_init(&s->lock);

    return 0;

fail:

    return -1;

}

static int dmg_open(BlockDriverState *bs, int flags)

{

    BDRVDMGState *s = bs->opaque;

    off_t info_begin,info_end,last_in_offset,last_out_offset;

    uint32_t count;

    uint32_t max_compressed_size=1,max_sectors_per_chunk=1,i;

    int64_t offset;



    bs->read_only = 1;

    s->n_chunks = 0;

    s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;



    

    offset = bdrv_getlength(bs->file);

    if (offset < 0) {

        goto fail;

    }

    offset -= 0x1d8;



    info_begin = read_off(bs, offset);

    if (info_begin == 0) {

	goto fail;

    }



    if (read_uint32(bs, info_begin) != 0x100) {

        goto fail;

    }



    count = read_uint32(bs, info_begin + 4);

    if (count == 0) {

        goto fail;

    }

    info_end = info_begin + count;



    offset = info_begin + 0x100;



    

    last_in_offset = last_out_offset = 0;

    while (offset < info_end) {

        uint32_t type;



	count = read_uint32(bs, offset);

	if(count==0)

	    goto fail;

        offset += 4;



	type = read_uint32(bs, offset);

	if (type == 0x6d697368 && count >= 244) {

	    int new_size, chunk_count;



            offset += 4;

            offset += 200;



	    chunk_count = (count-204)/40;

	    new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count);

	    s->types = g_realloc(s->types, new_size/2);

	    s->offsets = g_realloc(s->offsets, new_size);

	    s->lengths = g_realloc(s->lengths, new_size);

	    s->sectors = g_realloc(s->sectors, new_size);

	    s->sectorcounts = g_realloc(s->sectorcounts, new_size);



	    for(i=s->n_chunks;i<s->n_chunks+chunk_count;i++) {

		s->types[i] = read_uint32(bs, offset);

		offset += 4;

		if(s->types[i]!=0x80000005 && s->types[i]!=1 && s->types[i]!=2) {

		    if(s->types[i]==0xffffffff) {

			last_in_offset = s->offsets[i-1]+s->lengths[i-1];

			last_out_offset = s->sectors[i-1]+s->sectorcounts[i-1];

		    }

		    chunk_count--;

		    i--;

		    offset += 36;

		    continue;

		}

		offset += 4;



		s->sectors[i] = last_out_offset+read_off(bs, offset);

		offset += 8;



		s->sectorcounts[i] = read_off(bs, offset);

		offset += 8;



		s->offsets[i] = last_in_offset+read_off(bs, offset);

		offset += 8;



		s->lengths[i] = read_off(bs, offset);

		offset += 8;



		if(s->lengths[i]>max_compressed_size)

		    max_compressed_size = s->lengths[i];

		if(s->sectorcounts[i]>max_sectors_per_chunk)

		    max_sectors_per_chunk = s->sectorcounts[i];

	    }

	    s->n_chunks+=chunk_count;

	}

    }



    

    s->compressed_chunk = g_malloc(max_compressed_size+1);

    s->uncompressed_chunk = g_malloc(512*max_sectors_per_chunk);

    if(inflateInit(&s->zstream) != Z_OK)

	goto fail;



    s->current_chunk = s->n_chunks;



    qemu_co_mutex_init(&s->lock);

    return 0;

fail:

    return -1;

}

    off_t info_begin,info_end,last_in_offset,last_out_offset;     uint32_t count;     info_begin = read_off(bs, offset);     if (info_begin == 0) { 	goto fail;     if (read_uint32(bs, info_begin) != 0x100) {     count = read_uint32(bs, info_begin + 4);     if (count == 0) { 	count = read_uint32(bs, offset); 	if(count==0) 	    goto fail; 	type = read_uint32(bs, offset); 	    for(i=s->n_chunks;i<s->n_chunks+chunk_count;i++) { 		s->types[i] = read_uint32(bs, offset); 		s->sectors[i] = last_out_offset+read_off(bs, offset); 		offset += 8; 		s->sectorcounts[i] = read_off(bs, offset); 		offset += 8; 		s->offsets[i] = last_in_offset+read_off(bs, offset); 		offset += 8; 		s->lengths[i] = read_off(bs, offset); 		offset += 8;     if(inflateInit(&s->zstream) != Z_OK) 	goto fail;     return -1;
static int FUNC_0(BlockDriverState *VAR_0, int VAR_1)

{

    BDRVDMGState *s = VAR_0->opaque;

    off_t info_begin,info_end,last_in_offset,last_out_offset;

    uint32_t count;

    uint32_t max_compressed_size=1,max_sectors_per_chunk=1,i;

    int64_t offset;



    VAR_0->read_only = 1;

    s->n_chunks = 0;

    s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;



    

    offset = bdrv_getlength(VAR_0->file);

    if (offset < 0) {

        goto fail;

    }

    offset -= 0x1d8;



    info_begin = read_off(VAR_0, offset);

    if (info_begin == 0) {

	goto fail;

    }



    if (read_uint32(VAR_0, info_begin) != 0x100) {

        goto fail;

    }



    count = read_uint32(VAR_0, info_begin + 4);

    if (count == 0) {

        goto fail;

    }

    info_end = info_begin + count;



    offset = info_begin + 0x100;



    

    last_in_offset = last_out_offset = 0;

    while (offset < info_end) {

        uint32_t type;



	count = read_uint32(VAR_0, offset);

	if(count==0)

	    goto fail;

        offset += 4;



	type = read_uint32(VAR_0, offset);

	if (type == 0x6d697368 && count >= 244) {

	    int VAR_2, VAR_3;



            offset += 4;

            offset += 200;



	    VAR_3 = (count-204)/40;

	    VAR_2 = sizeof(uint64_t) * (s->n_chunks + VAR_3);

	    s->types = g_realloc(s->types, VAR_2/2);

	    s->offsets = g_realloc(s->offsets, VAR_2);

	    s->lengths = g_realloc(s->lengths, VAR_2);

	    s->sectors = g_realloc(s->sectors, VAR_2);

	    s->sectorcounts = g_realloc(s->sectorcounts, VAR_2);



	    for(i=s->n_chunks;i<s->n_chunks+VAR_3;i++) {

		s->types[i] = read_uint32(VAR_0, offset);

		offset += 4;

		if(s->types[i]!=0x80000005 && s->types[i]!=1 && s->types[i]!=2) {

		    if(s->types[i]==0xffffffff) {

			last_in_offset = s->offsets[i-1]+s->lengths[i-1];

			last_out_offset = s->sectors[i-1]+s->sectorcounts[i-1];

		    }

		    VAR_3--;

		    i--;

		    offset += 36;

		    continue;

		}

		offset += 4;



		s->sectors[i] = last_out_offset+read_off(VAR_0, offset);

		offset += 8;



		s->sectorcounts[i] = read_off(VAR_0, offset);

		offset += 8;



		s->offsets[i] = last_in_offset+read_off(VAR_0, offset);

		offset += 8;



		s->lengths[i] = read_off(VAR_0, offset);

		offset += 8;



		if(s->lengths[i]>max_compressed_size)

		    max_compressed_size = s->lengths[i];

		if(s->sectorcounts[i]>max_sectors_per_chunk)

		    max_sectors_per_chunk = s->sectorcounts[i];

	    }

	    s->n_chunks+=VAR_3;

	}

    }



    

    s->compressed_chunk = g_malloc(max_compressed_size+1);

    s->uncompressed_chunk = g_malloc(512*max_sectors_per_chunk);

    if(inflateInit(&s->zstream) != Z_OK)

	goto fail;



    s->current_chunk = s->n_chunks;



    qemu_co_mutex_init(&s->lock);

    return 0;

fail:

    return -1;

}

static int FUNC_0(BlockDriverState *VAR_0, int VAR_1)
{ BDRVDMGState *s = VAR_0->opaque; off_t info_begin,info_end,last_in_offset,last_out_offset; uint32_t count; uint32_t max_compressed_size=1,max_sectors_per_chunk=1,i; int64_t offset; VAR_0->read_only = 1; s->n_chunks = 0; s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL; offset = bdrv_getlength(VAR_0->file); if (offset < 0) { goto fail; } offset -= 0x1d8; info_begin = read_off(VAR_0, offset); if (info_begin == 0) { goto fail; } if (read_uint32(VAR_0, info_begin) != 0x100) { goto fail; } count = read_uint32(VAR_0, info_begin + 4); if (count == 0) { goto fail; } info_end = info_begin + count; offset = info_begin + 0x100; last_in_offset = last_out_offset = 0; while (offset < info_end) { uint32_t type; count = read_uint32(VAR_0, offset); if(count==0)
goto fail; offset += 4; type = read_uint32(VAR_0, offset); if (type == 0x6d697368 && count >= 244) { int VAR_2, VAR_3; offset += 4; offset += 200; VAR_3 = (count-204)/40; VAR_2 = sizeof(uint64_t) * (s->n_chunks + VAR_3); s->types = g_realloc(s->types, VAR_2/2); s->offsets = g_realloc(s->offsets, VAR_2); s->lengths = g_realloc(s->lengths, VAR_2); s->sectors = g_realloc(s->sectors, VAR_2); s->sectorcounts = g_realloc(s->sectorcounts, VAR_2); for(i=s->n_chunks;i<s->n_chunks+VAR_3;i++) { s->types[i] = read_uint32(VAR_0, offset); offset += 4; if(s->types[i]!=0x80000005 && s->types[i]!=1 && s->types[i]!=2) { if(s->types[i]==0xffffffff) { last_in_offset = s->offsets[i-1]+s->lengths[i-1]; last_out_offset = s->sectors[i-1]+s->sectorcounts[i-1]; } VAR_3--; i--; offset += 36; continue; } offset += 4; s->sectors[i] = last_out_offset+read_off(VAR_0, offset); offset += 8; s->sectorcounts[i] = read_off(VAR_0, offset); offset += 8; s->offsets[i] = last_in_offset+read_off(VAR_0, offset); offset += 8; s->lengths[i] = read_off(VAR_0, offset); offset += 8; if(s->lengths[i]>max_compressed_size)
max_compressed_size = s->lengths[i]; if(s->sectorcounts[i]>max_sectors_per_chunk)
max_sectors_per_chunk = s->sectorcounts[i]; } s->n_chunks+=VAR_3; } } s->compressed_chunk = g_malloc(max_compressed_size+1); s->uncompressed_chunk = g_malloc(512*max_sectors_per_chunk); if(inflateInit(&s->zstream) != Z_OK)
goto fail; s->current_chunk = s->n_chunks; qemu_co_mutex_init(&s->lock); return 0; fail:
return -1; }