[Contents] [Index] [Help] [Retrace] [Browse <] [Browse >]

/*----------------------------------------------------------------------*
 * GETDISPLAY.C  Support routines for reading/displaying ILBM files.
 * (IFF is Interchange Format File.)
 *
 * Based on code by Jerry Morrison and Steve Shaw, Electronic Arts.
 * This software is in the public domain.
 * Modified for iffparse.library by CBM 04/90
 * This version for the Amiga computer.
 *----------------------------------------------------------------------*/

#include "iffp/ilbm.h"
#include "iffp/packer.h"
#include "iffp/ilbmapp.h"

extern struct Library *GfxBase;

/* showilbm
 *
 * Passed an ILBMInfo initilized with with a not-in-use ParseInfo.iff
 *   IFFHandle and desired propchks, collectchks, stopchks, and a filename,
 *   will load and display an ILBM, initializing ilbm->Bmhd, ilbm->camg,
 *   ilbm->scr, ilbm->win, ilbm->vp, ilbm->srp, ilbm->wrp,
 *   ilbm->colortable, and ilbm->ncolors.
 *
 *   Note that ncolors may be more colors than you can LoadRGB4.
 *   Use MIN(ilbm->ncolors,MAXAMCOLORREG) for color count if you change
 *   the colors yourself using 1.3/2.0 functions.
 *
 * Returns 0 for success or an IFFERR (libraries/iffparse.h)
 */

LONG showilbm(struct ILBMInfo *ilbm, UBYTE *filename)
{
LONG error = 0L;

    if(!(ilbm->ParseInfo.iff))     return(CLIENT_ERROR);

    if(!(error = openifile((struct ParseInfo *)ilbm, filename, IFFF_READ)))
        {
        D(bug("showilbm: openifile successful\n"));

        error = parseifile((struct ParseInfo *)ilbm,
                                ID_FORM, ID_ILBM,
                                ilbm->ParseInfo.propchks,
                                ilbm->ParseInfo.collectchks,
                                ilbm->ParseInfo.stopchks);

        if((!error)||(error == IFFERR_EOC)||(error == IFFERR_EOF))
            {
            D(bug("showilbm: parseifile successful\n"));

            if(contextis(ilbm->ParseInfo.iff,ID_ILBM,ID_FORM))
                {
                if(error = createdisplay(ilbm)) deletedisplay(ilbm);
                }
            else
                {
                closeifile((struct ParseInfo *)ilbm);
                message("Not an ILBM\n");
                error = NOFILE;
                }
            }
        }
    return(error);
}


/* unshowilbm
 *
 * frees and closes everything alloc'd/opened by showilbm
 */
void unshowilbm(struct ILBMInfo *ilbm)
{
        deletedisplay(ilbm);
        closeifile((struct ParseInfo *)ilbm);
}



/* createdisplay
 *
 * Passed a initialized ILBMInfo with parsed IFFHandle (chunks parsed,
 * stopped at BODY),
 * opens/allocs the display and colortable, and displays the ILBM.
 *
 * If successful, sets up ilbm->Bmhd, ilbm->camg, ilbm->scr, ilbm->win,
 *   ilbm->vp,  ilbm->wrp, ilbm->srp and also ilbm->colortable and
 *   ilbm->ncolors.
 *
 * Note that ncolors may be more colors than you can LoadRGB4.
 * Use MIN(ilbm->ncolors,MAXAMCOLORREG) for color count if you change
 *   the colors yourself using 1.3/2.0 functions.
 *
 * Returns 0 for success or an IFFERR (libraries/iffparse.h)
 */

LONG createdisplay(struct ILBMInfo *ilbm)
        {
        int error;

        D(bug("createdisplay:\n"));

        error                   = getdisplay(ilbm);

        D(bug("createdisplay: after getdisplay, error = %ld\n", error));

        if(!error)      error   = loadbody(ilbm->ParseInfo.iff,
                                                &ilbm->scr->BitMap,&ilbm->Bmhd);

        D(bug("createdisplay: after loadbody, error = %ld\n", error));

        if(!error)
                {
                if(!(getcolors(ilbm)))
                   LoadRGB4(ilbm->vp, ilbm->colortable,
                                MIN(ilbm->ncolors,MAXAMCOLORREG));
                }
        if(error)  deletedisplay(ilbm);
        return(error);
        }


/* deletedisplay
 *
 * closes and deallocates created display and colors
 */
void deletedisplay(struct ILBMInfo *ilbm)
        {
        freedisplay(ilbm);
        freecolors(ilbm);
        }



/* getdisplay
 *
 * Passed an initialized ILBMInfo with a parsed IFFHandle (chunks parsed,
 * stopped at BODY),
 * gets the dimensions and mode for the display and calls the external
 * routine opendisplay().  Our opendisplay() is in the screen.c
 * module.  It opens a 2.0 or 1.3, ECS or non-ECS screen and window.
 * It also does 2.0 overscan centering based on the closest user prefs.
 *
 * If successful, sets up ilbm->Bmhd, ilbm->camg, ilbm->scr, ilbm->win,
 *   ilbm->vp, ilbm->wrp, ilbm->srp
 *
 * Returns 0 for success or an IFFERR (libraries/iffparse.h)
 */
LONG getdisplay(struct ILBMInfo *ilbm)
        {
        struct IFFHandle *iff;
        BitMapHeader *bmhd;
        ULONG                           modeid;
        UWORD                           wide, high, deep;


        if(!(iff=ilbm->ParseInfo.iff))     return(CLIENT_ERROR);

        if(!(bmhd = (BitMapHeader *)findpropdata(iff, ID_ILBM, ID_BMHD)))
                {
                message ("No ILBM.BMHD chunk\n");
                return(IFFERR_SYNTAX);
                }

        *(&ilbm->Bmhd)        = *bmhd;

        wide = (RowBytes(bmhd->w)) >= (RowBytes(bmhd->pageWidth)) ?
                bmhd->w : bmhd->pageWidth;
        high = MAX(bmhd->h, bmhd->pageHeight);
        deep = MIN(bmhd->nPlanes,MAXAMDEPTH);

        ilbm->camg = modeid = getcamg(ilbm);

        /*
         * Open the display
         */
        if(!(opendisplay(ilbm,wide,high,deep,modeid)))
                {
                message("Failed to open display.\n");
                return(1);
                }
        return(0);
        }


/* freedisplay
 *
 * closes and deallocates display from getdisplay (not colors)
 */
void freedisplay(struct ILBMInfo *ilbm)
        {
        closedisplay(ilbm);
        }