
/*----------------------------------------------------------------------*
 * GETBITMAP.C  Support routines for reading 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 Commodore-Amiga computer.
 *----------------------------------------------------------------------*/

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

/* createbrush
 *
 * Passed an initialized ILBMInfo with a parsed IFFHandle (chunks parsed,
 * stopped at BODY),
 * gets the bitmap and colors
 * Sets up ilbm->brbitmap, ilbm->colortable, ilbm->ncolors
 * Returns 0 for success
 */
LONG createbrush(struct ILBMInfo *ilbm)
	{
	int error;

	error 			= getbitmap(ilbm);
	if(!error) error 	= loadbody(ilbm->ParseInfo.iff,
						ilbm->brbitmap,&ilbm->Bmhd);
	if(!error) 		getcolors(ilbm);
	if(error)  		deletebrush(ilbm);
	return(error);
	}

/* deletebrush
 *
 * closes and deallocates created brush bitmap and colors
 */
void deletebrush(ilbm)
struct ILBMInfo		*ilbm;
	{
	freebitmap(ilbm);
	freecolors(ilbm);
	}


/* getbitmap
 *
 * Passed an initialized ILBMInfo with parsed IFFHandle (chunks parsed,
 * stopped at BODY), allocates a BitMap structure and planes just large
 * enough for the BODY.  Generally used for brushes but may be used
 * to load backgrounds without displaying, or to load deep ILBM's.
 * Sets ilbm->brbitmap.  Returns 0 for success.
 */
LONG getbitmap(struct ILBMInfo *ilbm)
	{
	struct IFFHandle	*iff;
	BitMapHeader	*bmhd;
	USHORT			wide, high;
	LONG  error = NULL;
	int k, extra=0;
	BYTE deep;

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

	ilbm->brbitmap = NULL;

	if (!( bmhd = (BitMapHeader *)
			findpropdata(iff, ID_ILBM, ID_BMHD)))
		{
		message(SI(MSG_IFFP_NOBMHD));
		return(IFFERR_SYNTAX);
		}

	*(&ilbm->Bmhd) = *bmhd;	/* copy contents of BMHD */

	wide = BitsPerRow(bmhd->w);
	high = bmhd->h;
	deep = bmhd->nPlanes;

	ilbm->camg = getcamg(ilbm);

	D(bug("allocbitmap: bmhd=$%lx wide=%ld high=%ld deep=%ld\n",
			bmhd,wide,high,deep));
	/*
	 * Allocate Bitmap and planes
	 */
        extra = deep > 8 ? deep - 8 : 0;
	if(ilbm->brbitmap = AllocMem(sizeof(struct BitMap) + (extra<<2),MEMF_CLEAR))
		{
		InitBitMap(ilbm->brbitmap,deep,wide,high);
		for(k=0; k<deep && (!error); k++) 
		    {
		    if(!(ilbm->brbitmap->Planes[k] = AllocRaster(wide,high))) error = 1;
		    if(! error)
			BltClear(ilbm->brbitmap->Planes[k],RASSIZE(wide,high),0);
		    }

		if(error)
		    {
		    message(SI(MSG_IFFP_NORASTER));
		    freebitmap(ilbm);
		    }
		}
	else error = 1;
	return(error);
	}

	
/* freebitmap
 *
 * deallocates ilbm->brbitmap BitMap structure and planes 
 */
void freebitmap(struct ILBMInfo * ilbm)
	{
	int k, extra=0;

	if(ilbm->brbitmap)
		{	
		for(k=0; k< ilbm->brbitmap->Depth; k++) 
			{
			if(ilbm->brbitmap->Planes[k]) 
				FreeRaster(ilbm->brbitmap->Planes[k],
					   (USHORT)(ilbm->brbitmap->BytesPerRow << 3),
					   ilbm->brbitmap->Rows);
			}

        	extra = ilbm->brbitmap->Depth > 8 ? ilbm->brbitmap->Depth - 8 : 0;
		FreeMem(ilbm->brbitmap,sizeof(struct BitMap) + (extra << 2));
		ilbm->brbitmap = NULL;
		}
	}

/* end */
