v1.12 - more comments, adding low-level example5, fixing issue when level_and_flags is set to MZ_DEFAULT_COMPRESSION, modified each project uses its own intermediate directory

This commit is contained in:
richgel99@gmail.com
2012-04-12 09:26:12 +00:00
parent 3172e9f7db
commit 6b95156074
9 changed files with 728 additions and 43 deletions

View File

@@ -22,7 +22,7 @@
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)bin"
IntermediateDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)\$(ConfigurationName)_$(PlatformName)"
ConfigurationType="1"
CharacterSet="1"
>
@@ -94,7 +94,7 @@
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)bin"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)\$(ConfigurationName)_$(PlatformName)"
ConfigurationType="1"
CharacterSet="1"
>
@@ -167,7 +167,7 @@
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)bin"
IntermediateDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)\$(ConfigurationName)_$(PlatformName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
@@ -244,7 +244,7 @@
<Configuration
Name="Release|x64"
OutputDirectory="$(SolutionDir)bin"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)\$(ConfigurationName)_$(PlatformName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"

View File

@@ -22,7 +22,7 @@
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)bin"
IntermediateDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)\$(ConfigurationName)_$(PlatformName)"
ConfigurationType="1"
CharacterSet="1"
>
@@ -94,7 +94,7 @@
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)bin"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)\$(ConfigurationName)_$(PlatformName)"
ConfigurationType="1"
CharacterSet="1"
>
@@ -167,7 +167,7 @@
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)bin"
IntermediateDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)\$(ConfigurationName)_$(PlatformName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
@@ -244,7 +244,7 @@
<Configuration
Name="Release|x64"
OutputDirectory="$(SolutionDir)bin"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)\$(ConfigurationName)_$(PlatformName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"

View File

@@ -22,7 +22,7 @@
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)bin"
IntermediateDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)\$(ConfigurationName)_$(PlatformName)"
ConfigurationType="1"
CharacterSet="1"
>
@@ -94,7 +94,7 @@
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)bin"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)\$(ConfigurationName)_$(PlatformName)"
ConfigurationType="1"
CharacterSet="1"
>
@@ -167,7 +167,7 @@
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)bin"
IntermediateDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)\$(ConfigurationName)_$(PlatformName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
@@ -244,7 +244,7 @@
<Configuration
Name="Release|x64"
OutputDirectory="$(SolutionDir)bin"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)\$(ConfigurationName)_$(PlatformName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"

View File

@@ -22,7 +22,7 @@
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)bin"
IntermediateDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)\$(ConfigurationName)_$(PlatformName)"
ConfigurationType="1"
CharacterSet="1"
>
@@ -94,7 +94,7 @@
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)bin"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)\$(ConfigurationName)_$(PlatformName)"
ConfigurationType="1"
CharacterSet="1"
>
@@ -167,7 +167,7 @@
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)bin"
IntermediateDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)\$(ConfigurationName)_$(PlatformName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
@@ -244,7 +244,7 @@
<Configuration
Name="Release|x64"
OutputDirectory="$(SolutionDir)bin"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)\$(ConfigurationName)_$(PlatformName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"

295
example5.c Normal file
View File

@@ -0,0 +1,295 @@
// example5.c - Demonstrates how to use miniz.c's low-level tdefl_compress() and tinfl_inflate() API's for simple file to file compression/decompression.
// The low-level API's are the fastest, make no use of dynamic memory allocation, and are the most flexible functions exposed by miniz.c.
// Public domain, April 11 2012, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c.
// For simplicity, this example is limited to files smaller than 4GB, but this is not a limitation of miniz.c.
#include "miniz.c"
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint;
#define my_max(a,b) (((a) > (b)) ? (a) : (b))
#define my_min(a,b) (((a) < (b)) ? (a) : (b))
// IN_BUF_SIZE is the size of the file read buffer.
// IN_BUF_SIZE must be >= 1
#define IN_BUF_SIZE (1024*512)
static uint8 s_inbuf[IN_BUF_SIZE];
// COMP_OUT_BUF_SIZE is the size of the output buffer used during compression.
// COMP_OUT_BUF_SIZE must be >= 1 and <= OUT_BUF_SIZE
#define COMP_OUT_BUF_SIZE (1024*512)
// OUT_BUF_SIZE is the size of the output buffer used during decompression.
// OUT_BUF_SIZE must be a power of 2 >= TINFL_LZ_DICT_SIZE (because the low-level decompressor not only writes, but reads from the output buffer as it decompresses)
//#define OUT_BUF_SIZE (TINFL_LZ_DICT_SIZE)
#define OUT_BUF_SIZE (1024*512)
static uint8 s_outbuf[OUT_BUF_SIZE];
int main(int argc, char *argv[])
{
const char *pMode;
FILE *pInfile, *pOutfile;
uint infile_size;
int level = Z_BEST_COMPRESSION;
int n = 1;
const char *pSrc_filename;
const char *pDst_filename;
const void *next_in = s_inbuf;
size_t avail_in = 0;
void *next_out = s_outbuf;
size_t avail_out = OUT_BUF_SIZE;
size_t total_in = 0, total_out = 0;
assert(COMP_OUT_BUF_SIZE <= OUT_BUF_SIZE);
printf("miniz.c version: %s\n", MZ_VERSION);
if (argc < 4)
{
printf("File to file compression/decompression using the low-level tinfl/tdefl API's.\n");
printf("Usage: example5 [options] [mode:c or d] infile outfile\n");
printf("\nModes:\n");
printf("c - Compresses file infile to a zlib stream in file outfile\n");
printf("d - Decompress zlib stream in file infile to file outfile\n");
printf("\nOptions:\n");
printf("-l[0-10] - Compression level, higher values are slower, 0 is none.\n");
return EXIT_FAILURE;
}
while ((n < argc) && (argv[n][0] == '-'))
{
switch (argv[n][1])
{
case 'l':
{
level = atoi(&argv[1][2]);
if ((level < 0) || (level > 10))
{
printf("Invalid level!\n");
return EXIT_FAILURE;
}
break;
}
default:
{
printf("Invalid option: %s\n", argv[n]);
return EXIT_FAILURE;
}
}
n++;
}
if ((argc - n) < 3)
{
printf("Must specify mode, input filename, and output filename after options!\n");
return EXIT_FAILURE;
}
else if ((argc - n) > 3)
{
printf("Too many filenames!\n");
return EXIT_FAILURE;
}
pMode = argv[n++];
if (!strchr("cCdD", pMode[0]))
{
printf("Invalid mode!\n");
return EXIT_FAILURE;
}
pSrc_filename = argv[n++];
pDst_filename = argv[n++];
printf("Mode: %c, Level: %u\nInput File: \"%s\"\nOutput File: \"%s\"\n", pMode[0], level, pSrc_filename, pDst_filename);
// Open input file.
pInfile = fopen(pSrc_filename, "rb");
if (!pInfile)
{
printf("Failed opening input file!\n");
return EXIT_FAILURE;
}
// Determine input file's size.
fseek(pInfile, 0, SEEK_END);
infile_size = ftell(pInfile);
fseek(pInfile, 0, SEEK_SET);
// Open output file.
pOutfile = fopen(pDst_filename, "wb");
if (!pOutfile)
{
printf("Failed opening output file!\n");
return EXIT_FAILURE;
}
printf("Input file size: %u\n", infile_size);
if ((pMode[0] == 'c') || (pMode[0] == 'C'))
{
uint infile_remaining = infile_size;
uint comp_flags = tdefl_create_comp_flags_from_zip_params(level, MZ_DEFAULT_WINDOW_BITS, MZ_DEFAULT_STRATEGY) | TDEFL_WRITE_ZLIB_HEADER;
// Initialize the low-level compressor.
tdefl_compressor deflator;
tdefl_status status = tdefl_init(&deflator, NULL, NULL, comp_flags);
if (status != TDEFL_STATUS_OKAY)
{
printf("tdefl_init() failed!\n");
return EXIT_FAILURE;
}
avail_out = COMP_OUT_BUF_SIZE;
// Compression.
for ( ; ; )
{
size_t in_bytes, out_bytes;
if (!avail_in)
{
// Input buffer is empty, so read more bytes from input file.
uint n = my_min(IN_BUF_SIZE, infile_remaining);
if (fread(s_inbuf, 1, n, pInfile) != n)
{
printf("Failed reading from input file!\n");
return EXIT_FAILURE;
}
next_in = s_inbuf;
avail_in = n;
infile_remaining -= n;
//printf("Input bytes remaining: %u\n", infile_remaining);
}
in_bytes = avail_in;
out_bytes = avail_out;
// Compress as much of the input as possible (or all of it) to the output buffer.
status = tdefl_compress(&deflator, next_in, &in_bytes, next_out, &out_bytes, infile_remaining ? TDEFL_NO_FLUSH : TDEFL_FINISH);
next_in = (const char *)next_in + in_bytes;
avail_in -= in_bytes;
total_in += in_bytes;
next_out = (char *)next_out + out_bytes;
avail_out -= out_bytes;
total_out += out_bytes;
if ((status != TDEFL_STATUS_OKAY) || (!avail_out))
{
// Output buffer is full, or compression is done or failed, so write buffer to output file.
uint n = COMP_OUT_BUF_SIZE - (uint)avail_out;
if (fwrite(s_outbuf, 1, n, pOutfile) != n)
{
printf("Failed writing to output file!\n");
return EXIT_FAILURE;
}
next_out = s_outbuf;
avail_out = COMP_OUT_BUF_SIZE;
}
if (status == TDEFL_STATUS_DONE)
{
// Compression completed successfully.
break;
}
else if (status != TDEFL_STATUS_OKAY)
{
// Compression somehow failed.
printf("tdefl_compress() failed with status %i!\n", status);
return EXIT_FAILURE;
}
}
}
else if ((pMode[0] == 'd') || (pMode[0] == 'D'))
{
// Decompression.
uint infile_remaining = infile_size;
tinfl_decompressor inflator;
tinfl_init(&inflator);
for ( ; ; )
{
size_t in_bytes, out_bytes;
tinfl_status status;
if (!avail_in)
{
// Input buffer is empty, so read more bytes from input file.
uint n = my_min(IN_BUF_SIZE, infile_remaining);
if (fread(s_inbuf, 1, n, pInfile) != n)
{
printf("Failed reading from input file!\n");
return EXIT_FAILURE;
}
next_in = s_inbuf;
avail_in = n;
infile_remaining -= n;
}
in_bytes = avail_in;
out_bytes = avail_out;
status = tinfl_decompress(&inflator, (const mz_uint8 *)next_in, &in_bytes, s_outbuf, (mz_uint8 *)next_out, &out_bytes, (infile_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0) | TINFL_FLAG_PARSE_ZLIB_HEADER);
avail_in -= in_bytes;
next_in = (const mz_uint8 *)next_in + in_bytes;
total_in += in_bytes;
avail_out -= out_bytes;
next_out = (mz_uint8 *)next_out + out_bytes;
total_out += out_bytes;
if ((status <= TINFL_STATUS_DONE) || (!avail_out))
{
// Output buffer is full, or decompression is done, so write buffer to output file.
uint n = OUT_BUF_SIZE - (uint)avail_out;
if (fwrite(s_outbuf, 1, n, pOutfile) != n)
{
printf("Failed writing to output file!\n");
return EXIT_FAILURE;
}
next_out = s_outbuf;
avail_out = OUT_BUF_SIZE;
}
// If status is <= TINFL_STATUS_DONE then either decompression is done or something went wrong.
if (status <= TINFL_STATUS_DONE)
{
if (status == TINFL_STATUS_DONE)
{
// Decompression completed successfully.
break;
}
else
{
// Decompression failed.
printf("tinfl_decompress() failed with status %i!\n", status);
return EXIT_FAILURE;
}
}
}
}
else
{
printf("Invalid mode!\n");
return EXIT_FAILURE;
}
fclose(pInfile);
if (EOF == fclose(pOutfile))
{
printf("Failed writing to output file!\n");
return EXIT_FAILURE;
}
printf("Total input bytes: %u\n", total_in);
printf("Total output bytes: %u\n", total_out);
printf("Success.\n");
return EXIT_SUCCESS;
}

346
example5.vcproj Normal file
View File

@@ -0,0 +1,346 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="example5"
ProjectGUID="{AE293522-92D8-4B60-95C7-B4AEE10A303F}"
RootNamespace="example5"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)bin"
IntermediateDirectory="$(ProjectName)\$(ConfigurationName)_$(PlatformName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="4"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)\$(ProjectName)D.exe"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)bin"
IntermediateDirectory="$(ProjectName)\$(ConfigurationName)_$(PlatformName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="4"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)\$(ProjectName)_x64D.exe"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)bin"
IntermediateDirectory="$(ProjectName)\$(ConfigurationName)_$(PlatformName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="4"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(SolutionDir)bin"
IntermediateDirectory="$(ProjectName)\$(ConfigurationName)_$(PlatformName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="4"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)\$(ProjectName)_x64.exe"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FD737F1-C7A5-4376-A066-2A32D752A31F}"
>
<File
RelativePath=".\example5.c"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{17DA6AB6-F800-4c08-8B7A-83BB121AAC02}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -9,6 +9,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example3", "example3.vcproj
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example4", "example4.vcproj", "{AE293522-92D8-4B60-95C7-C3AEE10A303F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example5", "example5.vcproj", "{AE293522-92D8-4B60-95C7-B4AEE10A303F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -49,6 +51,14 @@ Global
{AE293522-92D8-4B60-95C7-C3AEE10A303F}.Release|Win32.Build.0 = Release|Win32
{AE293522-92D8-4B60-95C7-C3AEE10A303F}.Release|x64.ActiveCfg = Release|x64
{AE293522-92D8-4B60-95C7-C3AEE10A303F}.Release|x64.Build.0 = Release|x64
{AE293522-92D8-4B60-95C7-B4AEE10A303F}.Debug|Win32.ActiveCfg = Debug|Win32
{AE293522-92D8-4B60-95C7-B4AEE10A303F}.Debug|Win32.Build.0 = Debug|Win32
{AE293522-92D8-4B60-95C7-B4AEE10A303F}.Debug|x64.ActiveCfg = Debug|x64
{AE293522-92D8-4B60-95C7-B4AEE10A303F}.Debug|x64.Build.0 = Debug|x64
{AE293522-92D8-4B60-95C7-B4AEE10A303F}.Release|Win32.ActiveCfg = Release|Win32
{AE293522-92D8-4B60-95C7-B4AEE10A303F}.Release|Win32.Build.0 = Release|Win32
{AE293522-92D8-4B60-95C7-B4AEE10A303F}.Release|x64.ActiveCfg = Release|x64
{AE293522-92D8-4B60-95C7-B4AEE10A303F}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

80
miniz.c
View File

@@ -1,30 +1,32 @@
/* miniz.c v1.11 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
/* miniz.c v1.12 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
See "unlicense" statement at the end of this file.
Rich Geldreich <richgel99@gmail.com>, last updated May 27, 2011
Rich Geldreich <richgel99@gmail.com>, last updated April 12, 2012
Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
Most API's defined in miniz.c are optional. For example, to disable the archive related functions just define
MINIZ_NO_ARCHIVE_APIS, or to get rid of all stdio usage define MINIZ_NO_STDIO (see the list below for more macros).
* Change History
May 15, v1.09 - Initial stable release.
May 27, v1.10 - Substantial compressor optimizations:
4/12/12 v1.12 - More comments, added low-level example5.c, fixed a couple minor level_and_flags issues in the archive API's.
level_and_flags can now be set to MZ_DEFAULT_COMPRESSION. Thanks to Bruce Dawson <bruced@valvesoftware.com> for the feedback/bug report.
5/28/11 v1.11 - Added statement from unlicense.org
5/27/11 v1.10 - Substantial compressor optimizations:
Level 1 is now ~4x faster than before. The L1 compressor's throughput now varies between 70-110MB/sec. on a
Core i7 (actual throughput varies depending on the type of data, and x64 vs. x86).
Improved baseline L2-L9 compression perf. Also, greatly improved compression perf. issues on some file types.
Refactored the compression code for better readability and maintainability.
Added level 10 compression level (L10 has slightly better ratio than level 9, but could have a potentially large
drop in throughput on some files).
May 28, v1.11 - Added statement from unlicense.org
5/15/11 v1.09 - Initial stable release.
* Deflate/Inflate implementation notes:
* Low-level Deflate/Inflate implementation notes:
Compression: Use the "tdefl" API's. The compressor supports raw, static, and dynamic blocks, lazy or
greedy parsing, match length filtering, RLE-only, and Huffman-only streams. It performs and compresses
approximately as well as zlib.
Decompression: Use the "tinfl" API's. The entire decompressor is implemented as a single function
coroutine: see tinfl_decompress(). It supports decompression into a 32KB wrapping buffer or into a memory
coroutine: see tinfl_decompress(). It supports decompression into a 32KB (or larger power of 2) wrapping buffer, or into a memory
block large enough to hold the entire file.
The low-level tdefl/tinfl API's do not make any use of dynamic memory allocation.
@@ -37,7 +39,7 @@
deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound
inflateInit/inflateInit2/inflate/inflateEnd
compress, compress2, compressBound, uncompress
CRC-32, Adler-32
CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly routines.
Supports raw deflate streams or standard zlib streams with adler-32 checking.
Limitations:
@@ -202,21 +204,21 @@ enum { MZ_DEFAULT_STRATEGY = 0, MZ_FILTERED = 1, MZ_HUFFMAN_ONLY = 2, MZ_RLE = 3
#ifndef MINIZ_NO_ZLIB_APIS
#define MZ_VERSION "9.1.11"
#define MZ_VERNUM 0x91B0
#define MZ_VERSION "9.1.12"
#define MZ_VERNUM 0x91C0
#define MZ_VER_MAJOR 9
#define MZ_VER_MINOR 1
#define MZ_VER_REVISION 11
#define MZ_VER_REVISION 12
#define MZ_VER_SUBREVISION 0
// Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other stuff is for advanced use.
// Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other values are for advanced use (refer to the zlib docs).
enum { MZ_NO_FLUSH = 0, MZ_PARTIAL_FLUSH = 1, MZ_SYNC_FLUSH = 2, MZ_FULL_FLUSH = 3, MZ_FINISH = 4, MZ_BLOCK = 5 };
// Return status codes. MZ_PARAM_ERROR is non-standard.
enum { MZ_OK = 0, MZ_STREAM_END = 1, MZ_NEED_DICT = 2, MZ_ERRNO = -1, MZ_STREAM_ERROR = -2, MZ_DATA_ERROR = -3, MZ_MEM_ERROR = -4, MZ_BUF_ERROR = -5, MZ_VERSION_ERROR = -6, MZ_PARAM_ERROR = -10000 };
// Compression levels.
enum { MZ_NO_COMPRESSION = 0, MZ_BEST_SPEED = 1, MZ_BEST_COMPRESSION = 9, MZ_DEFAULT_COMPRESSION = -1 };
// Compression levels: 0-9 are the standard zlib-style levels, 10 is best possible compression (not zlib compatible, and may be very slow), MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL.
enum { MZ_NO_COMPRESSION = 0, MZ_BEST_SPEED = 1, MZ_BEST_COMPRESSION = 9, MZ_UBER_COMPRESSION = 10, MZ_DEFAULT_LEVEL = 6, MZ_DEFAULT_COMPRESSION = -1 };
// Window bits
#define MZ_DEFAULT_WINDOW_BITS 15
@@ -585,11 +587,13 @@ mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilena
// Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive.
// To add a directory entry, call this method with an archive name ending in a forwardslash with empty buffer.
// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags);
mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32);
#ifndef MINIZ_NO_STDIO
// Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive.
// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
#endif
@@ -610,6 +614,7 @@ mz_bool mz_zip_writer_end(mz_zip_archive *pZip);
// Misc. high-level helper functions:
// mz_zip_add_mem_to_archive_file_in_place() efficiently (but not atomically) appends a memory blob to a ZIP archive.
// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
// Reads a single file from an archive into a heap block.
@@ -622,7 +627,11 @@ void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char
// ------------------- Low-level Decompression API Definitions
// Decompression flags.
// Decompression flags used by tinfl_decompress().
// TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream.
// TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available beyond the end of the supplied input buffer. If clear, the input buffer contains all remaining input.
// TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large enough to hold the entire decompressed stream. If clear, the output buffer is at least the size of the dictionary (typically 32KB).
// TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes.
enum
{
TINFL_FLAG_PARSE_ZLIB_HEADER = 1,
@@ -714,17 +723,21 @@ struct tinfl_decompressor_tag
// Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently).
#define TDEFL_LESS_MEMORY 0
// Compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search):
// tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search):
// TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap compression), 4095=Huffman+LZ (slowest/best compression).
enum
{
TDEFL_HUFFMAN_ONLY = 0, TDEFL_DEFAULT_MAX_PROBES = 128, TDEFL_MAX_PROBES_MASK = 0xFFF
};
// TDEFL_WRITE_ZLIB_HEADER: If set, the compressor outputs a zlib header before the deflate data, and the Adler-32 of the source data at the end. Otherwise, you'll get raw deflate data.
// TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even when not writing zlib headers).
// TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more efficient lazy parsing.
// TDEFL_NONDETERMINISTIC_PARSING_FLAG: Enable to decrease the compressor's initialization time to the minimum, but the output may vary from run to run given the same input (depending on the contents of memory).
// TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1)
// TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled.
// TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables.
// TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks.
enum
{
TDEFL_WRITE_ZLIB_HEADER = 0x01000,
@@ -794,6 +807,7 @@ typedef enum
TDEFL_FINISH = 4
} tdefl_flush;
// tdefl's compression state structure.
typedef struct
{
tdefl_put_buf_func_ptr m_pPut_buf_func;
@@ -822,11 +836,16 @@ typedef struct
} tdefl_compressor;
// Initializes the compressor.
// There is no corresponding deinit() function because the tdefl API's do not dynamically allocate memory.
// pBut_buf_func: If NULL, output data will be supplied to the specified callback. In this case, the user should call the tdefl_compress_buffer() API for compression.
// If pBut_buf_func is NULL the user should always call the tdefl_compress() API.
// flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.)
tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
// Compresses a block of data, consuming as much of the input as possible, and writing as much compressed data as possible.
// Compresses a block of data, consuming as much of the specified input buffer as possible, and writing as much compressed data to the specified output buffer as possible.
tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush);
// tdefl_compress_buffer() is only usable when the tdefl_init() is called with a valid tdefl_put_buf_func_ptr.
// tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr.
// tdefl_compress_buffer() always consumes the entire input buffer.
tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush);
@@ -2691,7 +2710,7 @@ static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256,
// level may actually range from [0,10] (10 is a "hidden" max level, where we want a bit more compression and it's fine if throughput to fall off a cliff on some files).
mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy)
{
mz_uint comp_flags = s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : 6] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0);
mz_uint comp_flags = s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0);
if (window_bits > 0) comp_flags |= TDEFL_WRITE_ZLIB_HEADER;
if (!level) comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS;
@@ -4041,15 +4060,20 @@ static mz_bool mz_zip_writer_write_zeros(mz_zip_archive *pZip, mz_uint64 cur_fil
mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32)
{
mz_uint16 method = 0, dos_time = 0, dos_date = 0;
mz_uint level = level_and_flags & 0xF, ext_attributes = 0, num_alignment_padding_bytes;
mz_uint level, ext_attributes = 0, num_alignment_padding_bytes;
mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0;
size_t archive_name_size;
mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
tdefl_compressor *pComp = NULL;
mz_bool store_data_uncompressed = ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA));
mz_bool store_data_uncompressed;
mz_zip_internal_state *pState;
if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) || (!pArchive_name) || ((comment_size) && (!pComment)) || (pZip->m_total_files == 0xFFFF) || (level > 10))
if ((int)level_and_flags < 0)
level_and_flags = MZ_DEFAULT_LEVEL;
level = level_and_flags & 0xF;
store_data_uncompressed = ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA));
if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) || (!pArchive_name) || ((comment_size) && (!pComment)) || (pZip->m_total_files == 0xFFFF) || (level > MZ_UBER_COMPRESSION))
return MZ_FALSE;
pState = pZip->m_pState;
@@ -4186,14 +4210,18 @@ mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name
#ifndef MINIZ_NO_STDIO
mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags)
{
mz_uint uncomp_crc32 = MZ_CRC32_INIT, level = level_and_flags & 0xF, num_alignment_padding_bytes;
mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes;
mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0;
mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = 0, comp_size = 0;
size_t archive_name_size;
mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
MZ_FILE *pSrc_file = NULL;
if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > 10))
if ((int)level_and_flags < 0)
level_and_flags = MZ_DEFAULT_LEVEL;
level = level_and_flags & 0xF;
if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION))
return MZ_FALSE;
if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)
return MZ_FALSE;
@@ -4582,7 +4610,9 @@ mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const
mz_zip_archive zip_archive;
struct MZ_FILE_STAT_STRUCT file_stat;
MZ_CLEAR_OBJ(zip_archive);
if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) || ((comment_size) && (!pComment)) || ((level_and_flags & 0xF) > 9))
if ((int)level_and_flags < 0)
level_and_flags = MZ_DEFAULT_LEVEL;
if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) || ((comment_size) && (!pComment)) || ((level_and_flags & 0xF) > MZ_UBER_COMPRESSION))
return MZ_FALSE;
if (!mz_zip_writer_validate_archive_name(pArchive_name))
return MZ_FALSE;

View File

@@ -32,7 +32,11 @@ typedef unsigned long long mz_uint64;
// Works around MSVC's spammy "warning C4127: conditional expression is constant" message.
#define MZ_MACRO_END while (0, 0)
// Decompression flags.
// Decompression flags used by tinfl_decompress().
// TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream.
// TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available beyond the end of the supplied input buffer. If clear, the input buffer contains all remaining input.
// TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large enough to hold the entire decompressed stream. If clear, the output buffer is at least the size of the dictionary (typically 32KB).
// TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes.
enum
{
TINFL_FLAG_PARSE_ZLIB_HEADER = 1,