/////////////////////////////////////////////////////////////
// CINEMA SDK : FILTER																		 //
/////////////////////////////////////////////////////////////
// VERSION    : CINEMA 4D																	 //
/////////////////////////////////////////////////////////////
// (c) 1989-2002 MAXON Computer GmbH, all rights reserved	 //
/////////////////////////////////////////////////////////////

// BFF (=basic file format) image loader and saver example

#include "c4d.h"
#include "c4d_symbols.h"

// be sure to use a unique ID obtained from www.plugincafe.com
#define ID_BFFLOADER 1000983
#define ID_BFFSAVER  1000957

class BFFLoaderData : public BitmapLoaderData
{
	public:
		virtual Bool Identify(const Filename &name, UCHAR *probe, LONG size);
		virtual LONG Load(const Filename &name, BaseBitmap *bm, LONG frame);
		virtual LONG GetSaver(void) { return ID_BFFSAVER; }
};

class BFFSaverData : public BitmapSaverData
{
	public:
		virtual LONG Save(const Filename &name, BaseBitmap *bm, BaseContainer *data, LONG savebits);
};

Bool BFFLoaderData::Identify(const Filename &name, UCHAR *probe, LONG size)
{
	ULONG *p=(ULONG*)probe,v1=p[0];					 
	lMotor(&v1); 
	return v1==0x42464600;
}

LONG BFFLoaderData::Load(const Filename &name, BaseBitmap *bm, LONG frame)
{
	LONG			y,bw,bh,header;
	Bool			ok    = TRUE;
	UCHAR			*line = NULL;
	AutoAlloc<BaseFile>	file;
	if (!file) return IMAGE_NOMEM;

	if (!file->Open(name,GE_READ,FILE_NODIALOG,GE_MOTOROLA)) return IMAGE_DISKERROR;

	file->ReadLong(&header);
	file->ReadLong(&bw);
	file->ReadLong(&bh);

	line = (UCHAR*)GeAlloc(sizeof(UCHAR)*3*bw);

	if (bm->Init(bw,bh,24)!=IMAGE_OK || !line) 
	{ 
		GeFree(line); 
		return IMAGE_NOMEM; 
	}

	for (y=0; y<bh; y++)
	{
		file->ReadBytes(line,bw*3);
		bm->SetLine(y,line,24);
	}

	ok=file->GetError()==0;
	GeFree(line);
	
	return ok?IMAGE_OK:IMAGE_DISKERROR;
}

LONG BFFSaverData::Save(const Filename &name, BaseBitmap *bm, BaseContainer *data, LONG savebits)
{
	LONG			y,bw,bh;
	Bool			ok    = TRUE;
	UCHAR			*line = NULL;
	AutoAlloc<BaseFile> file;
	if (!file) return IMAGE_NOMEM;

	if (!file->Open(name,GE_WRITE,FILE_NODIALOG,GE_MOTOROLA)) return IMAGE_DISKERROR;

	bw=bm->GetBw();
	bh=bm->GetBh();
	
	file->WriteLong(0x42464600);
	file->WriteLong(bw);
	file->WriteLong(bh);

	line = (UCHAR*)GeAlloc(sizeof(UCHAR)*3*bw);
	if (!line) 
	{ 
		GeFree(line); 
		return IMAGE_NOMEM; 
	}

	for (y=0; y<bh; y++)
	{
		bm->GetLine(y,line);
		file->WriteBytes(line,bw*3);
	}

	ok=file->GetError()==0;
	GeFree(line);
	
	return ok?IMAGE_OK:IMAGE_DISKERROR;
}

Bool RegisterBFF(void)
{
	// decide by name if the plugin shall be registered - just for user convenience
	String name=GeLoadString(IDS_BFF); if (!name.Content()) return TRUE;
	
	if (!RegisterBitmapLoaderPlugin(ID_BFFLOADER,name,0,gNew BFFLoaderData)) return FALSE;
	if (!RegisterBitmapSaverPlugin(ID_BFFSAVER,name,0,gNew BFFSaverData,"bff")) return FALSE;
	return TRUE;
}

