⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hip.cpp

📁 My (so called) HiP compression algorithm as console mode utility. It s a hybrid of Lempel-Ziv 77 a
💻 CPP
字号:
/*****************************************************************************

   HiP - a hybrid compression algorithm
   ------------------------------------

   project start:
   16th September 2k2

   by yoda in 2002

*****************************************************************************/

#define  WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <crtdbg.h>

//#pragma optimize( "", off)

#include "WarnOff.h"
#include "LinkerCmds.h"
#include "Macros.h"

#include "clsFile.h"
#include "ByteWriter.h"
#include "ByteReader.h"
#include "StopWatch.h"
#include "HipPack.h"

//
// types
//
enum HIP_METHOD
{
	HIP_COMPRESS,
	HIP_DECOMPRESS
};

//
// constants
//
#ifdef VERBOSE_PLEASE
#define BUILD_TYPE "  verbose build"
#else
#define BUILD_TYPE ""
#endif

#define TITLE \
	"HiP beta 1 - A single file compressor\n" \
	"compiled: "__DATE__" "__TIME__""BUILD_TYPE"\n" \
	"by yoda in 2002\n" \
	"------------------------------------------------------------------\n\n"

#define CMD_LINE \
	"Command line:\n" \
	"	HiP.exe (/[compress[X]/decompress]) (infile) (outfile)\n" \
	"	X - compression level (1..6)\n"

#define DEFAULT_LEVEL 4

//
// prototypes
//
BOOL  IsKeyDown(int iVKey);
BOOL  __stdcall CompressionCallback( DWORD cbDone, DWORD cbTotal );
BOOL  CompressFile( char* szFile, char* szOutFile, BYTE byLevel );
BOOL  DecompressFile( char* szFile, char* szOutFile );
int   main( int argc, char *argv[] );

//
// global variables
//
BOOL        g_bUntouchedCallback = TRUE;

BOOL IsKeyDown(int iVKey)
{
	return ( HIWORD( GetAsyncKeyState(iVKey) ) != 0);
}

//
// Purpose:
//   Callback procedure for the HipPack class
//   Used during compresion only
//
BOOL __stdcall CompressionCallback( DWORD cbDone, DWORD cbTotal )
{
	static UINT  iCaretsPrinted;
	UINT         iCaretsNow;

	if ( g_bUntouchedCallback )
	{
		g_bUntouchedCallback = FALSE;
		iCaretsPrinted       = 0;
		// print little grid
		printf( "              (Press ESC to cancel!)\n" );
		printf( "     0%%                 50%%              100%%\n");
		printf( "   [ ........................................ ]" );
	}

	// ESC pressed ?
	if ( IsKeyDown( VK_ESCAPE ) )
	{
		printf( "\n-> Process canceled by user...\n" );
		return FALSE; // ERR
	}

    iCaretsNow = (DWORD)( (float)cbDone / (float)(cbTotal / 40) );

	if ( iCaretsNow > 40 || cbDone == cbTotal )
		iCaretsNow = 40;

	BOOL bFirstLoop = TRUE;
	if ( iCaretsPrinted != iCaretsNow )
	{
		for ( UINT i = 0 ; i < iCaretsNow; i++ )
		{
			if ( bFirstLoop )
			{
				printf( "\r   [ " );
				bFirstLoop = FALSE;
			}
			printf( "*" );
		}
		iCaretsPrinted = iCaretsNow;
	}

	// end reached ?
	if ( cbDone == cbTotal )
		printfnl;

	return TRUE; // continue compression
}

//
// Purpose:
//   The root routine to compress a single file
//
BOOL CompressFile( char* szFile, char* szOutFile, BYTE byLevel )
{
	clsFILE            infile, outfile;
	BOOL               bRet      = FALSE;
	PHipPack           pEngine   = NULL;
	CStopWatch         stopper; 

	// validate procedure input
	if ( byLevel < 1 || byLevel > 9 )
	{
		printf( "!! Invalid compression level !\n" );
		return FALSE; // ERR
	}
	printf( "-> Compression level: %u\n", byLevel );

	//
	// map the file into memory
	//
//	printf( "-> Mapping input file..." );
	if ( !infile.GetFileHandle( szFile, F_OPENEXISTING_R ) ||
		 !infile.MapFile() )
	{
		printf( "!! Mapping the input file failed !\n" );
		goto ExitProc; // ERR
	}

	//
	// analyse the input file's image
	//

	// 0 byte file ?
	if ( infile.GetFSize() == 0 )
	{
		printf( "!! Please no 0 byte file next time !\n" );
		goto ExitProc; // ERR
	}

	// initialize engine
	pEngine = new HipPack( infile.GetMapPtr(), infile.GetFSize() );
	pEngine->SetCallback( CompressionCallback );

	//
	// perform compression
	//
	void*  pOut;
	DWORD  cbOut;
	printf( "-> Compressing input block...\n" );

	stopper.Start();
	BOOL bCompRet = pEngine->PerformCompression( byLevel, &pOut, &cbOut );
	stopper.Stop();

	printf( "-> Time elapse: %umin %usec %ums\n",
		stopper.GetTimeMinutes(),
		stopper.GetTimeSeconds(),
		stopper.GetTimeMSeconds() ); 

	if ( !bCompRet )
		return FALSE; // ERR

	//
	// print result
	//
	printf( "-> Compression ratio: %.2f%%\n",
		(float)( ((float)100 * (float)cbOut) / (float)infile.GetFSize()) );
	printf( "-> Bpb: ~%.2f\n", ((float)cbOut/(float)infile.GetFSize()) * 8 );

	//
	// write resulted data block to disk
	//
	printf( "-> Writing output to disk: %s\n", szOutFile );
	if ( !outfile.GetFileHandle( szOutFile, F_CREATENEW ) )
	{
		printf( "!! Error while creating output file !\n" );
		goto ExitProc;
	}
	outfile.Write( pOut, cbOut );
	outfile.Destroy();

	bRet = TRUE; // return OK

//	printf( "-> READY\n" );

ExitProc:
	//
	// perform cleanups
	//
	if ( pEngine )
		delete pEngine;

	return bRet;
}

//
// Purpose:
//   The root routine to decompress a single file
//
BOOL DecompressFile( char* szFile, char* szOutFile )
{
	BOOL        bRet = FALSE;
	clsFILE     infile, outfile;
	PHipPack    pEngine = NULL;
	CStopWatch  stopper;

	//
	// map the input file into memory
	//
	if ( !infile.GetFileHandle( szFile, F_OPENEXISTING_R ) ||
		 !infile.MapFile() )
	{
		printf( "!! Mapping input file failed !\n" );
		goto ExitProc;
	}

	//
	// analyse the file
	//

	// 0 byte file ?
	if ( infile.GetFSize() == 0 )
	{
		printf( "!! Please no 0 byte file next time !\n" );
		return FALSE; // ERR
	}

	// initialize engine
	pEngine = new HipPack( infile.GetMapPtr(), infile.GetFSize() );

	void*  pOut;
	DWORD  cbOut;
	pEngine->PerformDecompression( &pOut, &cbOut );

	//
	// write the output 2 disk
	//
	printf( "-> Writing output to disk: %s\n", szOutFile );
	if ( !outfile.GetFileHandle( szOutFile, F_CREATENEW ) )
	{
		printf( "!! Error while creating output file !\n" );
		goto ExitProc;
	}
	outfile.Write( pOut, cbOut );
	outfile.Destroy();

    bRet = TRUE; // return OK

//	printf( "-> READY\n" );

ExitProc:
	if ( pEngine )
		delete pEngine;

	return bRet;
}

//
// ENTRYPOINT
//
int main( int argc, char *argv[] )
{
	HIP_METHOD  hipAction;
	clsFILE     openfile;

	//
	// print title
	//
	printf( TITLE );
	
	//
	// handle command line
	//
	if ( argc != 4 )
	{
		printf( "!! Invalid number of arguments !\n\n" );
		printf( CMD_LINE );
		return -1; // ERR
	}

	BYTE level;
	if ( strnicmp(argv[1], "/COMPRESS", 9 ) == 0)
	{	
		hipAction = HIP_COMPRESS;
		// receive eventually a compression level else take default
		level = (BYTE)((PCHAR)argv[1])[9];
		if ( level == 0 )
			level  = DEFAULT_LEVEL;
		else
			level -= 0x30;
	}
	else if ( lstrcmpi(argv[1], "/DECOMPRESS") == 0)
		hipAction = HIP_DECOMPRESS;
	else
	{
		printf( "!! Invalid first argument !\n\n" );
		printf( CMD_LINE );
		return -1; // ERR
	}
	if ( !openfile.FileExists( argv[2] ) )
	{
		printf( "!! Couldn't open input file !\n" );
		return -1; // ERR
	}

	//
	// process
	//
	printf( "Processing....%s\n", argv[2] );
	printf( "Modus........." );
	switch( hipAction )
	{
	case HIP_COMPRESS:
		printf( "Compress\n" );
//		printfnl;
		CompressFile( argv[2], argv[3], level );
		break;

	case HIP_DECOMPRESS:
		printf( "Decompress\n" );
//		printfnl;
		DecompressFile( argv[2], argv[3] );
		break;
	}

	return 0; // OK
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -