Ejemplo n.º 1
0
giblorb_err_t giblorb_destroy_map( giblorb_map_t *map )
{
    int ix;

    if ( !map || !map->chunks || map->inited != giblorb_Inited_Magic )
        return giblorb_err_NotAMap;

    for ( ix = 0; ix < map->numchunks; ix++ )
    {
        giblorb_chunkdesc_t *chu = &( map->chunks[ix] );
        if ( chu->ptr )
        {
            giblorb_free( chu->ptr );
            chu->ptr = NULL;
        }
    }

    if ( map->chunks )
    {
        giblorb_free( map->chunks );
        map->chunks = NULL;
    }

    map->numchunks = 0;

    if ( map->resources )
    {
        giblorb_free( map->resources );
        map->resources = NULL;
    }

    if ( map->ressorted )
    {
        giblorb_free( map->ressorted );
        map->ressorted = NULL;
    }

    map->numresources = 0;

    map->file = NULL;
    map->inited = 0;

    giblorb_free( map );

    return giblorb_err_None;
}
Ejemplo n.º 2
0
giblorb_err_t giblorb_unload_chunk(giblorb_map_t *map, glui32 chunknum)
{
    giblorb_chunkdesc_t *chu;
    
    if (chunknum < 0 || chunknum >= map->numchunks)
        return giblorb_err_NotFound;

    chu = &(map->chunks[chunknum]);
    
    if (chu->ptr) {
        giblorb_free(chu->ptr);
        chu->ptr = NULL;
    }
    
    return giblorb_err_None;
}
Ejemplo n.º 3
0
giblorb_err_t giblorb_unload_chunk(giblorb_map_t *map, glui32 chunknum)
{
    giblorb_chunkdesc_t *chu;
    
	// XCode: removed "chunknum < 0" test to shut up compiler warning
    if (chunknum >= map->numchunks)
        return giblorb_err_NotFound;

    chu = &(map->chunks[chunknum]);
    
    if (chu->ptr) {
        giblorb_free(chu->ptr);
        chu->ptr = NULL;
    }
    
    return giblorb_err_None;
}
Ejemplo n.º 4
0
giblorb_err_t giblorb_create_map(strid_t file, giblorb_map_t **newmap)
{
    giblorb_err_t err;
    giblorb_map_t *map;
    glui32 readlen;
    glui32 nextpos, totallength;
    giblorb_chunkdesc_t *chunks;
    int chunks_size, numchunks;
    char buffer[16];
    
    *newmap = NULL;
    
    if (!lib_inited) {
        err = giblorb_initialize();
        if (err)
            return err;
        lib_inited = TRUE;
    }

    /* First, chew through the file and index the chunks. */
    
    glk_stream_set_position(file, 0, seekmode_Start);
    
    readlen = glk_get_buffer_stream(file, buffer, 12);
    if (readlen != 12)
        return giblorb_err_Read;
    
    if (giblorb_native4(buffer+0) != giblorb_ID_FORM)
        return giblorb_err_Format;
    if (giblorb_native4(buffer+8) != giblorb_ID_IFRS)
        return giblorb_err_Format;
    
    totallength = giblorb_native4(buffer+4) + 8;
    nextpos = 12;

    chunks_size = 8;
    numchunks = 0;
    chunks = (giblorb_chunkdesc_t *)giblorb_malloc(sizeof(giblorb_chunkdesc_t) 
        * chunks_size);

    while (nextpos < totallength) {
        glui32 type, len;
        int chunum;
        giblorb_chunkdesc_t *chu;
        
        glk_stream_set_position(file, nextpos, seekmode_Start);
        
        readlen = glk_get_buffer_stream(file, buffer, 8);
        if (readlen != 8)
            return giblorb_err_Read;
        
        type = giblorb_native4(buffer+0);
        len = giblorb_native4(buffer+4);
        
        if (numchunks >= chunks_size) {
            chunks_size *= 2;
            chunks = (giblorb_chunkdesc_t *)giblorb_realloc(chunks, 
                sizeof(giblorb_chunkdesc_t) * chunks_size);
        }
        
        chunum = numchunks;
        chu = &(chunks[chunum]);
        numchunks++;
        
        chu->type = type;
        chu->startpos = nextpos;
        if (type == giblorb_ID_FORM) {
            chu->datpos = nextpos;
            chu->len = len+8;
        }
        else {
            chu->datpos = nextpos+8;
            chu->len = len;
        }
        chu->ptr = NULL;
        chu->auxdatnum = -1;
        
        nextpos = nextpos + len + 8;
        if (nextpos & 1)
            nextpos++;
            
        if (nextpos > totallength)
            return giblorb_err_Format;
    }
    
    /* The basic IFF structure seems to be ok, and we have a list of
        chunks. Now we allocate the map structure itself. */
    
    map = (giblorb_map_t *)giblorb_malloc(sizeof(giblorb_map_t));
    if (!map) {
        giblorb_free(chunks);
        return giblorb_err_Alloc;
    }
        
    map->inited = giblorb_Inited_Magic;
    map->file = file;
    map->chunks = chunks;
    map->numchunks = numchunks;
    map->resources = NULL;
    map->ressorted = NULL;
    map->numresources = 0;
    /*map->releasenum = 0;
    map->zheader = NULL;
    map->resolution = NULL;
    map->palettechunk = -1;
    map->palette = NULL;
    map->auxsound = NULL;
    map->auxpict = NULL;*/
    
    /* Now we do everything else involved in loading the Blorb file,
        such as building resource lists. */
    
    err = giblorb_initialize_map(map);
    if (err) {
        giblorb_destroy_map(map);
        return err;
    }
    
    *newmap = map;
    return giblorb_err_None;
}
Ejemplo n.º 5
0
static giblorb_err_t giblorb_initialize_map( giblorb_map_t *map )
{
    /* It is important that the map structure be kept valid during this
        function. If this returns an error, giblorb_destroy_map() will
        be called. */

    int ix, jx;
    giblorb_result_t chunkres;
    giblorb_err_t err;
    char *ptr;
    glui32 len;
    glui32 numres;
    int gotindex = FALSE;

    for ( ix = 0; ix < map->numchunks; ix++ )
    {
        giblorb_chunkdesc_t *chu = &map->chunks[ix];

        switch ( chu->type )
        {

        case giblorb_ID_RIdx:
            /* Resource index chunk: build the resource list and
            sort it. */

            if ( gotindex )
                return giblorb_err_Format; /* duplicate index chunk */
            err = giblorb_load_chunk_by_number( map, giblorb_method_Memory, &chunkres, ix );
            if ( err )
                return err;

            ptr = chunkres.data.ptr;
            len = chunkres.length;
            numres = giblorb_native4( ptr + 0 );

            if ( numres )
            {
                int ix2;
                giblorb_resdesc_t *resources = NULL;
                giblorb_resdesc_t **ressorted = NULL;

                if ( len != numres * 12 + 4 )
                    return giblorb_err_Format; /* bad length field */

                resources = (giblorb_resdesc_t *)giblorb_malloc( numres * sizeof( giblorb_resdesc_t ) );
                if ( !resources )
                {
                    return giblorb_err_Alloc;
                }
                ressorted = (giblorb_resdesc_t **)giblorb_malloc( numres * sizeof( giblorb_resdesc_t * ) );
                if ( !ressorted )
                {
                    giblorb_free( resources );
                    return giblorb_err_Alloc;
                }

                ix2 = 0;
                for ( jx = 0; jx < numres; jx++ )
                {
                    giblorb_resdesc_t *res = &( resources[jx] );
                    glui32 respos;

                    res->usage = giblorb_native4( ptr + jx * 12 + 4 );
                    res->resnum = giblorb_native4( ptr + jx * 12 + 8 );
                    respos = giblorb_native4( ptr + jx * 12 + 12 );

                    while ( ix2 < map->numchunks && map->chunks[ix2].startpos < respos )
                        ix2++;

                    if ( ix2 >= map->numchunks || map->chunks[ix2].startpos != respos )
                    {
                        /* start pos does not match a real chunk */
                        giblorb_free( resources );
                        giblorb_free( ressorted );
                        return giblorb_err_Format;
                    }

                    res->chunknum = ix2;

                    ressorted[jx] = res;
                }

                /* Sort a resource list (actually a list of pointers to
                    structures in map->resources.) This makes it easy
                    to find resources by usage and resource number. */
                giblorb_qsort( ressorted, numres );

                map->numresources = numres;
                map->resources = resources;
                map->ressorted = ressorted;
            }

            giblorb_unload_chunk( map, ix );
            gotindex = TRUE;
            break;
        }
    }

    return giblorb_err_None;
}