📄 aricomp.cpp
字号:
/*
Static Arithmetic compression algorithm implementation
-------------------------------------------------------
console mode, single-file compressor
project start: 28th November 2002
by yoda
*/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <crtdbg.h>
#include "clsFile.h"
#include "StopWatch.h"
#include "AriCoder.h"
#include "CRC32.h"
#pragma comment(linker,"/SUBSYSTEM:CONSOLE") // a console, please
#pragma pack(1) // simon says: structures have to be byte aligned
// little optimization
#if !defined(_DEBUG)
#pragma comment(linker,"/FILEALIGN:512 /MERGE:.rdata=.text /MERGE:.data=.text /SECTION:.text,EWR /IGNORE:4078")
#endif
//
// constants
//
// [...]
//
// structs
//
// structures, you'll find in the compressed files
#include <PshPack1.h>
typedef struct _ARI_COMP_HEADER
{
WORD wSignature; // AC_SIGNATURE == "AC"
DWORD crcPre; // CRC before compression
// DWORD crcPost; // CRC after compression
// DWORD flags;
} ARI_COMP_HEADER, *PARI_COMP_HEADER;
#include <PopPack.h>
//
// prototypes
//
BOOL Compress(PSTR szInFile, PSTR szOutFile);
BOOL Decompress(PSTR szInFile, PSTR szOutFile);
void PrintCmdLine();
//
// macros
//
#include "macros.h"
//
// constants
//
#define AC_SIGNATURE 0x4341 // AC -> 'AriComp'-compressed
//
// global variables
//
// [...]
//
// root function if compress was specified in the command line
//
BOOL Compress(PSTR szInFile, PSTR szOutFile)
{
clsFILE *pfile, *cfOutFile;
DWORD dwOutSize;
ARI_COMP_HEADER hdr;
BOOL bRet = FALSE;
float fRatio;
DWORD cbWorkMem, dwPreCRC; //, dwPostCRC;
void* pWorkMem;
AriCoder encoder;
CStopWatch clock;
//
// map input file
//
pfile = new clsFILE();
if ( !pfile->GetFileHandle(szInFile, F_OPENEXISTING_R) )
{
printf("!! Error while opening input file image...\n");
return FALSE; // ERR
}
if ( !pfile->GetFSize() )
{
printf("!! 0 byte files aren't allowed as input...\n");
goto Cleanup; // ERR
}
if ( !pfile->MapFile() )
{
printf("!! Error while mapping file image...\n");
goto Cleanup; // ERR
}
// already compressed by HuffComp ?
try
{
if ( ((PARI_COMP_HEADER)pfile->GetMapPtr())->wSignature == AC_SIGNATURE )
printf("...input file is already compressed by AriComp\n");
}
catch(...)
{}
// some var inits
ZERO( hdr )
pWorkMem = pfile->GetMapPtr();
cbWorkMem = pfile->GetMapSize();
//
// calc pre-CRC32
//
dwPreCRC = CRC32::Generate( (PBYTE)pWorkMem, cbWorkMem );
printf( "-> CRC32: 0x%08lX\n", dwPreCRC );
//
// compress !
//
printf("-> Compressing input data block...\n");
clock.Start();
encoder.CompressData( (PBYTE)pWorkMem, cbWorkMem, (PBYTE&)pWorkMem, cbWorkMem );
clock.Stop();
// print symbol count table size
printf(
"-> Size of symbol count table: 0x%X bytes...\n",
encoder.m_cbSymCntTbl );
//
// calc post-CRC32
//
// dwPostCRC = CRC32::Generate( (PBYTE)pWorkMem, cbWorkMem );
//
// write output file
//
printf("-> Writing data to output file...\n");
cfOutFile = new clsFILE();
if ( !cfOutFile->GetFileHandle(szOutFile, F_CREATENEW) )
{
printf("!! Error while creating output file...\n");
goto Cleanup; // ERR
}
//
// build & write header
//
hdr.wSignature = AC_SIGNATURE;
hdr.crcPre = dwPreCRC;
// hdr.crcPost = dwPostCRC;
cfOutFile->Write( &hdr, sizeof(hdr) );
//
// write compressed block
//
cfOutFile->Write( pWorkMem, cbWorkMem );
delete cfOutFile;
//
// print little summary
//
dwOutSize = cbWorkMem;
fRatio = ((float)dwOutSize * 100) / (float)pfile->GetFSize();
printf( "...Compressed to: %u%%\n", (DWORD)fRatio);
printf( "...Time elapse: %u min %u s %u ms\n",
clock.GetTimeMinutes(),
clock.GetTimeSeconds(),
clock.GetTimeMSeconds() );
printf( "-> DONE\n" );
bRet = TRUE; // return OK
//
// cleanup
//
Cleanup:
delete pfile;
return bRet;
}
//
// root function if decompress was specified in the command line
//
BOOL Decompress(PSTR szInFile, PSTR szOutFile)
{
clsFILE *infile, *outfile;
PARI_COMP_HEADER pHdr;
CStopWatch clock;
//
// map input file to memory
//
infile = new clsFILE();
if ( !infile->GetFileHandle(szInFile, F_OPENEXISTING_R) )
{
printf("!! Error while opening input file image...\n");
return FALSE; // ERR
}
if ( !infile->GetFSize() )
{
printf("!! 0 byte files aren't allowed as input...\n");
delete infile;
return FALSE; // ERR
}
if ( !infile->MapFile() )
{
printf("!! Error while mapping file image...\n");
delete infile;
return FALSE; // ERR
}
//
// analyse data block
//
void *pWorkMem = infile->m_pMap;
DWORD cbWorkMem = infile->m_dwFileSize;
// check signature
pHdr = (PARI_COMP_HEADER)pWorkMem;
if (pHdr->wSignature != AC_SIGNATURE)
{
printf("!! Seems like the input image isn't an output of this tool - bad signature...\n");
delete infile;
return FALSE; // ERR
}
// check post-CRC
/*
if ( pHdr->crcPost != CRC32::Generate( (PBYTE)infile->m_pMap, infile->m_cbMappedSize ) )
{
printf( "!! CRC32 of packed file is BAD !\n" );
delete infile;
return FALSE; // ERR
}
*/
//
// decode input data block
//
printf("-> Decompressing input data block...\n");
AriCoder AriMan;
clock.Start();
AriMan.DecompressData(
(PBYTE)pWorkMem + sizeof(ARI_COMP_HEADER), cbWorkMem - sizeof(ARI_COMP_HEADER),
(PBYTE &)pWorkMem, cbWorkMem );
clock.Stop();
//
// validate CRC
//
if ( CRC32::Generate( (PBYTE)pWorkMem, cbWorkMem ) == pHdr->crcPre )
printf( "-> CRC32 is OK...\n" );
else
printf( "-> ! INVALID CRC32 !\n" );
//
// write the output buffer to disk
//
printf("-> Writing decompressed data to output file...\n");
outfile = new clsFILE();
if ( !outfile->GetFileHandle(szOutFile, F_CREATENEW) )
{
printf("!! Error while creating output file...\n");
delete infile;
delete outfile;
return FALSE; // ERR
}
outfile->Write( pWorkMem, cbWorkMem );
//
// print tiny summary
//
printf( "...Time elapse: %u min %u s %u ms\n",
clock.GetTimeMinutes(),
clock.GetTimeSeconds(),
clock.GetTimeMSeconds() );
printf("-> DONE\n");
//
// cleanup
//
delete infile;
delete outfile;
return TRUE; // OK
}
//
// print command line scheme to STDOUT
//
void PrintCmdLine()
{
printf("Command line:\n");
printf(" AriComp.EXE (input file) (output file) [/d]\n");
printf(" /d - means decompress input file and save to output file\n");
return;
}
//
// ENTRYPOINT
//
int main(int argc, char *argv[])
{
//
// print title
//
printf( "AriComp 1.0 - Static Arithmetic single-file compressor\n" );
printf( " compiled: "__DATE__" "__TIME__"\n" );
printf( " by yoda\n" );
printf( "------------------------------------------------------------------\n" );
printf( "\n");
//
// validate command line
//
if (argc < 3)
{
printf("!! Not enough arguments specified...\n");
PrintCmdLine();
return -1;
}
if (argc > 4)
{
printf("!! Too much arguments specified...\n");
PrintCmdLine();
return -1;
}
if (argc == 4 && lstrcmpi(argv[3], "/D") != 0)
{
PrintCmdLine();
printf("!! 3rd argument is optional and could only be \"/D\"...\n");
return -1;
}
//
// compress/decompress
//
printf("Processing: %s...\n", argv[1]);
printf("Modus: ");
__try
{
if (argc == 3)
{
printf("COMPRESS\n\n");
Compress(argv[1], argv[2]);
}
else
{
printf("DECOMPRESS\n\n");
Decompress(argv[1], argv[2]);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
printf("!! Exception caught in main()...\n");
return -1;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -