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

📄 aricomp.cpp

📁 This is a little console mode utility program which is able to (de-)compress single files with a s
💻 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 + -