📄 hip.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 + -