diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/xbox/xcompress | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'utils/xbox/xcompress')
| -rw-r--r-- | utils/xbox/xcompress/xcompress.cpp | 357 | ||||
| -rw-r--r-- | utils/xbox/xcompress/xcompress.sln | 21 | ||||
| -rw-r--r-- | utils/xbox/xcompress/xcompress.vcproj | 127 |
3 files changed, 505 insertions, 0 deletions
diff --git a/utils/xbox/xcompress/xcompress.cpp b/utils/xbox/xcompress/xcompress.cpp new file mode 100644 index 0000000..df87f00 --- /dev/null +++ b/utils/xbox/xcompress/xcompress.cpp @@ -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); + +}
\ No newline at end of file diff --git a/utils/xbox/xcompress/xcompress.sln b/utils/xbox/xcompress/xcompress.sln new file mode 100644 index 0000000..4a59466 --- /dev/null +++ b/utils/xbox/xcompress/xcompress.sln @@ -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 diff --git a/utils/xbox/xcompress/xcompress.vcproj b/utils/xbox/xcompress/xcompress.vcproj new file mode 100644 index 0000000..f9c43cc --- /dev/null +++ b/utils/xbox/xcompress/xcompress.vcproj @@ -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> |