mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-08 01:39:36 +00:00
1
This commit is contained in:
@@ -0,0 +1,357 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <conio.h>
|
||||
#include <assert.h>
|
||||
#include "../../../public/jcalg1.h"
|
||||
|
||||
#define DEFAULT_BLOCK_READ_SIZE (512*1024)
|
||||
#define BLOCK_SIZE (16*1024)
|
||||
#define WINDOW_SIZE (16*1024)
|
||||
|
||||
static unsigned g_BlockReadSize = DEFAULT_BLOCK_READ_SIZE;
|
||||
|
||||
|
||||
static void * __stdcall jcalgAlloc(DWORD size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static bool __stdcall jcalgDealloc(void* pointer)
|
||||
{
|
||||
free(pointer);
|
||||
return true;
|
||||
}
|
||||
|
||||
void decompress( char* filenameIn, char* filenameOut )
|
||||
{
|
||||
FILE* hIn = fopen( filenameIn, "rb" );
|
||||
if( !hIn )
|
||||
{
|
||||
printf("Failed to open input file: %s\n",filenameIn);
|
||||
return;
|
||||
}
|
||||
|
||||
FILE* hOut = fopen( filenameOut, "wb+" );
|
||||
if( !hIn )
|
||||
{
|
||||
printf("Failed to open output file: %s\n",filenameOut);
|
||||
fclose(hIn);
|
||||
return;
|
||||
}
|
||||
|
||||
char* inputBuffer = (char*)malloc( g_BlockReadSize );
|
||||
|
||||
xCompressHeader header;
|
||||
fread(&header,1,sizeof(header), hIn );
|
||||
fseek(hIn, 0, SEEK_SET);
|
||||
|
||||
char* outputBuffer = (char *)malloc( header.nDecompressionBufferSize );
|
||||
|
||||
|
||||
for(;;)
|
||||
{
|
||||
|
||||
// Read in a buffer full of compressed data.
|
||||
unsigned bytesRead = (unsigned)fread(inputBuffer,1,g_BlockReadSize, hIn );
|
||||
if( !bytesRead )
|
||||
break;
|
||||
|
||||
unsigned outputBufferLength;
|
||||
|
||||
xCompressHeader* header = (xCompressHeader*)inputBuffer;
|
||||
if( header->nMagic == xCompressHeader::MAGIC
|
||||
&& header->VERSION == xCompressHeader::VERSION )
|
||||
{
|
||||
|
||||
printf("Found header:\n"
|
||||
"\t%i Version\n"
|
||||
"\t%i Uncompressed Size\n"
|
||||
"\t%i ReadBlockSize\n"
|
||||
"\t%i DecompressionBufferSize\n",header->nVersion, header->nUncompressedFileSize,header->nReadBlockSize,header->nDecompressionBufferSize );
|
||||
|
||||
outputBufferLength = JCALG1_Decompress_Formatted_Buffer( bytesRead - sizeof(*header), inputBuffer + sizeof(*header), g_BlockReadSize * 8, outputBuffer );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
outputBufferLength = JCALG1_Decompress_Formatted_Buffer( bytesRead, inputBuffer, g_BlockReadSize * 8, outputBuffer );
|
||||
}
|
||||
|
||||
assert(0xFFFFFFFF != outputBufferLength );
|
||||
fwrite( outputBuffer,1,outputBufferLength, hOut);
|
||||
|
||||
printf("block:%u\n", outputBufferLength);
|
||||
}
|
||||
|
||||
free(inputBuffer);
|
||||
free(outputBuffer);
|
||||
|
||||
fclose(hIn);
|
||||
fclose(hOut);
|
||||
}
|
||||
|
||||
void compressSimple(char* filenameIn, char* filenameOut )
|
||||
{
|
||||
FILE* hIn = fopen( filenameIn, "rb" );
|
||||
if( !hIn )
|
||||
{
|
||||
printf("Failed to open input file: %s\n",filenameIn);
|
||||
return;
|
||||
}
|
||||
|
||||
fseek(hIn, 0, SEEK_END);
|
||||
unsigned uncompressedSize = ftell(hIn);
|
||||
fseek(hIn, 0, SEEK_SET);
|
||||
|
||||
char* uncompressedData = (char*)malloc( uncompressedSize );
|
||||
fread( uncompressedData,1,uncompressedSize, hIn );
|
||||
fclose(hIn);
|
||||
|
||||
char* compressedData = (char*)malloc( uncompressedSize * 4 + sizeof( xCompressSimpleHeader ));
|
||||
int compressedSize = JCALG1_Compress(
|
||||
uncompressedData,
|
||||
uncompressedSize,
|
||||
compressedData + sizeof( xCompressSimpleHeader ),
|
||||
uncompressedSize,
|
||||
jcalgAlloc,
|
||||
jcalgDealloc,
|
||||
NULL,
|
||||
true);
|
||||
|
||||
xCompressSimpleHeader* header = (xCompressSimpleHeader*)compressedData;
|
||||
header->nMagic = xCompressSimpleHeader::MAGIC;
|
||||
header->nUncompressedSize = uncompressedSize;
|
||||
compressedSize += sizeof( xCompressSimpleHeader );
|
||||
|
||||
|
||||
printf("uncompressed size: %uk, compressedSize = %uk\n",uncompressedSize/1024, compressedSize / 1024);
|
||||
|
||||
FILE* hOut = fopen( filenameOut, "wb+" );
|
||||
if( !hIn )
|
||||
{
|
||||
printf("Failed to open output file: %s\n",filenameOut);
|
||||
fclose(hIn);
|
||||
return;
|
||||
}
|
||||
fwrite( compressedData, 1, compressedSize, hOut );
|
||||
fclose( hOut );
|
||||
}
|
||||
|
||||
void decompressSimple(char* filenameIn, char* filenameOut )
|
||||
{
|
||||
FILE* hIn = fopen( filenameIn, "rb" );
|
||||
if( !hIn )
|
||||
{
|
||||
printf("Failed to open input file: %s\n",filenameIn);
|
||||
return;
|
||||
}
|
||||
|
||||
fseek(hIn, 0, SEEK_END);
|
||||
unsigned compressedSize = ftell(hIn);
|
||||
fseek(hIn, 0, SEEK_SET);
|
||||
|
||||
char* compressedData = (char*)malloc( compressedSize );
|
||||
fread( compressedData,1,compressedSize, hIn );
|
||||
fclose(hIn);
|
||||
|
||||
char* decompressedData = (char*)malloc( ((xCompressSimpleHeader*)compressedData)->nUncompressedSize );
|
||||
|
||||
unsigned decompressedSize = JCALG1_Decompress_Simple_Buffer( compressedData, decompressedData );
|
||||
FILE* hOut = fopen( filenameOut, "wb+" );
|
||||
if( !hIn )
|
||||
{
|
||||
printf("Failed to open output file: %s\n",filenameOut);
|
||||
fclose(hIn);
|
||||
return;
|
||||
}
|
||||
fwrite( decompressedData, 1, decompressedSize, hOut );
|
||||
fclose( hOut );
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
if( argc < 4 || argc > 5)
|
||||
{
|
||||
puts("USAGE: xcompress [c|d|cs|ds] <inputfile> <outputfile> [readsizekb]");
|
||||
puts("\nIf cs is specified, a 'simple' archive is created. (unaligned and decompresses the entire thing to a buffer)");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if( !strcmpi(argv[1],"d") )
|
||||
{
|
||||
decompress( argv[2], argv[3] );
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
if( !strcmpi(argv[1],"cs") )
|
||||
{
|
||||
compressSimple(argv[2], argv[3]);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if( !strcmpi(argv[1],"ds") )
|
||||
{
|
||||
decompressSimple(argv[2], argv[3]);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
FILE* hIn = fopen( argv[2], "rb" );
|
||||
if( !hIn )
|
||||
{
|
||||
printf("Failed to open input file: %s\n",argv[2]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
fseek( hIn, 0, SEEK_END );
|
||||
unsigned nInputLength = ftell( hIn );
|
||||
fseek( hIn, 0, SEEK_SET );
|
||||
|
||||
// Grab
|
||||
if( argc >= 5 )
|
||||
{
|
||||
g_BlockReadSize = atoi(argv[4]) * 1024;
|
||||
if( g_BlockReadSize <= 0 )
|
||||
{
|
||||
printf("Invalid block read size! %s\n", argv[4]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
printf("\nOptimized for read block size: %u\n",g_BlockReadSize);
|
||||
|
||||
FILE* hOut = fopen( argv[3], "wb+" );
|
||||
if( !hIn )
|
||||
{
|
||||
printf("Failed to open output file: %s\n",argv[3]);
|
||||
fclose(hIn);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
unsigned char inputBuffer[BLOCK_SIZE];
|
||||
unsigned char outputBuffer[BLOCK_SIZE * 2];
|
||||
unsigned bytesThisBlock = 0, // Total output bytes this block
|
||||
inputBytesThisBlock = 0, // Total input bytes this block
|
||||
totalBytes = 0,
|
||||
inputBytes = 0;
|
||||
|
||||
// Set up and write out the header;
|
||||
xCompressHeader header;
|
||||
header.nMagic = xCompressHeader::MAGIC;
|
||||
header.nVersion = xCompressHeader::VERSION;
|
||||
header.nUncompressedFileSize = nInputLength;
|
||||
header.nReadBlockSize = g_BlockReadSize;
|
||||
header.nDecompressionBufferSize = 0;
|
||||
header.nWindowSize = WINDOW_SIZE;
|
||||
|
||||
totalBytes = bytesThisBlock = inputBytesThisBlock = sizeof(header);
|
||||
fwrite(&header,1,sizeof(header),hOut);
|
||||
|
||||
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
// Read an input buffer full of data:
|
||||
size_t bytesRead = fread(inputBuffer,1,sizeof(inputBuffer),hIn);
|
||||
if( !bytesRead )
|
||||
break;
|
||||
|
||||
inputBytes += (unsigned)bytesRead;
|
||||
|
||||
unsigned compressedSize = JCALG1_Compress(
|
||||
inputBuffer,
|
||||
(unsigned)bytesRead,
|
||||
outputBuffer + sizeof(short),
|
||||
16384,
|
||||
jcalgAlloc,
|
||||
jcalgDealloc,
|
||||
NULL,
|
||||
true);
|
||||
|
||||
unsigned outputBufferSize;
|
||||
|
||||
// If we couldn't compress this block, just write it out:
|
||||
if( compressedSize == 0 )
|
||||
{
|
||||
outputBufferSize = (unsigned)(bytesRead + sizeof(unsigned short));
|
||||
*((unsigned short*)outputBuffer) = ((unsigned short)bytesRead) | 0x8000;
|
||||
memcpy(outputBuffer+2,inputBuffer,bytesRead);
|
||||
}
|
||||
// Tag the compression header onto this block:
|
||||
else
|
||||
{
|
||||
outputBufferSize = compressedSize + sizeof(unsigned short);
|
||||
*((unsigned short*)outputBuffer) = compressedSize;
|
||||
}
|
||||
|
||||
// Do we have enough room in this chunk to fit this buffer?
|
||||
if( bytesThisBlock + outputBufferSize > g_BlockReadSize )
|
||||
{
|
||||
// no, first align it:
|
||||
while( bytesThisBlock < g_BlockReadSize )
|
||||
{
|
||||
char b = 0;
|
||||
fwrite( &b, 1, sizeof(b), hOut );
|
||||
bytesThisBlock++;
|
||||
totalBytes++;
|
||||
}
|
||||
|
||||
// Compute the minimum size of the decompression buffer:
|
||||
if( inputBytesThisBlock > header.nDecompressionBufferSize )
|
||||
{
|
||||
header.nDecompressionBufferSize = inputBytesThisBlock;
|
||||
}
|
||||
|
||||
// Start a new block:
|
||||
bytesThisBlock = 0;
|
||||
inputBytesThisBlock = 0;
|
||||
}
|
||||
|
||||
// Write the chunk out:
|
||||
fwrite(outputBuffer,1, outputBufferSize, hOut);
|
||||
inputBytesThisBlock += bytesRead;
|
||||
bytesThisBlock+=outputBufferSize;
|
||||
totalBytes+=outputBufferSize;
|
||||
|
||||
static int counter =0;
|
||||
counter++;
|
||||
|
||||
if( counter % 4 == 0 )
|
||||
{
|
||||
printf("\r \rInput:%uk Output:%uk (%0.1f%%)",inputBytes / 1024,totalBytes / 1024, ( (double)totalBytes / (double)inputBytes ) * 100);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
// Grab the last block (may be the only block)Compute the minimum size of the decompression buffer:
|
||||
if( inputBytesThisBlock > header.nDecompressionBufferSize )
|
||||
{
|
||||
header.nDecompressionBufferSize = inputBytesThisBlock;
|
||||
inputBytesThisBlock = 0;
|
||||
}
|
||||
|
||||
unsigned short terminator = 0;
|
||||
fwrite(&terminator, 1, sizeof(terminator), hOut );
|
||||
|
||||
// Align the file to a 2k boundary.
|
||||
while( ( ftell(hOut) % 2048 ) != 0)
|
||||
{
|
||||
fwrite(&terminator,1,1,hOut);
|
||||
}
|
||||
|
||||
// Write the header out again, this time with ideal decompression size:
|
||||
header.nDecompressionBufferSize += 128;
|
||||
|
||||
fseek( hOut, 0, SEEK_SET );
|
||||
fwrite(&header,1,sizeof(header),hOut);
|
||||
|
||||
|
||||
printf("\n");
|
||||
fclose(hIn);
|
||||
fclose(hOut);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xcompress", "xcompress.vcproj", "{14872A1D-B112-4092-9ABD-BFF782B80E43}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
Release = Release
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{14872A1D-B112-4092-9ABD-BFF782B80E43}.Debug.ActiveCfg = Debug|Win32
|
||||
{14872A1D-B112-4092-9ABD-BFF782B80E43}.Debug.Build.0 = Debug|Win32
|
||||
{14872A1D-B112-4092-9ABD-BFF782B80E43}.Release.ActiveCfg = Release|Win32
|
||||
{14872A1D-B112-4092-9ABD-BFF782B80E43}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,127 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="xcompress"
|
||||
ProjectGUID="{14872A1D-B112-4092-9ABD-BFF782B80E43}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="..\..\..\..\game\bin"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/xcompress.exe"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/xcompress.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="4"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="if exist ..\..\..\..\game\bin\"$(TargetName)".exe attrib -r ..\..\..\..\game\bin\"$(TargetName)".exe
|
||||
if exist "$(TargetPath)" copy "$(TargetPath)" ..\..\..\..\game\bin
|
||||
"
|
||||
Outputs="..\..\..\..\game\bin\$(TargetName).exe"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/xcompress.exe"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath="..\..\..\public\jcalg1.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\lib\public\jcalg1_static.lib">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\xcompress.cpp">
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
Reference in New Issue
Block a user