#define PROGRAM_NAME	"Explode"
#define VERSION		"v3.0"

/* Explode is to be used together with Decrunch3x.c */

/* This version of Explode uses Decrunch30.c to explode  */
/* data compressed with BtoC v3.0. Use it as an example. */

/* Sorry, no makefile.					*/
/* To compile and link (without optimization):		*/
/* gcc explode.c decrunch30.c -o Explode -lc -lamiga	*/

#include <exec/types.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <inline/exec.h>
#include <inline/dos.h>

#define BTOC_MSG	( (ULONG)'B'<<24L | (ULONG)'T'<<16L | 'O'<<8 | 'C' )

char *NO_MEM = "No memory.";
char *USAGE = "\x1B[33m"PROGRAM_NAME"\x1B[0m "VERSION
" - to test the compression algorytmh of BtoC "VERSION
"\nBy \x1B[3m\x1B[2mStefano Reksten \x1B[0mof 3AM - \x1B[1mThe Three Amigos!!!\x1B[0m\n"
"Usage: "PROGRAM_NAME" <file.CMPR>";


ULONG data_size;
BPTR handle;
UBYTE *expl_ptr, *cmpr_ptr;
UBYTE most_used;
BOOL verbose=FALSE;
char filename[128];

extern BOOL Decrunch30(UBYTE *,UBYTE *);

void Fail(char*);
int main(int,char**);


void Fail( char *s )
{
if ( s )	puts( s );
if ( handle )	Close( handle );
if ( expl_ptr )	FreeMem( expl_ptr, data_size );
if ( cmpr_ptr )	FreeMem( cmpr_ptr, data_size );

exit( 0 );
}


int main( int argc, char **argv )
{
if ( argc==1 )
	Fail( USAGE );

puts( PROGRAM_NAME );

strcpy( filename, argv[1+verbose] );
printf( "File choosen : %s\n", filename );

if ( !( handle=Open( filename, MODE_OLDFILE ) ) )
	Fail( "No file" );

Read( handle, &data_size, sizeof(ULONG) );
if ( data_size != BTOC_MSG )
	Fail( "Data NOT compressed with BtoC" );

Read( handle, &data_size, sizeof(ULONG) );
Read( handle, &most_used, sizeof(UBYTE) );

if ( !(expl_ptr=(UBYTE *)AllocMem( data_size, MEMF_PUBLIC ) ) )
	Fail( NO_MEM );

if ( !(cmpr_ptr=(UBYTE *)AllocMem( data_size, MEMF_PUBLIC ) ) )
	Fail( NO_MEM );

/* Actually, you don't need to Alloc "data_size" bytes, as you	*/
/* compressed your data. You should know the exact size of the	*/
/* compressed file. (Lock, Examine & Alloc, or WRITE IT ON A	*/
/* PIECE OF PAPER!!!)						*/
/* Doing THIS way is a waste of memory.				*/


Seek( handle, 0, OFFSET_BEGINNING );
Read( handle, cmpr_ptr, data_size );
Close( handle ); handle = NULL;

printf( "Now decrunching.\n" );

if ( Decrunch30( expl_ptr, cmpr_ptr ) )
	{
	printf( "Done, writing .EXPL file.\n" );

	if ( !stricmp( filename+strlen( filename )-4, ".CBM" ) )
		filename[ strlen( filename )-4 ] = NULL;

	strcat( filename, ".EXPL" );

	if ( !(handle = Open( filename, MODE_NEWFILE ) ) )
		Fail( "File not opened" );

	Write( handle, expl_ptr, data_size );

	Fail( "File exploded." );
	}
else	Fail( "Did NOT decrunch!" );
}
