├── CMakeLists.txt ├── LICENSE ├── README.md ├── example1 ├── example1.c └── example1.vcxproj ├── example2 ├── example2.c └── example2.vcxproj ├── example3 ├── example3.cpp └── example3.vcxproj ├── example4 ├── cfile_stream.cpp ├── cfile_stream.h ├── comp_stream.cpp ├── comp_stream.h ├── data_stream.cpp ├── data_stream.h ├── data_stream_serializer.h ├── dynamic_stream.cpp ├── dynamic_stream.h ├── example4.cpp ├── example4.vcxproj ├── mem_stream.cpp ├── mem_stream.h └── stream_common.h ├── include ├── lzham.h ├── lzham_dynamic_lib.h ├── lzham_exports.inc ├── lzham_static_lib.h └── zlib.h ├── lzham.sln ├── lzham7zip ├── LzhamCodec.def ├── LzhamCodec.sln ├── LzhamCodec.vcxproj └── LzhamRegister.cpp ├── lzhamcomp ├── CMakeLists.txt ├── lzham_comp.h ├── lzham_lzbase.cpp ├── lzham_lzbase.h ├── lzham_lzcomp.cpp ├── lzham_lzcomp_internal.cpp ├── lzham_lzcomp_internal.h ├── lzham_lzcomp_state.cpp ├── lzham_match_accel.cpp ├── lzham_match_accel.h ├── lzham_null_threading.h ├── lzham_pthreads_threading.cpp ├── lzham_pthreads_threading.h ├── lzham_threading.h ├── lzham_win32_threading.cpp ├── lzham_win32_threading.h └── lzhamcomp.vcxproj ├── lzhamdecomp ├── CMakeLists.txt ├── lzham_assert.cpp ├── lzham_assert.h ├── lzham_checksum.cpp ├── lzham_checksum.h ├── lzham_config.h ├── lzham_core.h ├── lzham_decomp.h ├── lzham_helpers.h ├── lzham_huffman_codes.cpp ├── lzham_huffman_codes.h ├── lzham_lzdecomp.cpp ├── lzham_lzdecompbase.cpp ├── lzham_lzdecompbase.h ├── lzham_math.h ├── lzham_mem.cpp ├── lzham_mem.h ├── lzham_platform.cpp ├── lzham_platform.h ├── lzham_prefix_coding.cpp ├── lzham_prefix_coding.h ├── lzham_symbol_codec.cpp ├── lzham_symbol_codec.h ├── lzham_timer.cpp ├── lzham_timer.h ├── lzham_traits.h ├── lzham_types.h ├── lzham_utils.h ├── lzham_vector.cpp ├── lzham_vector.h └── lzhamdecomp.vcxproj ├── lzhamdll ├── CMakeLists.txt ├── lzham.vcxproj ├── lzham_api.cpp ├── lzham_dll_main.cpp └── lzhamdll.def ├── lzhamlib ├── lzham_lib.cpp └── lzhamlib.vcxproj └── lzhamtest ├── CMakeLists.txt ├── lzhamtest.cpp ├── lzhamtest.vcxproj ├── timer.cpp └── timer.h /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # PROJECT(lzham) 2 | cmake_minimum_required(VERSION 2.8) 3 | option(BUILD_X64 "build 64-bit" ON) 4 | option(BUILD_SHARED_LIBS "build shared/static libs" ON) 5 | 6 | add_subdirectory(lzhamdecomp) 7 | add_subdirectory(lzhamcomp) 8 | add_subdirectory(lzhamdll) 9 | add_subdirectory(lzhamtest) 10 | 11 | install(FILES include/lzham_dynamic_lib.h 12 | include/lzham_exports.inc 13 | include/lzham.h 14 | include/lzham_static_lib.h 15 | include/zlib.h 16 | DESTINATION include) 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2009-2015 Richard Geldreich, Jr. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /example1/example1.c: -------------------------------------------------------------------------------- 1 | // example1.c - Demonstrates how to use LZHAM's zlib emulation API's (lzham_deflateInit2(), lzham_deflate(), lzham_inflateInit2(), lzham_inflate(), etc.) for 2 | // streaming compression/decompression of files. 3 | // This example statically links against the lzhamlib, lzhamcomp, and lzhamdecomp libs. 4 | // For simplicity, this example is limited to files smaller than 4GB (not a limitation of LZHAM, just this sample). 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | // Define LZHAM_DEFINE_ZLIB_API causes lzham.h to remap the standard zlib.h functions/macro definitions to lzham's. 11 | // This is totally optional - you can also directly use the lzham_* functions and macros instead. 12 | #define LZHAM_DEFINE_ZLIB_API 13 | #include "lzham_static_lib.h" 14 | 15 | typedef unsigned char uint8; 16 | typedef unsigned short uint16; 17 | typedef unsigned int uint; 18 | 19 | #define my_max(a,b) (((a) > (b)) ? (a) : (b)) 20 | #define my_min(a,b) (((a) < (b)) ? (a) : (b)) 21 | 22 | #define BUF_SIZE (1024 * 1024) 23 | static uint8 s_inbuf[BUF_SIZE]; 24 | static uint8 s_outbuf[BUF_SIZE]; 25 | 26 | // Hard coded 2^23=8MB dictionary size (relatively small). 27 | #define WINDOW_BITS 23 28 | 29 | int main(int argc, char *argv[]) 30 | { 31 | const char *pMode; 32 | FILE *pInfile, *pOutfile; 33 | uint infile_size; 34 | int level = Z_BEST_COMPRESSION; 35 | z_stream stream; 36 | int n = 1; 37 | const char *pSrc_filename; 38 | const char *pDst_filename; 39 | 40 | printf("LZHAM example1 (streaming compression/decompression)\nUsing library version %s\n", ZLIB_VERSION); 41 | 42 | if (argc < 4) 43 | { 44 | printf("Usage: example1 [options] [mode:c or d] infile outfile\n"); 45 | printf("\nModes:\n"); 46 | printf("c - Compresses file infile to a LZHAM zlib stream in file outfile\n"); 47 | printf("d - Decompress a LZHAM zlib stream in file infile to file outfile\n"); 48 | printf("\nOptions:\n"); 49 | printf("-l[0-10] - Compression level, higher values are slower.\n"); 50 | return EXIT_FAILURE; 51 | } 52 | 53 | while ((n < argc) && (argv[n][0] == '-')) 54 | { 55 | switch (argv[n][1]) 56 | { 57 | case 'l': 58 | { 59 | level = atoi(&argv[1][2]); 60 | if ((level < 0) || (level > 10)) 61 | { 62 | printf("Invalid level!\n"); 63 | return EXIT_FAILURE; 64 | } 65 | break; 66 | } 67 | default: 68 | { 69 | printf("Invalid option: %s\n", argv[n]); 70 | return EXIT_FAILURE; 71 | } 72 | } 73 | n++; 74 | } 75 | 76 | if ((argc - n) < 3) 77 | { 78 | printf("Must specify mode, input filename, and output filename after options!\n"); 79 | return EXIT_FAILURE; 80 | } 81 | else if ((argc - n) > 3) 82 | { 83 | printf("Too many filenames!\n"); 84 | return EXIT_FAILURE; 85 | } 86 | 87 | pMode = argv[n++]; 88 | if (!strchr("cCdD", pMode[0])) 89 | { 90 | printf("Invalid mode!\n"); 91 | return EXIT_FAILURE; 92 | } 93 | 94 | pSrc_filename = argv[n++]; 95 | pDst_filename = argv[n++]; 96 | 97 | printf("Mode: %c, Level: %u\nInput File: \"%s\"\nOutput File: \"%s\"\n", pMode[0], level, pSrc_filename, pDst_filename); 98 | 99 | // Open input file. 100 | pInfile = fopen(pSrc_filename, "rb"); 101 | if (!pInfile) 102 | { 103 | printf("Failed opening input file!\n"); 104 | return EXIT_FAILURE; 105 | } 106 | 107 | // Determine input file's size. 108 | fseek(pInfile, 0, SEEK_END); 109 | infile_size = ftell(pInfile); 110 | fseek(pInfile, 0, SEEK_SET); 111 | 112 | // Open output file. 113 | pOutfile = fopen(pDst_filename, "wb"); 114 | if (!pOutfile) 115 | { 116 | printf("Failed opening output file!\n"); 117 | return EXIT_FAILURE; 118 | } 119 | 120 | printf("Input file size: %u\n", infile_size); 121 | 122 | // Init the z_stream 123 | memset(&stream, 0, sizeof(stream)); 124 | stream.next_in = s_inbuf; 125 | stream.avail_in = 0; 126 | stream.next_out = s_outbuf; 127 | stream.avail_out = BUF_SIZE; 128 | 129 | if ((pMode[0] == 'c') || (pMode[0] == 'C')) 130 | { 131 | // Compression. 132 | uint infile_remaining = infile_size; 133 | 134 | if (deflateInit2(&stream, level, LZHAM_Z_LZHAM, WINDOW_BITS, 9, LZHAM_Z_DEFAULT_STRATEGY) != Z_OK) 135 | { 136 | printf("deflateInit() failed!\n"); 137 | return EXIT_FAILURE; 138 | } 139 | 140 | for ( ; ; ) 141 | { 142 | int status; 143 | if (!stream.avail_in) 144 | { 145 | // Input buffer is empty, so read more bytes from input file. 146 | uint n = my_min(BUF_SIZE, infile_remaining); 147 | 148 | if (fread(s_inbuf, 1, n, pInfile) != n) 149 | { 150 | printf("Failed reading from input file!\n"); 151 | return EXIT_FAILURE; 152 | } 153 | 154 | stream.next_in = s_inbuf; 155 | stream.avail_in = n; 156 | 157 | infile_remaining -= n; 158 | //printf("Input bytes remaining: %u\n", infile_remaining); 159 | } 160 | 161 | status = deflate(&stream, infile_remaining ? Z_NO_FLUSH : Z_FINISH); 162 | 163 | if ((status == Z_STREAM_END) || (!stream.avail_out)) 164 | { 165 | // Output buffer is full, or compression is done, so write buffer to output file. 166 | uint n = BUF_SIZE - stream.avail_out; 167 | if (fwrite(s_outbuf, 1, n, pOutfile) != n) 168 | { 169 | printf("Failed writing to output file!\n"); 170 | return EXIT_FAILURE; 171 | } 172 | stream.next_out = s_outbuf; 173 | stream.avail_out = BUF_SIZE; 174 | } 175 | 176 | if (status == Z_STREAM_END) 177 | break; 178 | else if (status != Z_OK) 179 | { 180 | printf("deflate() failed with status %i!\n", status); 181 | return EXIT_FAILURE; 182 | } 183 | } 184 | 185 | if (deflateEnd(&stream) != Z_OK) 186 | { 187 | printf("deflateEnd() failed!\n"); 188 | return EXIT_FAILURE; 189 | } 190 | } 191 | else if ((pMode[0] == 'd') || (pMode[0] == 'D')) 192 | { 193 | // Decompression. 194 | uint infile_remaining = infile_size; 195 | 196 | if (inflateInit2(&stream, WINDOW_BITS)) 197 | { 198 | printf("inflateInit() failed!\n"); 199 | return EXIT_FAILURE; 200 | } 201 | 202 | for ( ; ; ) 203 | { 204 | int status; 205 | if (!stream.avail_in) 206 | { 207 | // Input buffer is empty, so read more bytes from input file. 208 | uint n = my_min(BUF_SIZE, infile_remaining); 209 | 210 | if (fread(s_inbuf, 1, n, pInfile) != n) 211 | { 212 | printf("Failed reading from input file!\n"); 213 | return EXIT_FAILURE; 214 | } 215 | 216 | stream.next_in = s_inbuf; 217 | stream.avail_in = n; 218 | 219 | infile_remaining -= n; 220 | } 221 | 222 | status = inflate(&stream, Z_SYNC_FLUSH); 223 | 224 | if ((status == Z_STREAM_END) || (!stream.avail_out)) 225 | { 226 | // Output buffer is full, or decompression is done, so write buffer to output file. 227 | uint n = BUF_SIZE - stream.avail_out; 228 | if (fwrite(s_outbuf, 1, n, pOutfile) != n) 229 | { 230 | printf("Failed writing to output file!\n"); 231 | return EXIT_FAILURE; 232 | } 233 | stream.next_out = s_outbuf; 234 | stream.avail_out = BUF_SIZE; 235 | } 236 | 237 | if (status == Z_STREAM_END) 238 | break; 239 | else if (status != Z_OK) 240 | { 241 | printf("inflate() failed with status %i!\n", status); 242 | return EXIT_FAILURE; 243 | } 244 | } 245 | 246 | if (inflateEnd(&stream) != Z_OK) 247 | { 248 | printf("inflateEnd() failed!\n"); 249 | return EXIT_FAILURE; 250 | } 251 | } 252 | else 253 | { 254 | printf("Invalid mode!\n"); 255 | return EXIT_FAILURE; 256 | } 257 | 258 | fclose(pInfile); 259 | if (EOF == fclose(pOutfile)) 260 | { 261 | printf("Failed writing to output file!\n"); 262 | return EXIT_FAILURE; 263 | } 264 | 265 | printf("Total input bytes: %u\n", stream.total_in); 266 | printf("Total output bytes: %u\n", stream.total_out); 267 | printf("Success.\n"); 268 | return EXIT_SUCCESS; 269 | } 270 | -------------------------------------------------------------------------------- /example2/example2.c: -------------------------------------------------------------------------------- 1 | // example2.c - Demonstrates single function call compression/decompression using the lzham_compress() and lzham_uncompress() functions. 2 | // This example statically links against the lzhamlib, lzhamcomp, and lzhamdecomp libs. 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | // Define LZHAM_DEFINE_ZLIB_API causes lzham.h to remap the standard zlib.h functions/macro definitions to lzham's. 9 | // This is totally optional - you can also directly use the lzham_* functions and macros instead. 10 | #define LZHAM_DEFINE_ZLIB_API 11 | #include "lzham_static_lib.h" 12 | 13 | typedef unsigned char uint8; 14 | typedef unsigned short uint16; 15 | typedef unsigned int uint; 16 | 17 | // The string to compress. 18 | static const char *s_pStr = "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ 19 | "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ 20 | "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ 21 | "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ 22 | "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ 23 | "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ 24 | "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ 25 | "Hal... Dave and I believe that there's something about the mission that we weren't told." \ 26 | "Something that the rest of the crew know and that you know. We'd like to know whether this is true."; 27 | 28 | int main(int argc, char *argv[]) 29 | { 30 | uint step = 0; 31 | int cmp_status; 32 | uLong src_len = (uLong)strlen(s_pStr); 33 | uLong cmp_len = compressBound(src_len); 34 | uLong uncomp_len = src_len; 35 | uint8 *pCmp, *pUncomp; 36 | uint total_succeeded = 0; 37 | argc, argv; 38 | 39 | printf("LZHAM example2 (single function call compression/decompression)\nUsing library version: %s\n", ZLIB_VERSION); 40 | 41 | do 42 | { 43 | // Allocate buffers to hold compressed and uncompressed data. 44 | pCmp = (uint8 *)malloc((size_t)cmp_len); 45 | pUncomp = (uint8 *)malloc((size_t)src_len); 46 | if ((!pCmp) || (!pUncomp)) 47 | { 48 | printf("Out of memory!\n"); 49 | return EXIT_FAILURE; 50 | } 51 | 52 | // Compress the string. 53 | cmp_status = compress(pCmp, &cmp_len, (const unsigned char *)s_pStr, src_len); 54 | if (cmp_status != Z_OK) 55 | { 56 | printf("compress() failed!\n"); 57 | free(pCmp); 58 | free(pUncomp); 59 | return EXIT_FAILURE; 60 | } 61 | 62 | printf("Compressed from %u to %u bytes\n", src_len, cmp_len); 63 | 64 | if (step) 65 | { 66 | // Purposely corrupt the compressed data if fuzzy testing (this is a very crude fuzzy test). 67 | uint n = 1 + (rand() % 3); 68 | while (n--) 69 | { 70 | uint i = rand() % cmp_len; 71 | pCmp[i] ^= (rand() & 0xFF); 72 | } 73 | } 74 | 75 | // Decompress. 76 | cmp_status = uncompress(pUncomp, &uncomp_len, pCmp, cmp_len); 77 | total_succeeded += (cmp_status == Z_OK); 78 | 79 | if (step) 80 | { 81 | printf("Simple fuzzy test: step %u total_succeeded: %u\n", step, total_succeeded); 82 | } 83 | else 84 | { 85 | if (cmp_status != Z_OK) 86 | { 87 | printf("uncompress failed!\n"); 88 | free(pCmp); 89 | free(pUncomp); 90 | return EXIT_FAILURE; 91 | } 92 | 93 | printf("Decompressed from %u to %u bytes\n", cmp_len, uncomp_len); 94 | 95 | // Ensure uncompress() returned the expected data. 96 | if ((uncomp_len != src_len) || (memcmp(pUncomp, s_pStr, (size_t)src_len))) 97 | { 98 | printf("Decompression failed!\n"); 99 | free(pCmp); 100 | free(pUncomp); 101 | return EXIT_FAILURE; 102 | } 103 | } 104 | 105 | free(pCmp); 106 | free(pUncomp); 107 | 108 | step++; 109 | 110 | // Keep on fuzzy testing if there's a non-empty command line. 111 | } while (argc >= 2); 112 | 113 | printf("Success.\n"); 114 | return EXIT_SUCCESS; 115 | } 116 | -------------------------------------------------------------------------------- /example3/example3.cpp: -------------------------------------------------------------------------------- 1 | // example3.cpp - Tests streaming and random access packet compression using the compressor's LZHAM_Z_FULL_FLUSH flush mode, and the 2 | // decompressor's LZHAM_Z_SYNC_FLUSH flush mode. 3 | // This example statically links against lzhamlib, lzhamcomp, and lzhamdecomp libs. 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | // Define LZHAM_DEFINE_ZLIB_API causes lzham.h to remap the zlib.h functions/macro definitions to lzham's. 11 | // This is totally optional - you can also directly use the lzham_* functions and macros instead. 12 | #define LZHAM_DEFINE_ZLIB_API 13 | #include "lzham_static_lib.h" 14 | 15 | typedef unsigned char uint8; 16 | typedef unsigned short uint16; 17 | typedef unsigned int uint; 18 | 19 | #define my_max(a,b) (((a) > (b)) ? (a) : (b)) 20 | #define my_min(a,b) (((a) < (b)) ? (a) : (b)) 21 | 22 | #define BUF_SIZE (1024 * 1024) 23 | static uint8 s_inbuf[BUF_SIZE]; 24 | static uint8 s_outbuf[BUF_SIZE]; 25 | 26 | #define WINDOW_BITS 20 27 | 28 | // Tests 29 | static bool sequential_test() 30 | { 31 | printf("Sequential record/packet decompression test:\n"); 32 | 33 | z_stream stream; 34 | memset(&stream, 0, sizeof(stream)); 35 | stream.next_in = s_inbuf; 36 | stream.avail_in = 0; 37 | stream.next_out = s_outbuf; 38 | stream.avail_out = BUF_SIZE; 39 | 40 | if (deflateInit2(&stream, Z_BEST_COMPRESSION, LZHAM_Z_LZHAM, WINDOW_BITS, 9, Z_DEFAULT_STRATEGY) != Z_OK) 41 | return false; 42 | 43 | std::vector comp_buf; 44 | const uint cRecordSize = 128; 45 | 46 | for (uint i = 0; i < 1000; i++) 47 | { 48 | memset(s_inbuf, 0, 128); 49 | sprintf((char*)s_inbuf, "%u, %u, %u, %u, This is a testThis is a testThis is a testThis is a testThis is a test\n", i, i, i, i); 50 | 51 | stream.next_in = s_inbuf; 52 | stream.avail_in = cRecordSize; 53 | 54 | while (stream.avail_in) 55 | { 56 | stream.next_out = s_outbuf; 57 | stream.avail_out = BUF_SIZE; 58 | 59 | if (deflate(&stream, Z_FULL_FLUSH) != Z_OK) 60 | { 61 | deflateEnd(&stream); 62 | return false; 63 | } 64 | 65 | comp_buf.insert(comp_buf.end(), s_outbuf, s_outbuf + (BUF_SIZE - stream.avail_out)); 66 | } 67 | 68 | printf("Compressing record %u and flushing compressor, %u bytes\n", i, stream.total_out); 69 | } 70 | 71 | stream.avail_in = 0; 72 | for ( ; ; ) 73 | { 74 | stream.next_out = s_outbuf; 75 | stream.avail_out = BUF_SIZE; 76 | int status = deflate(&stream, Z_FINISH); 77 | 78 | comp_buf.insert(comp_buf.end(), s_outbuf, s_outbuf + (BUF_SIZE - stream.avail_out)); 79 | 80 | if (status == Z_STREAM_END) 81 | break; 82 | else if (status != Z_OK) 83 | { 84 | deflateEnd(&stream); 85 | return false; 86 | } 87 | } 88 | 89 | deflateEnd(&stream); 90 | 91 | memset(&stream, 0, sizeof(stream)); 92 | stream.next_in = &comp_buf[0]; 93 | stream.avail_in = (uint)comp_buf.size(); 94 | stream.next_out = s_outbuf; 95 | stream.avail_out = BUF_SIZE; 96 | 97 | if (inflateInit2(&stream, WINDOW_BITS) != Z_OK) 98 | return false; 99 | 100 | for (uint i = 0; i < 1000; i++) 101 | { 102 | stream.next_out = s_outbuf; 103 | stream.avail_out = cRecordSize; 104 | 105 | int status = inflate(&stream, Z_SYNC_FLUSH); 106 | if (status == Z_STREAM_END) 107 | break; 108 | if (status != Z_OK) 109 | { 110 | inflateEnd(&stream); 111 | return false; 112 | } 113 | 114 | memset(s_inbuf, 0, 128); 115 | sprintf((char*)s_inbuf, "%u, %u, %u, %u, This is a testThis is a testThis is a testThis is a testThis is a test\n", i, i, i, i); 116 | if (memcmp(s_inbuf, s_outbuf, cRecordSize) != 0) 117 | return false; 118 | 119 | printf("Successfully decompressed record %u\n", i); 120 | } 121 | 122 | inflateEnd(&stream); 123 | 124 | return true; 125 | } 126 | 127 | static bool random_test() 128 | { 129 | printf("Random record/packet decompression test:\n"); 130 | 131 | z_stream stream; 132 | memset(&stream, 0, sizeof(stream)); 133 | stream.next_in = s_inbuf; 134 | stream.avail_in = 0; 135 | stream.next_out = s_outbuf; 136 | stream.avail_out = BUF_SIZE; 137 | 138 | if (deflateInit2(&stream, Z_BEST_COMPRESSION, LZHAM_Z_LZHAM, WINDOW_BITS, 9, Z_DEFAULT_STRATEGY) != Z_OK) 139 | return false; 140 | 141 | const uint cTotalRecords = 200; 142 | std::vector< std::vector > comp_bufs(cTotalRecords); 143 | 144 | const uint cRecordSize = 128; 145 | 146 | for (uint i = 0; i < cTotalRecords; i++) 147 | { 148 | memset(s_inbuf, 0, 128); 149 | sprintf((char*)s_inbuf, "%u, %u, %u, %u, This is a testThis is a testThis is a testThis is a testThis is a test\n", i, i, i, i); 150 | 151 | stream.next_in = s_inbuf; 152 | stream.avail_in = cRecordSize; 153 | 154 | while (stream.avail_in) 155 | { 156 | stream.next_out = s_outbuf; 157 | stream.avail_out = BUF_SIZE; 158 | 159 | if (deflate(&stream, Z_FULL_FLUSH) != Z_OK) 160 | { 161 | deflateEnd(&stream); 162 | return false; 163 | } 164 | 165 | comp_bufs[i].insert(comp_bufs[i].end(), s_outbuf, s_outbuf + (BUF_SIZE - stream.avail_out)); 166 | } 167 | 168 | printf("Compressing record %u and flushing compressor, %u bytes\n", i, stream.total_out); 169 | } 170 | 171 | deflateEnd(&stream); 172 | 173 | memset(&stream, 0, sizeof(stream)); 174 | stream.next_in = &(comp_bufs[0])[0]; 175 | stream.avail_in = (uint)comp_bufs[0].size(); 176 | stream.next_out = s_outbuf; 177 | stream.avail_out = BUF_SIZE; 178 | 179 | if (inflateInit2(&stream, WINDOW_BITS) != Z_OK) 180 | return false; 181 | 182 | for (uint i = 0; i < cTotalRecords * 2; i++) 183 | { 184 | uint rec_index = 0; 185 | if (i) 186 | rec_index = (rand() % (cTotalRecords - 1)) + 1; 187 | 188 | stream.next_in = &(comp_bufs[rec_index])[0]; 189 | stream.avail_in = (uint)comp_bufs[rec_index].size(); 190 | stream.next_out = s_outbuf; 191 | stream.avail_out = cRecordSize; 192 | 193 | int status = inflate(&stream, Z_SYNC_FLUSH); 194 | if (status == Z_STREAM_END) 195 | break; 196 | if (status != Z_OK) 197 | { 198 | inflateEnd(&stream); 199 | return false; 200 | } 201 | 202 | memset(s_inbuf, 0, 128); 203 | sprintf((char*)s_inbuf, "%u, %u, %u, %u, This is a testThis is a testThis is a testThis is a testThis is a test\n", rec_index, rec_index, rec_index, rec_index); 204 | if (memcmp(s_inbuf, s_outbuf, cRecordSize) != 0) 205 | return false; 206 | 207 | printf("Successfully decompressed random record %u\n", rec_index); 208 | } 209 | 210 | inflateEnd(&stream); 211 | 212 | return true; 213 | } 214 | 215 | int main(int argc, char *argv[]) 216 | { 217 | argc, argv; 218 | printf("LZHAM example3 (single function call compression/decompression with flushing)\nUsing library version: %s\n", ZLIB_VERSION); 219 | 220 | if (!sequential_test()) 221 | { 222 | printf("Sequential test failed!\n"); 223 | return EXIT_FAILURE; 224 | } 225 | 226 | if (!random_test()) 227 | { 228 | printf("Random test failed!\n"); 229 | return EXIT_FAILURE; 230 | } 231 | 232 | printf("Test succeeded.\n"); 233 | return EXIT_SUCCESS; 234 | } 235 | -------------------------------------------------------------------------------- /example4/cfile_stream.cpp: -------------------------------------------------------------------------------- 1 | // File: cfile_stream.cpp 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #include "cfile_stream.h" 4 | 5 | namespace lzham_ex 6 | { 7 | cfile_stream::cfile_stream() : 8 | data_stream(), m_pFile(NULL), m_size(0), m_ofs(0), m_has_ownership(false) 9 | { 10 | } 11 | 12 | cfile_stream::cfile_stream(FILE* pFile, const char* pFilename, uint attribs, bool has_ownership) : 13 | data_stream(), m_pFile(NULL), m_size(0), m_ofs(0), m_has_ownership(false) 14 | { 15 | open(pFile, pFilename, attribs, has_ownership); 16 | } 17 | 18 | cfile_stream::cfile_stream(const char* pFilename, uint attribs, bool open_existing) : 19 | data_stream(), m_pFile(NULL), m_size(0), m_ofs(0), m_has_ownership(false) 20 | { 21 | open(pFilename, attribs, open_existing); 22 | } 23 | 24 | cfile_stream::~cfile_stream() 25 | { 26 | close(); 27 | } 28 | 29 | bool cfile_stream::close() 30 | { 31 | clear_error(); 32 | 33 | if (m_opened) 34 | { 35 | bool status = true; 36 | if (m_has_ownership) 37 | { 38 | if (EOF == fclose(m_pFile)) 39 | status = false; 40 | } 41 | 42 | m_pFile = NULL; 43 | m_opened = false; 44 | m_size = 0; 45 | m_ofs = 0; 46 | m_has_ownership = false; 47 | 48 | return status; 49 | } 50 | 51 | return false; 52 | } 53 | 54 | bool cfile_stream::open(FILE* pFile, const char* pFilename, uint attribs, bool has_ownership) 55 | { 56 | assert(pFile); 57 | assert(pFilename); 58 | 59 | close(); 60 | 61 | set_name(pFilename); 62 | m_pFile = pFile; 63 | m_has_ownership = has_ownership; 64 | m_attribs = static_cast(attribs); 65 | 66 | m_ofs = _ftelli64(m_pFile); 67 | _fseeki64(m_pFile, 0, SEEK_END); 68 | m_size = _ftelli64(m_pFile); 69 | _fseeki64(m_pFile, m_ofs, SEEK_SET); 70 | 71 | m_opened = true; 72 | 73 | return true; 74 | } 75 | 76 | bool cfile_stream::open(const char* pFilename, uint attribs, bool open_existing) 77 | { 78 | assert(pFilename); 79 | 80 | close(); 81 | 82 | m_attribs = static_cast(attribs); 83 | 84 | const char* pMode; 85 | if ((is_readable()) && (is_writable())) 86 | pMode = open_existing ? "r+b" : "w+b"; 87 | else if (is_writable()) 88 | pMode = open_existing ? "ab" : "wb"; 89 | else if (is_readable()) 90 | pMode = "rb"; 91 | else 92 | { 93 | set_error(); 94 | return false; 95 | } 96 | 97 | FILE* pFile = NULL; 98 | #ifdef _MSC_VER 99 | fopen_s(&pFile, pFilename, pMode); 100 | #else 101 | pFile = fopen(pFilename, pMode); 102 | #endif 103 | m_has_ownership = true; 104 | 105 | if (!pFile) 106 | { 107 | set_error(); 108 | return false; 109 | } 110 | 111 | return open(pFile, pFilename, attribs, true); 112 | } 113 | 114 | uint cfile_stream::read(void* pBuf, uint len) 115 | { 116 | assert(pBuf && (len <= 0x7FFFFFFF)); 117 | 118 | if (!m_opened || (!is_readable()) || (!len)) 119 | return 0; 120 | 121 | len = static_cast(LZHAM_EX_MIN(len, get_remaining())); 122 | 123 | if (fread(pBuf, 1, len, m_pFile) != len) 124 | { 125 | set_error(); 126 | return 0; 127 | } 128 | 129 | m_ofs += len; 130 | return len; 131 | } 132 | 133 | uint cfile_stream::write(const void* pBuf, uint len) 134 | { 135 | assert(pBuf && (len <= 0x7FFFFFFF)); 136 | 137 | if (!m_opened || (!is_writable()) || (!len)) 138 | return 0; 139 | 140 | size_t n = fwrite(pBuf, 1, len, m_pFile); 141 | 142 | m_ofs += n; 143 | m_size = LZHAM_EX_MAX(m_size, m_ofs); 144 | 145 | if (n != len) 146 | set_error(); 147 | 148 | return static_cast(n); 149 | } 150 | 151 | bool cfile_stream::flush() 152 | { 153 | if ((!m_opened) || (!is_writable())) 154 | return false; 155 | 156 | if (EOF == fflush(m_pFile)) 157 | { 158 | set_error(); 159 | return false; 160 | } 161 | 162 | return true; 163 | } 164 | 165 | uint64 cfile_stream::get_size() 166 | { 167 | if (!m_opened) 168 | return 0; 169 | 170 | return m_size; 171 | } 172 | 173 | uint64 cfile_stream::get_remaining() 174 | { 175 | if (!m_opened) 176 | return 0; 177 | 178 | assert(m_ofs <= m_size); 179 | return m_size - m_ofs; 180 | } 181 | 182 | uint64 cfile_stream::get_ofs() 183 | { 184 | if (!m_opened) 185 | return 0; 186 | 187 | return m_ofs; 188 | } 189 | 190 | bool cfile_stream::seek(int64 ofs, bool relative) 191 | { 192 | if ((!m_opened) || (!is_seekable())) 193 | return false; 194 | 195 | int64 new_ofs = relative ? (m_ofs + ofs) : ofs; 196 | if (new_ofs < 0) 197 | return false; 198 | else if (static_cast(new_ofs) > m_size) 199 | return false; 200 | 201 | if (static_cast(new_ofs) != m_ofs) 202 | { 203 | if (_fseeki64(m_pFile, new_ofs, SEEK_SET) != 0) 204 | { 205 | set_error(); 206 | return false; 207 | } 208 | 209 | m_ofs = new_ofs; 210 | } 211 | 212 | return true; 213 | } 214 | 215 | bool cfile_stream::read_file_into_array(const char* pFilename, std::vector& buf) 216 | { 217 | cfile_stream in_stream(pFilename); 218 | if (!in_stream.is_opened()) 219 | return false; 220 | return in_stream.read_array(buf); 221 | } 222 | 223 | bool cfile_stream::write_array_to_file(const char* pFilename, const std::vector& buf) 224 | { 225 | cfile_stream out_stream(pFilename, cDataStreamWritable|cDataStreamSeekable); 226 | if (!out_stream.is_opened()) 227 | return false; 228 | return out_stream.write_array(buf); 229 | } 230 | 231 | } // namespace lzham_ex 232 | -------------------------------------------------------------------------------- /example4/cfile_stream.h: -------------------------------------------------------------------------------- 1 | // File: cfile_stream.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | #include "data_stream.h" 5 | #include 6 | 7 | namespace lzham_ex 8 | { 9 | // stdio.h FILE stream. Supports 64-bit offsets/file sizes. 10 | class cfile_stream : public data_stream 11 | { 12 | public: 13 | cfile_stream(); 14 | cfile_stream(FILE* pFile, const char* pFilename, uint attribs, bool has_ownership); 15 | cfile_stream(const char* pFilename, uint attribs = cDataStreamReadable | cDataStreamSeekable, bool open_existing = false); 16 | 17 | virtual ~cfile_stream(); 18 | 19 | virtual bool close(); 20 | 21 | bool open(FILE* pFile, const char* pFilename, uint attribs, bool has_ownership); 22 | bool open(const char* pFilename, uint attribs = cDataStreamReadable | cDataStreamSeekable, bool open_existing = false); 23 | 24 | inline FILE* get_file() const { return m_pFile; } 25 | 26 | virtual uint read(void* pBuf, uint len); 27 | virtual uint write(const void* pBuf, uint len); 28 | virtual bool flush(); 29 | 30 | virtual uint64 get_size(); 31 | virtual uint64 get_remaining(); 32 | virtual uint64 get_ofs(); 33 | 34 | virtual bool seek(int64 ofs, bool relative); 35 | 36 | static bool read_file_into_array(const char* pFilename, std::vector& buf); 37 | static bool write_array_to_file(const char* pFilename, const std::vector& buf); 38 | 39 | private: 40 | FILE* m_pFile; 41 | uint64 m_size, m_ofs; 42 | bool m_has_ownership; 43 | }; 44 | 45 | } // namespace lzham_ex 46 | -------------------------------------------------------------------------------- /example4/comp_stream.h: -------------------------------------------------------------------------------- 1 | // File: comp_stream.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #include "data_stream.h" 4 | 5 | #include "lzham.h" 6 | 7 | namespace lzham_ex 8 | { 9 | template 10 | class packed_value 11 | { 12 | public: 13 | packed_value() { } 14 | packed_value(T val) { *this = val; } 15 | 16 | inline operator T() const 17 | { 18 | T result = 0; 19 | for (int i = sizeof(T) - 1; i >= 0; i--) 20 | result = static_cast((result << 8) | m_bytes[i]); 21 | return result; 22 | } 23 | 24 | packed_value& operator= (T val) 25 | { 26 | for (int i = 0; i < sizeof(T); i++) 27 | { 28 | m_bytes[i] = static_cast(val); 29 | val >>= 8; 30 | } 31 | return *this; 32 | } 33 | 34 | private: 35 | uint8 m_bytes[sizeof(T)]; 36 | }; 37 | 38 | #pragma pack(push) 39 | #pragma pack(1) 40 | struct compressed_stream_header 41 | { 42 | enum { cSig = 0x41485a4c }; 43 | packed_value m_sig; 44 | 45 | packed_value m_uncomp_size; 46 | packed_value m_comp_size; 47 | 48 | enum 49 | { 50 | cCompMethodLZHAM = 0, 51 | }; 52 | packed_value m_method; 53 | packed_value m_window_size; 54 | 55 | packed_value m_header_crc; 56 | 57 | void clear() { memset(this, 0, sizeof(*this)); } 58 | void compute_crc() { m_sig = (uint32)cSig; m_header_crc = lzham_z_crc32(LZHAM_Z_CRC32_INIT, (uint8*)this, sizeof(*this) - sizeof(uint32)); } 59 | bool validate() const { return (m_sig == (uint32)cSig) && (m_header_crc == lzham_z_crc32(LZHAM_Z_CRC32_INIT, (uint8*)this, sizeof(*this) - sizeof(uint32))); } 60 | }; 61 | #pragma pack(pop) 62 | 63 | class compression_stream : public data_stream 64 | { 65 | public: 66 | compression_stream(); 67 | compression_stream(data_stream *pOutput_stream, const lzham_compress_params *pComp_params = NULL, const char* pName = "compression_stream", uint window_size = 19, lzham_compress_level level = LZHAM_COMP_LEVEL_DEFAULT, bool multithreading = false, uint64 source_stream_size = DATA_STREAM_SIZE_UNKNOWN); 68 | virtual ~compression_stream(); 69 | 70 | virtual data_stream *get_output_stream() { return m_pOutput_stream; } 71 | 72 | virtual bool open(data_stream *pOutput_stream, const lzham_compress_params *pComp_params = NULL, const char* pName = "compression_stream", uint window_size = 19, lzham_compress_level level = LZHAM_COMP_LEVEL_DEFAULT, bool multithreading = false, uint64 source_stream_size = DATA_STREAM_SIZE_UNKNOWN); 73 | virtual bool close(); 74 | 75 | virtual uint read(void* pBuf, uint len); 76 | virtual uint write(const void* pBuf, uint len); 77 | virtual bool flush(); 78 | 79 | virtual uint64 get_size(); 80 | virtual uint64 get_remaining(); 81 | virtual uint64 get_ofs(); 82 | 83 | virtual bool seek(int64 ofs, bool relative); 84 | 85 | private: 86 | data_stream *m_pOutput_stream; 87 | 88 | lzham_compress_state_ptr m_pComp_state; 89 | 90 | uint64 m_total_uncomp_size; 91 | uint64 m_total_comp_size; 92 | 93 | uint64 m_total_promised_uncomp_size; 94 | 95 | uint64 m_header_stream_ofs; 96 | 97 | enum { cBufSize = 65535 }; 98 | std::vector m_buf; 99 | 100 | compressed_stream_header m_hdr; 101 | 102 | bool m_opened; 103 | 104 | void clear(); 105 | bool flush_output_buf(uint out_buf_size); 106 | }; 107 | 108 | class decompression_stream : public data_stream 109 | { 110 | public: 111 | decompression_stream(); 112 | decompression_stream(data_stream *pInput_stream, const char* pName = "decompression_stream"); 113 | virtual ~decompression_stream(); 114 | 115 | virtual data_stream *get_input_stream() { return m_pInput_stream; } 116 | 117 | virtual bool open(data_stream *pInput_stream, const char* pName = "decompression_stream"); 118 | virtual bool close(); 119 | 120 | virtual uint read(void* pBuf, uint len); 121 | virtual uint write(const void* pBuf, uint len); 122 | virtual bool flush(); 123 | 124 | virtual uint64 get_size(); 125 | virtual uint64 get_remaining(); 126 | virtual uint64 get_ofs(); 127 | 128 | virtual bool seek(int64 ofs, bool relative); 129 | 130 | private: 131 | data_stream *m_pInput_stream; 132 | 133 | compressed_stream_header m_hdr; 134 | 135 | lzham_decompress_state_ptr m_pDecomp_state; 136 | 137 | std::vector m_buf; 138 | uint m_buf_ofs; 139 | 140 | uint m_chunk_size; 141 | bool m_no_more_input_bytes; 142 | 143 | uint64 m_total_bytes_read; 144 | uint64 m_total_bytes_unpacked; 145 | 146 | lzham_decompress_status_t m_decomp_status; 147 | 148 | bool m_decomp_completed; 149 | bool m_comp_size_known; 150 | bool m_opened; 151 | 152 | void clear(); 153 | bool refill_input_buffer(); 154 | bool term_stream(); 155 | }; 156 | 157 | } // namespace lzham_ex 158 | -------------------------------------------------------------------------------- /example4/data_stream.cpp: -------------------------------------------------------------------------------- 1 | // File: data_stream.cpp 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #include "data_stream.h" 4 | #include 5 | 6 | namespace lzham_ex 7 | { 8 | data_stream::data_stream() : 9 | m_attribs(0), 10 | m_opened(false), m_error(false), m_got_cr(false) 11 | { 12 | } 13 | 14 | data_stream::data_stream(const char* pName, uint attribs) : 15 | m_name(pName), 16 | m_attribs(static_cast(attribs)), 17 | m_opened(false), m_error(false), m_got_cr(false) 18 | { 19 | } 20 | 21 | uint64 data_stream::skip(uint64 len) 22 | { 23 | uint64 total_bytes_read = 0; 24 | 25 | const uint cBufSize = 1024; 26 | uint8 buf[cBufSize]; 27 | 28 | while (len) 29 | { 30 | const uint64 bytes_to_read = LZHAM_EX_MIN(sizeof(buf), len); 31 | const uint64 bytes_read = read(buf, static_cast(bytes_to_read)); 32 | total_bytes_read += bytes_read; 33 | 34 | if (bytes_read != bytes_to_read) 35 | break; 36 | 37 | len -= bytes_read; 38 | } 39 | 40 | return total_bytes_read; 41 | } 42 | 43 | bool data_stream::read_line(std::string& str) 44 | { 45 | str.resize(0); 46 | 47 | for ( ; ; ) 48 | { 49 | const int c = read_byte(); 50 | 51 | const bool prev_got_cr = m_got_cr; 52 | m_got_cr = false; 53 | 54 | if (c < 0) 55 | { 56 | if (!str.empty()) 57 | break; 58 | 59 | return false; 60 | } 61 | else if ((26 == c) || (!c)) 62 | continue; 63 | else if (13 == c) 64 | { 65 | m_got_cr = true; 66 | break; 67 | } 68 | else if (10 == c) 69 | { 70 | if (prev_got_cr) 71 | continue; 72 | 73 | break; 74 | } 75 | 76 | str.append(1, static_cast(c)); 77 | } 78 | 79 | return true; 80 | } 81 | 82 | bool data_stream::printf(const char* p, ...) 83 | { 84 | va_list args; 85 | 86 | va_start(args, p); 87 | char buf[4096]; 88 | #ifdef _MSC_VER 89 | int l = vsprintf_s(buf, sizeof(buf), p, args); 90 | #else 91 | int l = vsprintf(buf, p, args); 92 | #endif 93 | va_end(args); 94 | if (l < 0) 95 | return false; 96 | return write(buf, l) == static_cast(l); 97 | } 98 | 99 | bool data_stream::write_line(const std::string& str) 100 | { 101 | if (!str.empty()) 102 | return write(str.c_str(), static_cast(str.length())) == str.length(); 103 | 104 | return true; 105 | } 106 | 107 | bool data_stream::read_array(std::vector& buf) 108 | { 109 | if (get_remaining() > 1024U*1024U*1024U) 110 | return false; 111 | 112 | uint32 bytes_to_read = static_cast(get_remaining()); 113 | if (!bytes_to_read) 114 | { 115 | buf.resize(0); 116 | return true; 117 | } 118 | 119 | if (buf.size() < bytes_to_read) 120 | buf.resize(bytes_to_read); 121 | 122 | return read(&buf[0], bytes_to_read) == bytes_to_read; 123 | } 124 | 125 | bool data_stream::write_array(const std::vector& buf) 126 | { 127 | size_t cur_ofs = 0; 128 | 129 | while (cur_ofs < buf.size()) 130 | { 131 | size_t num_remaining = buf.size() - cur_ofs; 132 | uint32 n = static_cast(LZHAM_EX_MIN(256U*1024U*1024U, num_remaining)); 133 | 134 | if (write(&buf[cur_ofs], n) != n) 135 | return false; 136 | 137 | cur_ofs += n; 138 | } 139 | 140 | return true; 141 | } 142 | 143 | } // namespace lzham_ex 144 | -------------------------------------------------------------------------------- /example4/data_stream.h: -------------------------------------------------------------------------------- 1 | // File: data_stream.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | #include "stream_common.h" 5 | 6 | namespace lzham_ex 7 | { 8 | enum data_stream_attribs 9 | { 10 | cDataStreamReadable = 1, 11 | cDataStreamWritable = 2, 12 | cDataStreamSeekable = 4 13 | }; 14 | 15 | const int64 DATA_STREAM_SIZE_UNKNOWN = cINT64_MAX; 16 | const int64 DATA_STREAM_SIZE_INFINITE = cUINT64_MAX; 17 | 18 | class data_stream 19 | { 20 | data_stream(const data_stream&); 21 | data_stream& operator= (const data_stream&); 22 | 23 | public: 24 | data_stream(); 25 | data_stream(const char* pName, uint attribs); 26 | 27 | virtual ~data_stream() { } 28 | 29 | virtual data_stream *get_parent() { return NULL; } 30 | 31 | virtual bool close() { m_opened = false; m_error = false; m_got_cr = false; return true; } 32 | 33 | typedef uint16 attribs_t; 34 | inline attribs_t get_attribs() const { return m_attribs; } 35 | 36 | inline bool is_opened() const { return m_opened; } 37 | 38 | inline bool is_readable() const { return (m_attribs & cDataStreamReadable) != 0; } 39 | inline bool is_writable() const { return (m_attribs & cDataStreamWritable) != 0; } 40 | inline bool is_seekable() const { return (m_attribs & cDataStreamSeekable) != 0; } 41 | 42 | inline bool get_error() const { return m_error; } 43 | inline void set_error() { m_error = true; } 44 | inline void clear_error() { m_error = false; } 45 | 46 | inline const std::string& get_name() const { return m_name; } 47 | inline void set_name(const char* pName) { m_name = pName; } 48 | 49 | virtual uint read(void* pBuf, uint len) = 0; 50 | virtual uint64 skip(uint64 len); 51 | 52 | virtual uint write(const void* pBuf, uint len) = 0; 53 | virtual bool flush() = 0; 54 | 55 | virtual bool is_size_known() const { return true; } 56 | 57 | // get_size() and get_remaining() return DATA_STREAM_SIZE_UNKNOWN if size hasn't been determined yet. 58 | // For infinite streams, DATA_STREAM_SIZE_INFINITE is returned. 59 | virtual uint64 get_size() = 0; 60 | virtual uint64 get_remaining() = 0; 61 | 62 | virtual uint64 get_ofs() = 0; 63 | virtual bool seek(int64 ofs, bool relative) = 0; 64 | 65 | virtual const void* get_ptr() const { return NULL; } 66 | 67 | inline int read_byte() { uint8 c; if (read(&c, 1) != 1) return -1; return c; } 68 | inline bool write_byte(uint8 c) { return write(&c, 1) == 1; } 69 | 70 | bool read_line(std::string& str); 71 | bool write_line(const std::string& str); 72 | 73 | bool printf(const char* p, ...); 74 | 75 | // Reads remaining stream into byte array. Max size is 1GB. 76 | bool read_array(std::vector& buf); 77 | 78 | // Writes entire byte array to stream. 79 | bool write_array(const std::vector& buf); 80 | 81 | protected: 82 | std::string m_name; 83 | 84 | attribs_t m_attribs; 85 | bool m_opened : 1; 86 | bool m_error : 1; 87 | bool m_got_cr : 1; 88 | 89 | inline void post_seek() { m_got_cr = false; } 90 | }; 91 | 92 | } // namespace lzham_ex 93 | 94 | -------------------------------------------------------------------------------- /example4/dynamic_stream.cpp: -------------------------------------------------------------------------------- 1 | // File: dynamic_stream.cpp 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #include "dynamic_stream.h" 4 | 5 | namespace lzham_ex 6 | { 7 | dynamic_stream::dynamic_stream(uint64 initial_size, const char* pName, uint attribs) : 8 | data_stream(pName, attribs), 9 | m_ofs(0) 10 | { 11 | open(initial_size, pName, attribs); 12 | } 13 | 14 | dynamic_stream::dynamic_stream(const void* pBuf, uint64 size, const char* pName, uint attribs) : 15 | data_stream(pName, attribs), 16 | m_ofs(0) 17 | { 18 | open(pBuf, size, pName, attribs); 19 | } 20 | 21 | dynamic_stream::dynamic_stream() : 22 | data_stream(), 23 | m_ofs(0) 24 | { 25 | open(); 26 | } 27 | 28 | dynamic_stream::~dynamic_stream() 29 | { 30 | } 31 | 32 | bool dynamic_stream::open(uint64 initial_size, const char* pName, uint attribs) 33 | { 34 | if (initial_size > static_cast(-1)) 35 | return false; 36 | 37 | close(); 38 | 39 | m_opened = true; 40 | m_buf.clear(); 41 | m_buf.resize(static_cast(initial_size)); 42 | m_ofs = 0; 43 | m_name = pName ? pName : "dynamic_stream"; 44 | m_attribs = static_cast(attribs); 45 | return true; 46 | } 47 | 48 | bool dynamic_stream::reopen(const char* pName, uint attribs) 49 | { 50 | if (!m_opened) 51 | { 52 | return open(0, pName, attribs); 53 | } 54 | 55 | m_name = pName ? pName : "dynamic_stream"; 56 | m_attribs = static_cast(attribs); 57 | return true; 58 | } 59 | 60 | bool dynamic_stream::open(const void* pBuf, uint64 size, const char* pName, uint attribs) 61 | { 62 | if (!m_opened) 63 | { 64 | if (size > static_cast(-1)) 65 | return false; 66 | 67 | m_opened = true; 68 | m_buf.resize(static_cast(size)); 69 | if (size) 70 | memcpy(&m_buf[0], pBuf, static_cast(size)); 71 | m_ofs = 0; 72 | m_name = pName ? pName : "dynamic_stream"; 73 | m_attribs = static_cast(attribs); 74 | return true; 75 | } 76 | 77 | return false; 78 | } 79 | 80 | bool dynamic_stream::close() 81 | { 82 | if (m_opened) 83 | { 84 | m_opened = false; 85 | m_buf.clear(); 86 | m_ofs = 0; 87 | return true; 88 | } 89 | 90 | return false; 91 | } 92 | 93 | bool dynamic_stream::reserve(uint64 size) 94 | { 95 | if (m_opened) 96 | { 97 | if (size > static_cast(-1)) 98 | return false; 99 | m_buf.reserve(static_cast(size)); 100 | } 101 | return true; 102 | } 103 | 104 | uint dynamic_stream::read(void* pBuf, uint len) 105 | { 106 | if ((!m_opened) || (!is_readable()) || (!len)) 107 | return 0; 108 | 109 | assert(m_ofs <= m_buf.size()); 110 | 111 | uint64 bytes_left = m_buf.size() - m_ofs; 112 | 113 | len = static_cast(LZHAM_EX_MIN(len, bytes_left)); 114 | 115 | if (len) 116 | { 117 | memcpy(pBuf, &m_buf[static_cast(m_ofs)], len); 118 | 119 | m_ofs += len; 120 | } 121 | 122 | return len; 123 | } 124 | 125 | uint dynamic_stream::write(const void* pBuf, uint len) 126 | { 127 | if ((!m_opened) || (!is_writable()) || (!len)) 128 | return 0; 129 | 130 | assert(m_ofs <= m_buf.size()); 131 | 132 | uint64 new_ofs = m_ofs + len; 133 | if (new_ofs > m_buf.size()) 134 | { 135 | if (new_ofs > static_cast(-1)) 136 | return false; 137 | m_buf.resize(static_cast(new_ofs)); 138 | } 139 | 140 | memcpy(&m_buf[static_cast(m_ofs)], pBuf, len); 141 | m_ofs = new_ofs; 142 | 143 | return len; 144 | } 145 | 146 | bool dynamic_stream::flush() 147 | { 148 | if (!m_opened) 149 | return false; 150 | 151 | return true; 152 | } 153 | 154 | uint64 dynamic_stream::get_size() 155 | { 156 | if (!m_opened) 157 | return 0; 158 | 159 | return m_buf.size(); 160 | } 161 | 162 | uint64 dynamic_stream::get_remaining() 163 | { 164 | if (!m_opened) 165 | return 0; 166 | 167 | assert(m_ofs <= m_buf.size()); 168 | 169 | return m_buf.size() - m_ofs; 170 | } 171 | 172 | uint64 dynamic_stream::get_ofs() 173 | { 174 | if (!m_opened) 175 | return 0; 176 | 177 | return m_ofs; 178 | } 179 | 180 | bool dynamic_stream::seek(int64 ofs, bool relative) 181 | { 182 | if ((!m_opened) || (!is_seekable())) 183 | return false; 184 | 185 | int64 new_ofs = relative ? (m_ofs + ofs) : ofs; 186 | 187 | if (new_ofs < 0) 188 | return false; 189 | else if (new_ofs > static_cast(m_buf.size())) 190 | return false; 191 | 192 | m_ofs = static_cast(new_ofs); 193 | 194 | post_seek(); 195 | 196 | return true; 197 | } 198 | 199 | } // namespace lzham_ex 200 | -------------------------------------------------------------------------------- /example4/dynamic_stream.h: -------------------------------------------------------------------------------- 1 | // File: dynamic_stream.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | #include "data_stream.h" 5 | 6 | namespace lzham_ex 7 | { 8 | // A fully growable stream, internally uses std::vector to store written data. 9 | class dynamic_stream : public data_stream 10 | { 11 | public: 12 | dynamic_stream(uint64 initial_size, const char* pName = "dynamic_stream", uint attribs = cDataStreamSeekable | cDataStreamWritable | cDataStreamReadable); 13 | dynamic_stream(const void* pBuf, uint64 size, const char* pName = "dynamic_stream", uint attribs = cDataStreamSeekable | cDataStreamWritable | cDataStreamReadable); 14 | dynamic_stream(); 15 | 16 | virtual ~dynamic_stream(); 17 | 18 | bool open(uint64 initial_size = 0, const char* pName = "dynamic_stream", uint attribs = cDataStreamSeekable | cDataStreamWritable | cDataStreamReadable); 19 | bool reopen(const char* pName, uint attribs); 20 | bool open(const void* pBuf, uint64 size, const char* pName = "dynamic_stream", uint attribs = cDataStreamSeekable | cDataStreamWritable | cDataStreamReadable); 21 | 22 | virtual bool close(); 23 | 24 | inline const std::vector& get_buf() const { return m_buf; } 25 | inline std::vector& get_buf() { return m_buf; } 26 | 27 | bool reserve(uint64 size); 28 | 29 | virtual const void* get_ptr() const { return m_buf.empty() ? NULL : &m_buf[0]; } 30 | 31 | virtual uint read(void* pBuf, uint len); 32 | 33 | virtual uint write(const void* pBuf, uint len); 34 | 35 | virtual bool flush(); 36 | 37 | virtual uint64 get_size(); 38 | virtual uint64 get_remaining(); 39 | virtual uint64 get_ofs(); 40 | 41 | virtual bool seek(int64 ofs, bool relative); 42 | 43 | private: 44 | std::vector m_buf; 45 | uint64 m_ofs; 46 | }; 47 | 48 | } // namespace lzham_ex 49 | 50 | -------------------------------------------------------------------------------- /example4/example4.cpp: -------------------------------------------------------------------------------- 1 | // example4.cpp - Simple example of the various example stream and serialization classes in the "lzham_ex" namespace. 2 | // This example statically links against the lzhamlib, lzhamcomp, and lzhamdecomp libs. 3 | // 4 | // Note: The C++ classes in the "lzham_ex" namespace are totally optional and not part of the core LZHAM codec itself. They're mainly here to serve as more 5 | // complex examples of how to use the library. I debated whether to include them at all, given their complexity, but they make decent examples of how to 6 | // create a easy to use stream/serialization library with built-in support for compression. 7 | // 8 | // Short description of each header: 9 | // data_stream.h - Defines the data_stream abstract base class. A data_stream is like a file: it's a sequential stream of bytes that can be read/written from/to the current file position. 10 | // data_stream's can be read-only, write-only, readable+writable, and seekable/non-seekable, and have a finite, infinite, or unknown length. 11 | // dynamic_stream.h - A growable data stream. Internally, it used a std::vector to store the stream's data. 12 | // mem_stream.h - A non-growable data stream aliased over a user-provided memory buffer. 13 | // cfile_stream.h - A data stream read and/or written to a file. Internally used the C stdio API's fopen(), fread(), etc. 14 | // comp_stream.h - compression_stream is a write-only non-seekable stream that automatically compresses all data passed to it. decompression_stream is its read-only, non-seekable counterpart. 15 | // compression_stream writes the compressed data to the specified output data_stream. It supports non-seekable output streams. 16 | // decompression_stream reads the compressed data from the specified input data_stream. It supports non-seekable input streams. 17 | // All compressed data streams begin with a endian-neutral header (see compressed_stream_header struct). 18 | // data_stream_serializer.h - A simple serialization/deserialization helper class. Supports big and little endian data. 19 | #include "data_stream.h" 20 | #include "dynamic_stream.h" 21 | #include "mem_stream.h" 22 | #include "comp_stream.h" 23 | #include "cfile_stream.h" 24 | #include "data_stream_serializer.h" 25 | 26 | #include "lzham_static_lib.h" 27 | 28 | int main(int argc, char *argv[]) 29 | { 30 | argc, argv; 31 | printf("LZHAM example4 (example stream/serialization classes)\nUsing library version: 0x%04X\n", LZHAM_DLL_VERSION); 32 | 33 | // Create a write-only growable data buffer to hold the compressed data. 34 | lzham_ex::dynamic_stream compressed_data_buf(0, "compressed_data", lzham_ex::cDataStreamWritable); 35 | 36 | // Create and open a compression stream, have its output written to the growable data buffer. 37 | lzham_ex::compression_stream compression_stream; 38 | if (!compression_stream.open(&compressed_data_buf)) 39 | { 40 | printf("Failed opening compression stream!\n"); 41 | return EXIT_FAILURE; 42 | } 43 | 44 | // printf some stuff into the compression stream. 45 | for (int i = 0; i < 500; i++) 46 | compression_stream.printf("This is a test %u\n", i); 47 | 48 | // Create a serializer chained to the compression stream, and output some things to it. 49 | lzham_ex::data_stream_serializer serializer(&compression_stream); 50 | serializer << 9999 << "This is a test"; 51 | 52 | printf("Uncompressed size: %i\n", static_cast(compression_stream.get_ofs())); 53 | 54 | // Close the compression stream. 55 | if (!compression_stream.close()) 56 | { 57 | printf("Failed closing compression stream!\n"); 58 | return EXIT_FAILURE; 59 | } 60 | 61 | printf("Compressed size: %i\n", static_cast(compressed_data_buf.get_ofs())); 62 | 63 | // Now reopen the growable data buffer as readable/seekable (this is optional/only for testing - it could have been open with all permissions above). 64 | compressed_data_buf.reopen("dynamic_string", lzham_ex::cDataStreamSeekable | lzham_ex::cDataStreamReadable); 65 | // Set the data buffer's pointer to the beginning of the stream. 66 | compressed_data_buf.seek(0, false); 67 | 68 | // Create a decompression stream which gets its input from the growable data buffer used to hold the compressed data. 69 | lzham_ex::decompression_stream decompression_stream; 70 | if (!decompression_stream.open(&compressed_data_buf)) 71 | { 72 | printf("Failed opening decompression stream!\n"); 73 | return EXIT_FAILURE; 74 | } 75 | 76 | // Read the lines from the decompression stream. 77 | for (int i = 0; i < 500; i++) 78 | { 79 | std::string str; 80 | if (!decompression_stream.read_line(str)) 81 | { 82 | printf("Failed reading from decompression stream!\n"); 83 | return EXIT_FAILURE; 84 | } 85 | printf("%s\n", str.c_str()); 86 | } 87 | 88 | // Create another serializer that reads from the decompression stream, and deserialize some things. 89 | lzham_ex::data_stream_serializer deserializer(&decompression_stream); 90 | int i; 91 | std::string s; 92 | deserializer >> i >> s; 93 | printf("%i %s\n", i, s.c_str()); 94 | 95 | // Close the decompression stream. 96 | if (!decompression_stream.close()) 97 | { 98 | printf("Failed closing decompression stream!\n"); 99 | return EXIT_FAILURE; 100 | } 101 | 102 | printf("Test succeeded.\n"); 103 | return EXIT_SUCCESS; 104 | } 105 | -------------------------------------------------------------------------------- /example4/mem_stream.cpp: -------------------------------------------------------------------------------- 1 | // File: mem_stream.cpp 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #include "mem_stream.h" 4 | 5 | namespace lzham_ex 6 | { 7 | mem_stream::mem_stream() : 8 | data_stream(), 9 | m_pBuf(NULL), 10 | m_size(0), 11 | m_ofs(0) 12 | { 13 | } 14 | 15 | mem_stream::mem_stream(void* p, uint64 size) : 16 | data_stream(), 17 | m_pBuf(NULL), 18 | m_size(0), 19 | m_ofs(0) 20 | { 21 | open(p, size); 22 | } 23 | 24 | mem_stream::mem_stream(const void* p, uint64 size) : 25 | data_stream(), 26 | m_pBuf(NULL), 27 | m_size(0), 28 | m_ofs(0) 29 | { 30 | open(p, size); 31 | } 32 | 33 | mem_stream::~mem_stream() 34 | { 35 | } 36 | 37 | bool mem_stream::open(const void* p, uint64 size) 38 | { 39 | assert(p); 40 | 41 | close(); 42 | 43 | if ((!p) || (!size)) 44 | return false; 45 | 46 | m_opened = true; 47 | m_pBuf = (uint8*)(p); 48 | m_size = size; 49 | m_ofs = 0; 50 | m_attribs = cDataStreamSeekable | cDataStreamReadable; 51 | return true; 52 | } 53 | 54 | bool mem_stream::open(void* p, uint64 size) 55 | { 56 | assert(p); 57 | 58 | close(); 59 | 60 | if ((!p) || (!size)) 61 | return false; 62 | 63 | m_opened = true; 64 | m_pBuf = static_cast(p); 65 | m_size = size; 66 | m_ofs = 0; 67 | m_attribs = cDataStreamSeekable | cDataStreamWritable | cDataStreamReadable; 68 | return true; 69 | } 70 | 71 | bool mem_stream::close() 72 | { 73 | if (m_opened) 74 | { 75 | m_opened = false; 76 | m_pBuf = NULL; 77 | m_size = 0; 78 | m_ofs = 0; 79 | return true; 80 | } 81 | 82 | return false; 83 | } 84 | 85 | uint mem_stream::read(void* pBuf, uint len) 86 | { 87 | if ((!m_opened) || (!is_readable()) || (!len)) 88 | return 0; 89 | 90 | assert(m_ofs <= m_size); 91 | 92 | uint64 bytes_left = m_size - m_ofs; 93 | 94 | len = (uint)LZHAM_EX_MIN(len, bytes_left); 95 | 96 | if (len) 97 | { 98 | memcpy(pBuf, &m_pBuf[m_ofs], len); 99 | 100 | m_ofs += len; 101 | } 102 | 103 | return len; 104 | } 105 | 106 | uint mem_stream::write(const void* pBuf, uint len) 107 | { 108 | if ((!m_opened) || (!is_writable()) || (!len)) 109 | return 0; 110 | 111 | assert(m_ofs <= m_size); 112 | 113 | uint64 bytes_left = m_size - m_ofs; 114 | 115 | len = (uint)LZHAM_EX_MIN(len, bytes_left); 116 | 117 | if (len) 118 | { 119 | memcpy(&m_pBuf[m_ofs], pBuf, len); 120 | 121 | m_ofs += len; 122 | } 123 | 124 | return len; 125 | } 126 | 127 | bool mem_stream::flush() 128 | { 129 | if (!m_opened) 130 | return false; 131 | 132 | return true; 133 | } 134 | 135 | uint64 mem_stream::get_size() 136 | { 137 | if (!m_opened) 138 | return 0; 139 | 140 | return m_size; 141 | } 142 | 143 | uint64 mem_stream::get_remaining() 144 | { 145 | if (!m_opened) 146 | return 0; 147 | 148 | assert(m_ofs <= m_size); 149 | 150 | return m_size - m_ofs; 151 | } 152 | 153 | uint64 mem_stream::get_ofs() 154 | { 155 | if (!m_opened) 156 | return 0; 157 | 158 | return m_ofs; 159 | } 160 | 161 | bool mem_stream::seek(int64 ofs, bool relative) 162 | { 163 | if ((!m_opened) || (!is_seekable())) 164 | return false; 165 | 166 | int64 new_ofs = relative ? (m_ofs + ofs) : ofs; 167 | 168 | if (new_ofs < 0) 169 | return false; 170 | else if (new_ofs > (int64)m_size) 171 | return false; 172 | 173 | m_ofs = (uint64)new_ofs; 174 | 175 | post_seek(); 176 | 177 | return true; 178 | } 179 | 180 | } // namespace lzham_ex 181 | 182 | -------------------------------------------------------------------------------- /example4/mem_stream.h: -------------------------------------------------------------------------------- 1 | // File: mem_stream.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | #include "data_stream.h" 5 | 6 | namespace lzham_ex 7 | { 8 | // Provides a read/write stream view of a static, user provided memory buffer. 9 | class mem_stream : public data_stream 10 | { 11 | public: 12 | mem_stream(); 13 | mem_stream(void* p, uint64 size); 14 | mem_stream(const void* p, uint64 size); 15 | 16 | virtual ~mem_stream(); 17 | 18 | bool open(const void* p, uint64 size); 19 | bool open(void* p, uint64 size); 20 | 21 | virtual bool close(); 22 | 23 | inline const void* get_buf() const { return m_pBuf; } 24 | inline void* get_buf() { return m_pBuf; } 25 | 26 | virtual const void* get_ptr() const { return m_pBuf; } 27 | 28 | virtual uint read(void* pBuf, uint len); 29 | virtual uint write(const void* pBuf, uint len); 30 | 31 | virtual bool flush(); 32 | 33 | virtual uint64 get_size(); 34 | virtual uint64 get_remaining(); 35 | virtual uint64 get_ofs(); 36 | 37 | virtual bool seek(int64 ofs, bool relative); 38 | 39 | private: 40 | uint8* m_pBuf; 41 | uint64 m_size; 42 | uint64 m_ofs; 43 | }; 44 | 45 | } // namespace lzham_ex 46 | 47 | -------------------------------------------------------------------------------- /example4/stream_common.h: -------------------------------------------------------------------------------- 1 | // File: stream_common.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define LZHAM_EX_MAX(a,b) (((a) > (b)) ? (a) : (b)) 15 | #define LZHAM_EX_MIN(a,b) (((a) < (b)) ? (a) : (b)) 16 | 17 | #if __BIG_ENDIAN__ 18 | #define LZHAM_EX_LITTLE_ENDIAN_CPU 0 19 | #else 20 | #define LZHAM_EX_LITTLE_ENDIAN_CPU 1 21 | #endif 22 | 23 | namespace lzham_ex 24 | { 25 | typedef signed char int8; 26 | typedef unsigned char uint8; 27 | typedef signed short int16; 28 | typedef unsigned short uint16; 29 | typedef unsigned int uint; 30 | typedef signed int int32; 31 | typedef unsigned int uint32; 32 | typedef signed __int64 int64; 33 | typedef unsigned __int64 uint64; 34 | 35 | const uint16 cUINT16_MIN = 0; 36 | const uint16 cUINT16_MAX = 0xFFFFU; 37 | const uint64 cUINT64_MIN = 0; 38 | const uint64 cUINT64_MAX = 0xFFFFFFFFFFFFFFFFULL; //0xFFFFFFFFFFFFFFFFui64; 39 | const int64 cINT64_MIN = (int64)0x8000000000000000ULL; //(-9223372036854775807i64 - 1); 40 | const int64 cINT64_MAX = (int64)0x7FFFFFFFFFFFFFFFULL; //9223372036854775807i64; 41 | 42 | template inline void zero_object(T& obj) { memset(&obj, 0, sizeof(obj)); } 43 | } // namespace lzham_ex 44 | -------------------------------------------------------------------------------- /include/lzham_dynamic_lib.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define LZHAM_DYNAMIC_LIB 1 4 | #include "lzham.h" 5 | 6 | #ifdef _XBOX 7 | #define LZHAM_DLL_FILENAME "lzham_x360.dll" 8 | #define LZHAM_DEBUG_DLL_FILENAME "lzham_x360D.dll" 9 | #else 10 | // FIXME: This stuff should probably be moved to another header. 11 | #if LZHAM_64BIT 12 | #define LZHAM_DLL_FILENAME "lzham_x64.dll" 13 | #define LZHAM_DEBUG_DLL_FILENAME "lzham_x64D.dll" 14 | #else 15 | #define LZHAM_DLL_FILENAME "lzham_x86.dll" 16 | #define LZHAM_DEBUG_DLL_FILENAME "lzham_x86D.dll" 17 | #endif 18 | #endif 19 | 20 | #ifdef __cplusplus 21 | // Simple helper class that demonstrates how to dynamically load the LZHAM DLL. 22 | // The load() method loads the DLL, then initializes the member function pointers in ilzham by calling GetProcAddress() on all exported API's defined in lzham_exports.inc. 23 | class lzham_dll_loader : public ilzham 24 | { 25 | lzham_dll_loader(const lzham_dll_loader &other); 26 | lzham_dll_loader& operator= (const lzham_dll_loader &rhs); 27 | 28 | public: 29 | lzham_dll_loader() : ilzham(), m_handle(NULL), m_win32_error(S_OK) 30 | { 31 | } 32 | 33 | virtual ~lzham_dll_loader() 34 | { 35 | unload(); 36 | } 37 | 38 | enum 39 | { 40 | cErrorMissingExport = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x201), 41 | cErrorUnsupportedDLLVersion = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x202), 42 | }; 43 | 44 | // Assumes LZHAM DLL is in the same path as the executable. 45 | #if defined(_XBOX) || defined(_MSC_VER) 46 | static void create_module_path(char *pModulePath, int size_in_chars, bool debug_dll) 47 | { 48 | #ifdef _XBOX 49 | char *buf = "D:\\unused.xex"; 50 | #else 51 | char buf[MAX_PATH]; 52 | GetModuleFileNameA(NULL, buf, sizeof(buf)); 53 | #endif 54 | char drive_buf[_MAX_DRIVE], dir_buf[_MAX_DIR], filename_buf[_MAX_FNAME], ext_buf[_MAX_EXT]; 55 | _splitpath_s(buf, drive_buf, _MAX_DRIVE, dir_buf, _MAX_DIR, NULL, 0, NULL, 0); 56 | _splitpath_s(debug_dll ? LZHAM_DEBUG_DLL_FILENAME : LZHAM_DLL_FILENAME, NULL, 0, NULL, 0, filename_buf, _MAX_FNAME, ext_buf, _MAX_EXT); 57 | _makepath_s(pModulePath, size_in_chars, drive_buf, dir_buf, filename_buf, ext_buf); 58 | } 59 | #else 60 | static void create_module_path(char *pModulePath, int size_in_chars, bool debug_dll) 61 | { 62 | strcpy(pModulePath, debug_dll ? LZHAM_DEBUG_DLL_FILENAME : LZHAM_DLL_FILENAME); 63 | } 64 | #endif 65 | 66 | virtual bool load() 67 | { 68 | HRESULT hres = load(NULL); 69 | return S_OK == hres; 70 | } 71 | 72 | HRESULT load(const char* pModulePath) 73 | { 74 | unload(); 75 | 76 | char buf[MAX_PATH]; 77 | if (!pModulePath) 78 | { 79 | create_module_path(buf, sizeof(buf), false); 80 | pModulePath = buf; 81 | } 82 | 83 | m_win32_error = S_OK; 84 | 85 | m_handle = LoadLibraryA(pModulePath); 86 | if (NULL == m_handle) 87 | { 88 | m_win32_error = HRESULT_FROM_WIN32(GetLastError()); 89 | return m_win32_error; 90 | } 91 | 92 | struct 93 | { 94 | const char* pName; 95 | void** pFunc_ptr; 96 | } 97 | funcs[] = 98 | { 99 | #define LZHAM_DLL_FUNC_NAME(x) { #x, (void**)&x }, 100 | #include "lzham_exports.inc" 101 | #undef LZHAM_DLL_FUNC_NAME 102 | }; 103 | 104 | const int cNumFuncs = sizeof(funcs) / sizeof(funcs[0]); 105 | 106 | for (int i = 0; i < cNumFuncs; i++) 107 | { 108 | #ifdef _XBOX 109 | if ((*funcs[i].pFunc_ptr = GetProcAddress(m_handle, (LPCSTR)(i + 1))) == NULL) 110 | #else 111 | if ((*funcs[i].pFunc_ptr = (void*)GetProcAddress(m_handle, funcs[i].pName)) == NULL) 112 | #endif 113 | { 114 | unload(); 115 | 116 | m_win32_error = cErrorMissingExport; 117 | return m_win32_error; 118 | } 119 | } 120 | 121 | int dll_ver = lzham_get_version(); 122 | 123 | // Ensure DLL's major version is the expected version. 124 | if ((dll_ver >> 8U) != (LZHAM_DLL_VERSION >> 8U)) 125 | { 126 | unload(); 127 | 128 | m_win32_error = cErrorUnsupportedDLLVersion; 129 | return m_win32_error; 130 | } 131 | 132 | return S_OK; 133 | } 134 | 135 | virtual void unload() 136 | { 137 | if (m_handle) 138 | { 139 | FreeLibrary(m_handle); 140 | m_handle = NULL; 141 | } 142 | 143 | clear(); 144 | 145 | m_win32_error = S_OK; 146 | } 147 | 148 | virtual bool is_loaded() { return m_handle != NULL; } 149 | 150 | HRESULT get_last_win32_error() { return m_win32_error; } 151 | 152 | private: 153 | HMODULE m_handle; 154 | HRESULT m_win32_error; 155 | }; 156 | #endif // #ifdef __cplusplus 157 | -------------------------------------------------------------------------------- /include/lzham_exports.inc: -------------------------------------------------------------------------------- 1 | // Note: The order here must match the ordinal declarations in lzhamdll.def! 2 | LZHAM_DLL_FUNC_NAME(lzham_get_version) 3 | LZHAM_DLL_FUNC_NAME(lzham_set_memory_callbacks) 4 | LZHAM_DLL_FUNC_NAME(lzham_compress_init) 5 | LZHAM_DLL_FUNC_NAME(lzham_compress_reinit) 6 | LZHAM_DLL_FUNC_NAME(lzham_compress) 7 | LZHAM_DLL_FUNC_NAME(lzham_compress2) 8 | LZHAM_DLL_FUNC_NAME(lzham_compress_deinit) 9 | LZHAM_DLL_FUNC_NAME(lzham_compress_memory) 10 | LZHAM_DLL_FUNC_NAME(lzham_decompress_init) 11 | LZHAM_DLL_FUNC_NAME(lzham_decompress) 12 | LZHAM_DLL_FUNC_NAME(lzham_decompress_deinit) 13 | LZHAM_DLL_FUNC_NAME(lzham_decompress_memory) 14 | LZHAM_DLL_FUNC_NAME(lzham_decompress_reinit) 15 | LZHAM_DLL_FUNC_NAME(lzham_z_version) 16 | LZHAM_DLL_FUNC_NAME(lzham_z_deflateInit) 17 | LZHAM_DLL_FUNC_NAME(lzham_z_deflateInit2) 18 | LZHAM_DLL_FUNC_NAME(lzham_z_deflateReset) 19 | LZHAM_DLL_FUNC_NAME(lzham_z_deflate) 20 | LZHAM_DLL_FUNC_NAME(lzham_z_deflateEnd) 21 | LZHAM_DLL_FUNC_NAME(lzham_z_deflateBound) 22 | LZHAM_DLL_FUNC_NAME(lzham_z_compress) 23 | LZHAM_DLL_FUNC_NAME(lzham_z_compress2) 24 | LZHAM_DLL_FUNC_NAME(lzham_z_compressBound) 25 | LZHAM_DLL_FUNC_NAME(lzham_z_inflateInit) 26 | LZHAM_DLL_FUNC_NAME(lzham_z_inflateInit2) 27 | LZHAM_DLL_FUNC_NAME(lzham_z_inflateReset) 28 | LZHAM_DLL_FUNC_NAME(lzham_z_inflate) 29 | LZHAM_DLL_FUNC_NAME(lzham_z_inflateEnd) 30 | LZHAM_DLL_FUNC_NAME(lzham_z_uncompress) 31 | LZHAM_DLL_FUNC_NAME(lzham_z_error) 32 | -------------------------------------------------------------------------------- /include/lzham_static_lib.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define LZHAM_STATIC_LIB 1 4 | #include "lzham.h" 5 | 6 | #ifdef __cplusplus 7 | // Like lzham_dynamic_lib, except it sets the function pointer members to point directly to the C functions in lzhamlib 8 | class lzham_static_lib : public ilzham 9 | { 10 | lzham_static_lib(const lzham_static_lib &other); 11 | lzham_static_lib& operator= (const lzham_static_lib &rhs); 12 | 13 | public: 14 | lzham_static_lib() : ilzham() { } 15 | 16 | virtual ~lzham_static_lib() { } 17 | 18 | virtual bool load() 19 | { 20 | this->lzham_get_version = ::lzham_get_version; 21 | this->lzham_set_memory_callbacks = ::lzham_set_memory_callbacks; 22 | this->lzham_compress_init = ::lzham_compress_init; 23 | this->lzham_compress_deinit = ::lzham_compress_deinit; 24 | this->lzham_compress = ::lzham_compress; 25 | this->lzham_compress2 = ::lzham_compress2; 26 | this->lzham_compress_reinit = ::lzham_compress_reinit; 27 | this->lzham_compress_memory = ::lzham_compress_memory; 28 | this->lzham_decompress_init = ::lzham_decompress_init; 29 | this->lzham_decompress_reinit = ::lzham_decompress_reinit; 30 | this->lzham_decompress_deinit = ::lzham_decompress_deinit; 31 | this->lzham_decompress = ::lzham_decompress; 32 | this->lzham_decompress_memory = ::lzham_decompress_memory; 33 | 34 | this->lzham_z_version = ::lzham_z_version; 35 | this->lzham_z_deflateInit = ::lzham_z_deflateInit; 36 | this->lzham_z_deflateInit2 = ::lzham_z_deflateInit2; 37 | this->lzham_z_deflateReset = ::lzham_z_deflateReset; 38 | this->lzham_z_deflate = ::lzham_z_deflate; 39 | this->lzham_z_deflateEnd = ::lzham_z_deflateEnd; 40 | this->lzham_z_deflateBound = ::lzham_z_deflateBound; 41 | this->lzham_z_compress = ::lzham_z_compress; 42 | this->lzham_z_compress2 = ::lzham_z_compress2; 43 | this->lzham_z_compressBound = ::lzham_z_compressBound; 44 | this->lzham_z_inflateInit = ::lzham_z_inflateInit; 45 | this->lzham_z_inflateInit2 = ::lzham_z_inflateInit2; 46 | this->lzham_z_inflate = ::lzham_z_inflate; 47 | this->lzham_z_inflateEnd = ::lzham_z_inflateEnd; 48 | this->lzham_z_inflateReset = ::lzham_z_inflateReset; 49 | this->lzham_z_uncompress = ::lzham_z_uncompress; 50 | this->lzham_z_error = ::lzham_z_error; 51 | 52 | return true; 53 | } 54 | 55 | virtual void unload() { clear(); } 56 | 57 | virtual bool is_loaded() { return lzham_get_version != NULL; } 58 | }; 59 | #endif // __cplusplus 60 | -------------------------------------------------------------------------------- /include/zlib.h: -------------------------------------------------------------------------------- 1 | #define LZHAM_DEFINE_ZLIB_API 2 | #include "lzham.h" -------------------------------------------------------------------------------- /lzham.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lzhamdll", "lzhamdll\lzham.vcxproj", "{763BE79D-1280-41B7-81C5-7DC41E2BDB44}" 5 | EndProject 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lzhamtest", "lzhamtest\lzhamtest.vcxproj", "{BBE16587-150E-460C-8AB4-F18B92D0B981}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lzhamdecomp", "lzhamdecomp\lzhamdecomp.vcxproj", "{8DA0CD32-701D-48D7-AE92-728338501500}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lzhamcomp", "lzhamcomp\lzhamcomp.vcxproj", "{8DA0CD46-791D-48D7-AE92-728338501500}" 11 | EndProject 12 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example1", "example1\example1.vcxproj", "{BBE16587-150E-460C-8AB4-E18B92D0B982}" 13 | EndProject 14 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lzhamlib", "lzhamlib\lzhamlib.vcxproj", "{83A2F0B5-1D02-4A13-B579-714F60E31774}" 15 | EndProject 16 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example2", "example2\example2.vcxproj", "{CBE16587-150E-460C-8AB4-E18B92D0B983}" 17 | EndProject 18 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example3", "example3\example3.vcxproj", "{1BE16587-150E-460C-8AB4-E18B92D0BA87}" 19 | EndProject 20 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example4", "example4\example4.vcxproj", "{1BE16587-260E-460C-8AB4-E18B92D0BA87}" 21 | EndProject 22 | Global 23 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 24 | Debug|Win32 = Debug|Win32 25 | Debug|x64 = Debug|x64 26 | Release|Win32 = Release|Win32 27 | Release|x64 = Release|x64 28 | EndGlobalSection 29 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 30 | {763BE79D-1280-41B7-81C5-7DC41E2BDB44}.Debug|Win32.ActiveCfg = Debug|Win32 31 | {763BE79D-1280-41B7-81C5-7DC41E2BDB44}.Debug|Win32.Build.0 = Debug|Win32 32 | {763BE79D-1280-41B7-81C5-7DC41E2BDB44}.Debug|x64.ActiveCfg = Debug|x64 33 | {763BE79D-1280-41B7-81C5-7DC41E2BDB44}.Debug|x64.Build.0 = Debug|x64 34 | {763BE79D-1280-41B7-81C5-7DC41E2BDB44}.Release|Win32.ActiveCfg = Release|Win32 35 | {763BE79D-1280-41B7-81C5-7DC41E2BDB44}.Release|Win32.Build.0 = Release|Win32 36 | {763BE79D-1280-41B7-81C5-7DC41E2BDB44}.Release|x64.ActiveCfg = Release|x64 37 | {763BE79D-1280-41B7-81C5-7DC41E2BDB44}.Release|x64.Build.0 = Release|x64 38 | {BBE16587-150E-460C-8AB4-F18B92D0B981}.Debug|Win32.ActiveCfg = Debug|Win32 39 | {BBE16587-150E-460C-8AB4-F18B92D0B981}.Debug|Win32.Build.0 = Debug|Win32 40 | {BBE16587-150E-460C-8AB4-F18B92D0B981}.Debug|x64.ActiveCfg = Debug|x64 41 | {BBE16587-150E-460C-8AB4-F18B92D0B981}.Debug|x64.Build.0 = Debug|x64 42 | {BBE16587-150E-460C-8AB4-F18B92D0B981}.Release|Win32.ActiveCfg = Release|Win32 43 | {BBE16587-150E-460C-8AB4-F18B92D0B981}.Release|Win32.Build.0 = Release|Win32 44 | {BBE16587-150E-460C-8AB4-F18B92D0B981}.Release|x64.ActiveCfg = Release|x64 45 | {BBE16587-150E-460C-8AB4-F18B92D0B981}.Release|x64.Build.0 = Release|x64 46 | {8DA0CD32-701D-48D7-AE92-728338501500}.Debug|Win32.ActiveCfg = Debug|Win32 47 | {8DA0CD32-701D-48D7-AE92-728338501500}.Debug|Win32.Build.0 = Debug|Win32 48 | {8DA0CD32-701D-48D7-AE92-728338501500}.Debug|x64.ActiveCfg = Debug|x64 49 | {8DA0CD32-701D-48D7-AE92-728338501500}.Debug|x64.Build.0 = Debug|x64 50 | {8DA0CD32-701D-48D7-AE92-728338501500}.Release|Win32.ActiveCfg = Release|Win32 51 | {8DA0CD32-701D-48D7-AE92-728338501500}.Release|Win32.Build.0 = Release|Win32 52 | {8DA0CD32-701D-48D7-AE92-728338501500}.Release|x64.ActiveCfg = Release|x64 53 | {8DA0CD32-701D-48D7-AE92-728338501500}.Release|x64.Build.0 = Release|x64 54 | {8DA0CD46-791D-48D7-AE92-728338501500}.Debug|Win32.ActiveCfg = Debug|Win32 55 | {8DA0CD46-791D-48D7-AE92-728338501500}.Debug|Win32.Build.0 = Debug|Win32 56 | {8DA0CD46-791D-48D7-AE92-728338501500}.Debug|x64.ActiveCfg = Debug|x64 57 | {8DA0CD46-791D-48D7-AE92-728338501500}.Debug|x64.Build.0 = Debug|x64 58 | {8DA0CD46-791D-48D7-AE92-728338501500}.Release|Win32.ActiveCfg = Release|Win32 59 | {8DA0CD46-791D-48D7-AE92-728338501500}.Release|Win32.Build.0 = Release|Win32 60 | {8DA0CD46-791D-48D7-AE92-728338501500}.Release|x64.ActiveCfg = Release|x64 61 | {8DA0CD46-791D-48D7-AE92-728338501500}.Release|x64.Build.0 = Release|x64 62 | {BBE16587-150E-460C-8AB4-E18B92D0B982}.Debug|Win32.ActiveCfg = Debug|Win32 63 | {BBE16587-150E-460C-8AB4-E18B92D0B982}.Debug|Win32.Build.0 = Debug|Win32 64 | {BBE16587-150E-460C-8AB4-E18B92D0B982}.Debug|x64.ActiveCfg = Debug|x64 65 | {BBE16587-150E-460C-8AB4-E18B92D0B982}.Debug|x64.Build.0 = Debug|x64 66 | {BBE16587-150E-460C-8AB4-E18B92D0B982}.Release|Win32.ActiveCfg = Release|Win32 67 | {BBE16587-150E-460C-8AB4-E18B92D0B982}.Release|Win32.Build.0 = Release|Win32 68 | {BBE16587-150E-460C-8AB4-E18B92D0B982}.Release|x64.ActiveCfg = Release|x64 69 | {BBE16587-150E-460C-8AB4-E18B92D0B982}.Release|x64.Build.0 = Release|x64 70 | {83A2F0B5-1D02-4A13-B579-714F60E31774}.Debug|Win32.ActiveCfg = Debug|Win32 71 | {83A2F0B5-1D02-4A13-B579-714F60E31774}.Debug|Win32.Build.0 = Debug|Win32 72 | {83A2F0B5-1D02-4A13-B579-714F60E31774}.Debug|x64.ActiveCfg = Debug|x64 73 | {83A2F0B5-1D02-4A13-B579-714F60E31774}.Debug|x64.Build.0 = Debug|x64 74 | {83A2F0B5-1D02-4A13-B579-714F60E31774}.Release|Win32.ActiveCfg = Release|Win32 75 | {83A2F0B5-1D02-4A13-B579-714F60E31774}.Release|Win32.Build.0 = Release|Win32 76 | {83A2F0B5-1D02-4A13-B579-714F60E31774}.Release|x64.ActiveCfg = Release|x64 77 | {83A2F0B5-1D02-4A13-B579-714F60E31774}.Release|x64.Build.0 = Release|x64 78 | {CBE16587-150E-460C-8AB4-E18B92D0B983}.Debug|Win32.ActiveCfg = Debug|Win32 79 | {CBE16587-150E-460C-8AB4-E18B92D0B983}.Debug|Win32.Build.0 = Debug|Win32 80 | {CBE16587-150E-460C-8AB4-E18B92D0B983}.Debug|x64.ActiveCfg = Debug|x64 81 | {CBE16587-150E-460C-8AB4-E18B92D0B983}.Debug|x64.Build.0 = Debug|x64 82 | {CBE16587-150E-460C-8AB4-E18B92D0B983}.Release|Win32.ActiveCfg = Release|Win32 83 | {CBE16587-150E-460C-8AB4-E18B92D0B983}.Release|Win32.Build.0 = Release|Win32 84 | {CBE16587-150E-460C-8AB4-E18B92D0B983}.Release|x64.ActiveCfg = Release|x64 85 | {CBE16587-150E-460C-8AB4-E18B92D0B983}.Release|x64.Build.0 = Release|x64 86 | {1BE16587-150E-460C-8AB4-E18B92D0BA87}.Debug|Win32.ActiveCfg = Debug|Win32 87 | {1BE16587-150E-460C-8AB4-E18B92D0BA87}.Debug|Win32.Build.0 = Debug|Win32 88 | {1BE16587-150E-460C-8AB4-E18B92D0BA87}.Debug|x64.ActiveCfg = Debug|x64 89 | {1BE16587-150E-460C-8AB4-E18B92D0BA87}.Debug|x64.Build.0 = Debug|x64 90 | {1BE16587-150E-460C-8AB4-E18B92D0BA87}.Release|Win32.ActiveCfg = Release|Win32 91 | {1BE16587-150E-460C-8AB4-E18B92D0BA87}.Release|Win32.Build.0 = Release|Win32 92 | {1BE16587-150E-460C-8AB4-E18B92D0BA87}.Release|x64.ActiveCfg = Release|x64 93 | {1BE16587-150E-460C-8AB4-E18B92D0BA87}.Release|x64.Build.0 = Release|x64 94 | {1BE16587-260E-460C-8AB4-E18B92D0BA87}.Debug|Win32.ActiveCfg = Debug|Win32 95 | {1BE16587-260E-460C-8AB4-E18B92D0BA87}.Debug|Win32.Build.0 = Debug|Win32 96 | {1BE16587-260E-460C-8AB4-E18B92D0BA87}.Debug|x64.ActiveCfg = Debug|x64 97 | {1BE16587-260E-460C-8AB4-E18B92D0BA87}.Debug|x64.Build.0 = Debug|x64 98 | {1BE16587-260E-460C-8AB4-E18B92D0BA87}.Release|Win32.ActiveCfg = Release|Win32 99 | {1BE16587-260E-460C-8AB4-E18B92D0BA87}.Release|Win32.Build.0 = Release|Win32 100 | {1BE16587-260E-460C-8AB4-E18B92D0BA87}.Release|x64.ActiveCfg = Release|x64 101 | {1BE16587-260E-460C-8AB4-E18B92D0BA87}.Release|x64.Build.0 = Release|x64 102 | EndGlobalSection 103 | GlobalSection(SolutionProperties) = preSolution 104 | HideSolutionNode = FALSE 105 | EndGlobalSection 106 | EndGlobal 107 | -------------------------------------------------------------------------------- /lzham7zip/LzhamCodec.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | CreateObject PRIVATE 3 | GetNumberOfMethods PRIVATE 4 | GetMethodProperty PRIVATE 5 | -------------------------------------------------------------------------------- /lzham7zip/LzhamCodec.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LzhamCodec", "LzhamCodec.vcxproj", "{3681BF59-1883-4045-9712-324CB59589B6}" 5 | ProjectSection(ProjectDependencies) = postProject 6 | {8DA0CD32-701D-48D7-AE92-728338501500} = {8DA0CD32-701D-48D7-AE92-728338501500} 7 | {8DA0CD46-791D-48D7-AE92-728338501500} = {8DA0CD46-791D-48D7-AE92-728338501500} 8 | {83A2F0B5-1D02-4A13-B579-714F60E31774} = {83A2F0B5-1D02-4A13-B579-714F60E31774} 9 | EndProjectSection 10 | EndProject 11 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lzhamcomp", "..\lzhamcomp\lzhamcomp.vcxproj", "{8DA0CD46-791D-48D7-AE92-728338501500}" 12 | EndProject 13 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lzhamdecomp", "..\lzhamdecomp\lzhamdecomp.vcxproj", "{8DA0CD32-701D-48D7-AE92-728338501500}" 14 | EndProject 15 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lzhamlib", "..\lzhamlib\lzhamlib.vcxproj", "{83A2F0B5-1D02-4A13-B579-714F60E31774}" 16 | EndProject 17 | Global 18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 19 | Debug|Win32 = Debug|Win32 20 | Debug|x64 = Debug|x64 21 | Release|Win32 = Release|Win32 22 | Release|x64 = Release|x64 23 | EndGlobalSection 24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 25 | {3681BF59-1883-4045-9712-324CB59589B6}.Debug|Win32.ActiveCfg = Debug|Win32 26 | {3681BF59-1883-4045-9712-324CB59589B6}.Debug|Win32.Build.0 = Debug|Win32 27 | {3681BF59-1883-4045-9712-324CB59589B6}.Debug|x64.ActiveCfg = Debug|x64 28 | {3681BF59-1883-4045-9712-324CB59589B6}.Debug|x64.Build.0 = Debug|x64 29 | {3681BF59-1883-4045-9712-324CB59589B6}.Release|Win32.ActiveCfg = Release|Win32 30 | {3681BF59-1883-4045-9712-324CB59589B6}.Release|Win32.Build.0 = Release|Win32 31 | {3681BF59-1883-4045-9712-324CB59589B6}.Release|x64.ActiveCfg = Release|x64 32 | {3681BF59-1883-4045-9712-324CB59589B6}.Release|x64.Build.0 = Release|x64 33 | {8DA0CD46-791D-48D7-AE92-728338501500}.Debug|Win32.ActiveCfg = Debug|Win32 34 | {8DA0CD46-791D-48D7-AE92-728338501500}.Debug|Win32.Build.0 = Debug|Win32 35 | {8DA0CD46-791D-48D7-AE92-728338501500}.Debug|x64.ActiveCfg = Debug|x64 36 | {8DA0CD46-791D-48D7-AE92-728338501500}.Debug|x64.Build.0 = Debug|x64 37 | {8DA0CD46-791D-48D7-AE92-728338501500}.Release|Win32.ActiveCfg = Release|Win32 38 | {8DA0CD46-791D-48D7-AE92-728338501500}.Release|Win32.Build.0 = Release|Win32 39 | {8DA0CD46-791D-48D7-AE92-728338501500}.Release|x64.ActiveCfg = Release|x64 40 | {8DA0CD46-791D-48D7-AE92-728338501500}.Release|x64.Build.0 = Release|x64 41 | {8DA0CD32-701D-48D7-AE92-728338501500}.Debug|Win32.ActiveCfg = Debug|Win32 42 | {8DA0CD32-701D-48D7-AE92-728338501500}.Debug|Win32.Build.0 = Debug|Win32 43 | {8DA0CD32-701D-48D7-AE92-728338501500}.Debug|x64.ActiveCfg = Debug|x64 44 | {8DA0CD32-701D-48D7-AE92-728338501500}.Debug|x64.Build.0 = Debug|x64 45 | {8DA0CD32-701D-48D7-AE92-728338501500}.Release|Win32.ActiveCfg = Release|Win32 46 | {8DA0CD32-701D-48D7-AE92-728338501500}.Release|Win32.Build.0 = Release|Win32 47 | {8DA0CD32-701D-48D7-AE92-728338501500}.Release|x64.ActiveCfg = Release|x64 48 | {8DA0CD32-701D-48D7-AE92-728338501500}.Release|x64.Build.0 = Release|x64 49 | {83A2F0B5-1D02-4A13-B579-714F60E31774}.Debug|Win32.ActiveCfg = Debug|Win32 50 | {83A2F0B5-1D02-4A13-B579-714F60E31774}.Debug|Win32.Build.0 = Debug|Win32 51 | {83A2F0B5-1D02-4A13-B579-714F60E31774}.Debug|x64.ActiveCfg = Debug|x64 52 | {83A2F0B5-1D02-4A13-B579-714F60E31774}.Debug|x64.Build.0 = Debug|x64 53 | {83A2F0B5-1D02-4A13-B579-714F60E31774}.Release|Win32.ActiveCfg = Release|Win32 54 | {83A2F0B5-1D02-4A13-B579-714F60E31774}.Release|Win32.Build.0 = Release|Win32 55 | {83A2F0B5-1D02-4A13-B579-714F60E31774}.Release|x64.ActiveCfg = Release|x64 56 | {83A2F0B5-1D02-4A13-B579-714F60E31774}.Release|x64.Build.0 = Release|x64 57 | EndGlobalSection 58 | GlobalSection(SolutionProperties) = preSolution 59 | HideSolutionNode = FALSE 60 | EndGlobalSection 61 | EndGlobal 62 | -------------------------------------------------------------------------------- /lzhamcomp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | PROJECT(lzhamcomp) 2 | cmake_minimum_required(VERSION 2.8) 3 | option(BUILD_X64 "build 64-bit" TRUE) 4 | 5 | message("Initial BUILD_X64=${BUILD_X64}") 6 | message("Initial CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}") 7 | 8 | if( NOT CMAKE_BUILD_TYPE ) 9 | set( CMAKE_BUILD_TYPE Release ) 10 | endif( NOT CMAKE_BUILD_TYPE ) 11 | 12 | message( ${PROJECT_NAME} " build type: " ${CMAKE_BUILD_TYPE} ) 13 | 14 | if (BUILD_X64) 15 | message("Building 64-bit") 16 | else() 17 | message("Building 32-bit") 18 | endif(BUILD_X64) 19 | 20 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -Wall -Wextra") 21 | set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -Wall -Wextra") 22 | 23 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -Wextra -O3 -fomit-frame-pointer -fexpensive-optimizations") 24 | set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -Wextra") 25 | 26 | set(SRC_LIST 27 | lzham_lzbase.cpp 28 | lzham_lzbase.h 29 | lzham_lzcomp.cpp 30 | lzham_lzcomp_internal.cpp 31 | lzham_lzcomp_internal.h 32 | lzham_lzcomp_state.cpp 33 | lzham_match_accel.cpp 34 | lzham_match_accel.h 35 | lzham_null_threading.h 36 | lzham_pthreads_threading.cpp 37 | lzham_pthreads_threading.h 38 | lzham_threading.h) 39 | 40 | if (WIN32) 41 | list (APPEND SRC_LIST lzham_win32_threading.cpp) 42 | endif () 43 | 44 | # -fno-strict-aliasing is *required* to compile LZHAM 45 | set(GCC_COMPILE_FLAGS "-fno-strict-aliasing -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64") 46 | 47 | if (NOT BUILD_X64) 48 | set(GCC_COMPILE_FLAGS "${GCC_COMPILE_FLAGS} -m32") 49 | endif() 50 | 51 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_LINK_FLAGS}") 52 | 53 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GCC_COMPILE_FLAGS}") 54 | set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${GCC_COMPILE_FLAGS} -DNDEBUG") 55 | set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${GCC_COMPILE_FLAGS} -D_DEBUG") 56 | 57 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COMPILE_FLAGS}") 58 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${GCC_COMPILE_FLAGS} -DNDEBUG") 59 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${GCC_COMPILE_FLAGS} -D_DEBUG") 60 | 61 | include_directories( 62 | ${PROJECT_SOURCE_DIR}/../lzhamdecomp 63 | ${PROJECT_SOURCE_DIR}/../include) 64 | 65 | #set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin_linux) 66 | 67 | add_library(${PROJECT_NAME} ${SRC_LIST}) 68 | target_link_libraries(${PROJECT_NAME} lzhamdecomp pthread) 69 | install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib${LIB_SUFFIX} ARCHIVE DESTINATION lib${LIB_SUFFIX} RUNTIME DESTINATION bin) 70 | -------------------------------------------------------------------------------- /lzhamcomp/lzham_comp.h: -------------------------------------------------------------------------------- 1 | // File: lzham_comp.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | #include "lzham.h" 5 | 6 | namespace lzham 7 | { 8 | lzham_compress_state_ptr LZHAM_CDECL lzham_lib_compress_init(const lzham_compress_params *pParams); 9 | 10 | lzham_compress_state_ptr LZHAM_CDECL lzham_lib_compress_reinit(lzham_compress_state_ptr p); 11 | 12 | lzham_uint32 LZHAM_CDECL lzham_lib_compress_deinit(lzham_compress_state_ptr p); 13 | 14 | lzham_compress_status_t LZHAM_CDECL lzham_lib_compress( 15 | lzham_compress_state_ptr p, 16 | const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, 17 | lzham_uint8 *pOut_buf, size_t *pOut_buf_size, 18 | lzham_bool no_more_input_bytes_flag); 19 | 20 | lzham_compress_status_t LZHAM_CDECL lzham_lib_compress2( 21 | lzham_compress_state_ptr p, 22 | const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, 23 | lzham_uint8 *pOut_buf, size_t *pOut_buf_size, 24 | lzham_flush_t flush_type); 25 | 26 | lzham_compress_status_t LZHAM_CDECL lzham_lib_compress_memory(const lzham_compress_params *pParams, lzham_uint8* pDst_buf, size_t *pDst_len, const lzham_uint8* pSrc_buf, size_t src_len, lzham_uint32 *pAdler32); 27 | 28 | int lzham_lib_z_deflateInit(lzham_z_streamp pStream, int level); 29 | int lzham_lib_z_deflateInit2(lzham_z_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy); 30 | int lzham_lib_z_deflateReset(lzham_z_streamp pStream); 31 | int lzham_lib_z_deflate(lzham_z_streamp pStream, int flush); 32 | int lzham_lib_z_deflateEnd(lzham_z_streamp pStream); 33 | lzham_z_ulong lzham_lib_z_deflateBound(lzham_z_streamp pStream, lzham_z_ulong source_len); 34 | int lzham_lib_z_compress2(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len, int level); 35 | int lzham_lib_z_compress(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len); 36 | lzham_z_ulong lzham_lib_z_compressBound(lzham_z_ulong source_len); 37 | 38 | } // namespace lzham 39 | -------------------------------------------------------------------------------- /lzhamcomp/lzham_lzbase.h: -------------------------------------------------------------------------------- 1 | // File: lzham_lzbase.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | 5 | #include "lzham_lzdecompbase.h" 6 | 7 | //#define LZHAM_LZVERIFY 8 | //#define LZHAM_DISABLE_RAW_BLOCKS 9 | 10 | namespace lzham 11 | { 12 | 13 | struct CLZBase : CLZDecompBase 14 | { 15 | static uint8 m_slot_tab0[4096]; 16 | static uint8 m_slot_tab1[512]; 17 | static uint8 m_slot_tab2[256]; 18 | 19 | void init_slot_tabs(); 20 | 21 | inline void compute_lzx_position_slot(uint dist, uint& slot, uint& ofs) 22 | { 23 | uint s; 24 | if (dist < 0x1000) 25 | s = m_slot_tab0[dist]; 26 | else if (dist < 0x100000) 27 | s = m_slot_tab1[dist >> 11]; 28 | else if (dist < 0x1000000) 29 | s = m_slot_tab2[dist >> 16]; 30 | else if (dist < 0x2000000) 31 | s = 48 + ((dist - 0x1000000) >> 23); 32 | else if (dist < 0x4000000) 33 | s = 50 + ((dist - 0x2000000) >> 24); 34 | else 35 | s = 52 + ((dist - 0x4000000) >> 25); 36 | 37 | ofs = (dist - m_lzx_position_base[s]) & m_lzx_position_extra_mask[s]; 38 | slot = s; 39 | 40 | LZHAM_ASSERT(s < m_num_lzx_slots); 41 | LZHAM_ASSERT((m_lzx_position_base[slot] + ofs) == dist); 42 | LZHAM_ASSERT(ofs < (1U << m_lzx_position_extra_bits[slot])); 43 | } 44 | }; 45 | 46 | } // namespace lzham 47 | -------------------------------------------------------------------------------- /lzhamcomp/lzham_match_accel.h: -------------------------------------------------------------------------------- 1 | // File: lzham_match_accel.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | #include "lzham_lzbase.h" 5 | #include "lzham_threading.h" 6 | 7 | namespace lzham 8 | { 9 | const uint cMatchAccelMaxSupportedProbes = 128; 10 | const uint cMatchAccelMaxSupportedThreads = 32; 11 | 12 | struct node 13 | { 14 | uint m_left; 15 | uint m_right; 16 | }; 17 | 18 | LZHAM_DEFINE_BITWISE_MOVABLE(node); 19 | 20 | #pragma pack(push, 1) 21 | struct dict_match 22 | { 23 | uint m_dist; 24 | uint16 m_len; 25 | 26 | inline uint get_dist() const { return m_dist & 0x7FFFFFFF; } 27 | inline uint get_len() const { return m_len + 2; } 28 | inline bool is_last() const { return (int)m_dist < 0; } 29 | }; 30 | #pragma pack(pop) 31 | 32 | LZHAM_DEFINE_BITWISE_MOVABLE(dict_match); 33 | 34 | class search_accelerator 35 | { 36 | LZHAM_NO_COPY_OR_ASSIGNMENT_OP(search_accelerator); 37 | 38 | public: 39 | search_accelerator(lzham_malloc_context malloc_context); 40 | 41 | lzham_malloc_context get_malloc_context() const { return m_malloc_context; } 42 | 43 | // If all_matches is true, the match finder returns all found matches with no filtering. 44 | // Otherwise, the finder will tend to return lists of matches with mostly unique lengths. 45 | // For each length, it will discard matches with worse distances (in the coding sense). 46 | enum 47 | { 48 | cFlagDeterministic = 1, 49 | cFlagLen2Matches = 2, 50 | cFlagHash24 = 4 51 | }; 52 | 53 | bool init(CLZBase* pLZBase, task_pool* pPool, uint max_helper_threads, uint max_dict_size, uint max_matches, bool all_matches, uint max_probes, uint flags); 54 | 55 | void reset(); 56 | void flush(); 57 | 58 | inline uint get_max_dict_size() const { return m_max_dict_size; } 59 | inline uint get_max_dict_size_mask() const { return m_max_dict_size_mask; } 60 | inline uint get_cur_dict_size() const { return m_cur_dict_size; } 61 | 62 | inline uint get_lookahead_pos() const { return m_lookahead_pos; } 63 | inline uint get_lookahead_size() const { return m_lookahead_size; } 64 | 65 | inline uint get_char(int delta_pos) const { return m_dict[(m_lookahead_pos + delta_pos) & m_max_dict_size_mask]; } 66 | inline uint get_char(uint cur_dict_pos, int delta_pos) const { return m_dict[(cur_dict_pos + delta_pos) & m_max_dict_size_mask]; } 67 | inline const uint8* get_ptr(uint pos) const { return &m_dict[pos]; } 68 | 69 | uint get_max_helper_threads() const { return m_max_helper_threads; } 70 | 71 | inline uint operator[](uint pos) const { return m_dict[pos]; } 72 | 73 | uint get_max_add_bytes() const; 74 | bool add_bytes_begin(uint num_bytes, const uint8* pBytes); 75 | inline atomic32_t get_num_completed_helper_threads() const { return m_num_completed_helper_threads; } 76 | void add_bytes_end(); 77 | 78 | // Returns the lookahead's raw position/size/dict_size at the time add_bytes_begin() is called. 79 | inline uint get_fill_lookahead_pos() const { return m_fill_lookahead_pos; } 80 | inline uint get_fill_lookahead_size() const { return m_fill_lookahead_size; } 81 | inline uint get_fill_dict_size() const { return m_fill_dict_size; } 82 | 83 | uint get_len2_match(uint lookahead_ofs); 84 | dict_match* find_matches(uint lookahead_ofs, bool spin = true); 85 | 86 | void advance_bytes(uint num_bytes); 87 | 88 | LZHAM_FORCE_INLINE uint get_match_len(uint lookahead_ofs, int dist, uint max_match_len, uint start_match_len = 0) const 89 | { 90 | LZHAM_ASSERT(lookahead_ofs < m_lookahead_size); 91 | LZHAM_ASSERT(start_match_len <= max_match_len); 92 | LZHAM_ASSERT(max_match_len <= (get_lookahead_size() - lookahead_ofs)); 93 | 94 | const int find_dict_size = m_cur_dict_size + lookahead_ofs; 95 | if (dist > find_dict_size) 96 | return 0; 97 | 98 | const uint comp_pos = static_cast((m_lookahead_pos + lookahead_ofs - dist) & m_max_dict_size_mask); 99 | const uint lookahead_pos = (m_lookahead_pos + lookahead_ofs) & m_max_dict_size_mask; 100 | 101 | const uint8* pComp = &m_dict[comp_pos]; 102 | const uint8* pLookahead = &m_dict[lookahead_pos]; 103 | 104 | uint match_len; 105 | for (match_len = start_match_len; match_len < max_match_len; match_len++) 106 | if (pComp[match_len] != pLookahead[match_len]) 107 | break; 108 | 109 | return match_len; 110 | } 111 | 112 | public: 113 | lzham_malloc_context m_malloc_context; 114 | 115 | CLZBase* m_pLZBase; 116 | task_pool* m_pTask_pool; 117 | uint m_max_helper_threads; 118 | 119 | uint m_max_dict_size; 120 | uint m_max_dict_size_mask; 121 | 122 | uint m_lookahead_pos; 123 | uint m_lookahead_size; 124 | 125 | uint m_cur_dict_size; 126 | 127 | lzham::vector m_dict; 128 | 129 | lzham::vector m_hash; 130 | lzham::vector m_nodes; 131 | 132 | lzham::vector m_matches; 133 | lzham::vector m_match_refs; 134 | 135 | enum { cDigramHashSize = 4096 }; 136 | lzham::vector m_digram_hash; 137 | lzham::vector m_digram_next; 138 | 139 | lzham::vector m_thread_dict_offsets[cMatchAccelMaxSupportedThreads]; 140 | 141 | uint m_fill_lookahead_pos; 142 | uint m_fill_lookahead_size; 143 | uint m_fill_dict_size; 144 | 145 | uint m_max_probes; 146 | uint m_max_matches; 147 | 148 | bool m_all_matches; 149 | 150 | bool m_deterministic; 151 | bool m_len2_matches; 152 | bool m_hash24; 153 | 154 | volatile atomic32_t m_next_match_ref; 155 | 156 | volatile atomic32_t m_num_completed_helper_threads; 157 | 158 | void find_all_matches_callback_st(uint64 data, void* pData_ptr); 159 | void find_all_matches_callback_mt(uint64 data, void* pData_ptr); 160 | bool find_all_matches(uint num_bytes); 161 | bool find_len2_matches(); 162 | }; 163 | 164 | } // namespace lzham 165 | -------------------------------------------------------------------------------- /lzhamcomp/lzham_null_threading.h: -------------------------------------------------------------------------------- 1 | // File: lzham_task_pool_null.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | 5 | namespace lzham 6 | { 7 | class semaphore 8 | { 9 | LZHAM_NO_COPY_OR_ASSIGNMENT_OP(semaphore); 10 | 11 | public: 12 | inline semaphore(long initialCount = 0, long maximumCount = 1, const char* pName = NULL) 13 | { 14 | (void)initialCount, (void)maximumCount, (void)pName; 15 | } 16 | 17 | inline ~semaphore() 18 | { 19 | } 20 | 21 | inline void release(long releaseCount = 1, long *pPreviousCount = NULL) 22 | { 23 | (void)releaseCount, (void)pPreviousCount; 24 | } 25 | 26 | inline bool wait(uint32 milliseconds = cUINT32_MAX) 27 | { 28 | (void)milliseconds; 29 | return true; 30 | } 31 | }; 32 | 33 | class task_pool 34 | { 35 | public: 36 | inline task_pool(lzham_malloc_context malloc_context) { 37 | (void)malloc_context; } 38 | inline task_pool(uint num_threads) { (void)num_threads; } 39 | inline ~task_pool() { } 40 | 41 | inline bool init(uint num_threads) { (void)num_threads; return true; } 42 | inline void deinit(); 43 | 44 | inline uint get_num_threads() const { return 0; } 45 | inline uint get_num_outstanding_tasks() const { return 0; } 46 | 47 | // C-style task callback 48 | typedef void (*task_callback_func)(uint64 data, void* pData_ptr); 49 | inline bool queue_task(task_callback_func pFunc, uint64 data = 0, void* pData_ptr = NULL) 50 | { 51 | pFunc(data, pData_ptr); 52 | return true; 53 | } 54 | 55 | class executable_task 56 | { 57 | public: 58 | virtual void execute_task(uint64 data, void* pData_ptr) = 0; 59 | }; 60 | 61 | // It's the caller's responsibility to delete pObj within the execute_task() method, if needed! 62 | inline bool queue_task(executable_task* pObj, uint64 data = 0, void* pData_ptr = NULL) 63 | { 64 | pObj->execute_task(data, pData_ptr); 65 | return true; 66 | } 67 | 68 | template 69 | inline bool queue_object_task(S* pObject, T pObject_method, uint64 data = 0, void* pData_ptr = NULL) 70 | { 71 | (pObject->*pObject_method)(data, pData_ptr); 72 | return true; 73 | } 74 | 75 | template 76 | inline bool queue_multiple_object_tasks(S* pObject, T pObject_method, uint64 first_data, uint num_tasks, void* pData_ptr = NULL) 77 | { 78 | for (uint i = 0; i < num_tasks; i++) 79 | { 80 | (pObject->*pObject_method)(first_data + i, pData_ptr); 81 | } 82 | return true; 83 | } 84 | 85 | void join() { } 86 | }; 87 | 88 | inline void lzham_sleep(unsigned int milliseconds) 89 | { 90 | (void)milliseconds; 91 | } 92 | 93 | inline uint lzham_get_max_helper_threads() 94 | { 95 | return 0; 96 | } 97 | 98 | } // namespace lzham 99 | -------------------------------------------------------------------------------- /lzhamcomp/lzham_pthreads_threading.cpp: -------------------------------------------------------------------------------- 1 | // File: lzham_task_pool_pthreads.cpp 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #include "lzham_core.h" 4 | #include "lzham_pthreads_threading.h" 5 | #include "lzham_timer.h" 6 | 7 | #ifdef WIN32 8 | #include 9 | #endif 10 | 11 | #if defined(__GNUC__) && !defined(__APPLE__) && !defined(__MINGW32__) && !defined(__FreeBSD__) 12 | #include 13 | #endif 14 | 15 | #if LZHAM_USE_PTHREADS_API 16 | 17 | #ifdef WIN32 18 | #pragma comment(lib, "../ext/libpthread/lib/pthreadVC2.lib") 19 | #endif 20 | 21 | namespace lzham 22 | { 23 | task_pool::task_pool(lzham_malloc_context malloc_context) : 24 | m_task_stack(malloc_context), 25 | m_num_threads(0), 26 | m_tasks_available(0, 32767), 27 | m_malloc_context(malloc_context), 28 | m_num_outstanding_tasks(0), 29 | m_exit_flag(false) 30 | { 31 | utils::zero_object(m_threads); 32 | } 33 | 34 | task_pool::task_pool(lzham_malloc_context malloc_context, uint num_threads) : 35 | m_task_stack(malloc_context), 36 | m_num_threads(0), 37 | m_tasks_available(0, 32767), 38 | m_malloc_context(malloc_context), 39 | m_num_outstanding_tasks(0), 40 | m_exit_flag(false) 41 | { 42 | utils::zero_object(m_threads); 43 | 44 | bool status = init(num_threads); 45 | LZHAM_VERIFY(status); 46 | } 47 | 48 | task_pool::~task_pool() 49 | { 50 | deinit(); 51 | } 52 | 53 | bool task_pool::init(uint num_threads) 54 | { 55 | LZHAM_ASSERT(num_threads <= cMaxThreads); 56 | num_threads = math::minimum(num_threads, cMaxThreads); 57 | 58 | deinit(); 59 | 60 | bool succeeded = true; 61 | 62 | m_num_threads = 0; 63 | while (m_num_threads < num_threads) 64 | { 65 | int status = pthread_create(&m_threads[m_num_threads], NULL, thread_func, this); 66 | if (status) 67 | { 68 | succeeded = false; 69 | break; 70 | } 71 | 72 | m_num_threads++; 73 | } 74 | 75 | if (!succeeded) 76 | { 77 | deinit(); 78 | return false; 79 | } 80 | 81 | return true; 82 | } 83 | 84 | void task_pool::deinit() 85 | { 86 | if (m_num_threads) 87 | { 88 | join(); 89 | 90 | atomic_exchange32(&m_exit_flag, true); 91 | 92 | m_tasks_available.release(m_num_threads); 93 | 94 | for (uint i = 0; i < m_num_threads; i++) 95 | pthread_join(m_threads[i], NULL); 96 | 97 | m_num_threads = 0; 98 | 99 | atomic_exchange32(&m_exit_flag, false); 100 | } 101 | 102 | m_task_stack.clear(); 103 | m_num_outstanding_tasks = 0; 104 | } 105 | 106 | bool task_pool::queue_task(task_callback_func pFunc, uint64 data, void* pData_ptr) 107 | { 108 | LZHAM_ASSERT(m_num_threads); 109 | LZHAM_ASSERT(pFunc); 110 | 111 | task tsk; 112 | tsk.m_callback = pFunc; 113 | tsk.m_data = data; 114 | tsk.m_pData_ptr = pData_ptr; 115 | tsk.m_flags = 0; 116 | 117 | if (!m_task_stack.try_push(tsk)) 118 | return false; 119 | 120 | atomic_increment32(&m_num_outstanding_tasks); 121 | 122 | m_tasks_available.release(1); 123 | 124 | return true; 125 | } 126 | 127 | // It's the object's responsibility to delete pObj within the execute_task() method, if needed! 128 | bool task_pool::queue_task(executable_task* pObj, uint64 data, void* pData_ptr) 129 | { 130 | LZHAM_ASSERT(m_num_threads); 131 | LZHAM_ASSERT(pObj); 132 | 133 | task tsk; 134 | tsk.m_pObj = pObj; 135 | tsk.m_data = data; 136 | tsk.m_pData_ptr = pData_ptr; 137 | tsk.m_flags = cTaskFlagObject; 138 | 139 | if (!m_task_stack.try_push(tsk)) 140 | return false; 141 | 142 | atomic_increment32(&m_num_outstanding_tasks); 143 | 144 | m_tasks_available.release(1); 145 | 146 | return true; 147 | } 148 | 149 | void task_pool::process_task(task& tsk) 150 | { 151 | if (tsk.m_flags & cTaskFlagObject) 152 | tsk.m_pObj->execute_task(tsk.m_data, tsk.m_pData_ptr); 153 | else 154 | tsk.m_callback(tsk.m_data, tsk.m_pData_ptr); 155 | 156 | atomic_decrement32(&m_num_outstanding_tasks); 157 | } 158 | 159 | void task_pool::join() 160 | { 161 | task tsk; 162 | while (atomic_add32(&m_num_outstanding_tasks, 0) > 0) 163 | { 164 | if (m_task_stack.pop(tsk)) 165 | { 166 | process_task(tsk); 167 | } 168 | else 169 | { 170 | lzham_sleep(1); 171 | } 172 | } 173 | } 174 | 175 | void * task_pool::thread_func(void *pContext) 176 | { 177 | task_pool* pPool = static_cast(pContext); 178 | task tsk; 179 | 180 | for ( ; ; ) 181 | { 182 | if (!pPool->m_tasks_available.wait()) 183 | break; 184 | 185 | if (pPool->m_exit_flag) 186 | break; 187 | 188 | if (pPool->m_task_stack.pop(tsk)) 189 | { 190 | pPool->process_task(tsk); 191 | } 192 | } 193 | 194 | return NULL; 195 | } 196 | 197 | uint lzham_get_max_helper_threads() 198 | { 199 | #if defined(__APPLE__) || defined(__FreeBSD__) 200 | int num_procs = static_cast(sysconf(_SC_NPROCESSORS_ONLN)); 201 | return (num_procs >= 1) ? (num_procs - 1) : 0; 202 | #elif (1) 203 | uint num_procs = get_nprocs(); 204 | return num_procs ? (num_procs - 1) : 0; 205 | #else 206 | printf("TODO: lzham_get_max_helper_threads(): Implement system specific func to determine the max # of helper threads\n"); 207 | // Just assume a dual-core machine. 208 | return 1; 209 | #endif 210 | } 211 | 212 | } // namespace lzham 213 | 214 | #endif // LZHAM_USE_PTHREADS_API 215 | -------------------------------------------------------------------------------- /lzhamcomp/lzham_threading.h: -------------------------------------------------------------------------------- 1 | // File: lzham_threading.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | 4 | #if LZHAM_USE_WIN32_API 5 | #include "lzham_win32_threading.h" 6 | #elif LZHAM_USE_PTHREADS_API 7 | #include "lzham_pthreads_threading.h" 8 | #else 9 | #include "lzham_null_threading.h" 10 | #endif 11 | 12 | 13 | -------------------------------------------------------------------------------- /lzhamcomp/lzham_win32_threading.cpp: -------------------------------------------------------------------------------- 1 | // File: lzham_task_pool_win32.cpp 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #include "lzham_core.h" 4 | #include "lzham_win32_threading.h" 5 | #include "lzham_timer.h" 6 | #include "lzham_lzcomp_internal.h" 7 | #include 8 | 9 | #if LZHAM_USE_WIN32_API 10 | 11 | namespace lzham 12 | { 13 | task_pool::task_pool(lzham_malloc_context malloc_context) : 14 | m_malloc_context(malloc_context), 15 | m_task_stack(malloc_context), 16 | m_num_threads(0), 17 | m_tasks_available(0, 32767), 18 | m_num_outstanding_tasks(0), 19 | m_exit_flag(false) 20 | { 21 | utils::zero_object(m_threads); 22 | } 23 | 24 | task_pool::task_pool(lzham_malloc_context malloc_context, uint num_threads) : 25 | m_malloc_context(malloc_context), 26 | m_task_stack(malloc_context), 27 | m_num_threads(0), 28 | m_tasks_available(0, 32767), 29 | m_num_outstanding_tasks(0), 30 | m_exit_flag(false) 31 | { 32 | utils::zero_object(m_threads); 33 | 34 | bool status = init(num_threads); 35 | LZHAM_VERIFY(status); 36 | } 37 | 38 | task_pool::~task_pool() 39 | { 40 | deinit(); 41 | } 42 | 43 | bool task_pool::init(uint num_threads) 44 | { 45 | LZHAM_ASSERT(num_threads <= cMaxThreads); 46 | num_threads = math::minimum(num_threads, cMaxThreads); 47 | 48 | deinit(); 49 | 50 | bool succeeded = true; 51 | 52 | m_num_threads = 0; 53 | while (m_num_threads < num_threads) 54 | { 55 | m_threads[m_num_threads] = (HANDLE)_beginthreadex(NULL, 32768, thread_func, this, 0, NULL); 56 | LZHAM_ASSERT(m_threads[m_num_threads] != 0); 57 | 58 | if (!m_threads[m_num_threads]) 59 | { 60 | succeeded = false; 61 | LZHAM_LOG_ERROR(10000); 62 | break; 63 | } 64 | 65 | m_num_threads++; 66 | } 67 | 68 | if (!succeeded) 69 | { 70 | deinit(); 71 | return false; 72 | } 73 | 74 | return true; 75 | } 76 | 77 | void task_pool::deinit() 78 | { 79 | if (m_num_threads) 80 | { 81 | join(); 82 | 83 | atomic_exchange32(&m_exit_flag, true); 84 | 85 | m_tasks_available.release(m_num_threads); 86 | 87 | for (uint i = 0; i < m_num_threads; i++) 88 | { 89 | if (m_threads[i]) 90 | { 91 | for ( ; ; ) 92 | { 93 | DWORD result = WaitForSingleObject(m_threads[i], 30000); 94 | if ((result == WAIT_OBJECT_0) || (result == WAIT_ABANDONED)) 95 | break; 96 | } 97 | 98 | CloseHandle(m_threads[i]); 99 | m_threads[i] = NULL; 100 | } 101 | } 102 | 103 | m_num_threads = 0; 104 | 105 | atomic_exchange32(&m_exit_flag, false); 106 | } 107 | 108 | m_task_stack.clear(); 109 | m_num_outstanding_tasks = 0; 110 | } 111 | 112 | bool task_pool::queue_task(task_callback_func pFunc, uint64 data, void* pData_ptr) 113 | { 114 | LZHAM_ASSERT(m_num_threads); 115 | LZHAM_ASSERT(pFunc); 116 | 117 | task tsk; 118 | tsk.m_callback = pFunc; 119 | tsk.m_data = data; 120 | tsk.m_pData_ptr = pData_ptr; 121 | tsk.m_flags = 0; 122 | 123 | if (!m_task_stack.try_push(tsk)) 124 | { 125 | LZHAM_LOG_ERROR(10001); 126 | return false; 127 | } 128 | 129 | atomic_increment32(&m_num_outstanding_tasks); 130 | 131 | m_tasks_available.release(1); 132 | 133 | return true; 134 | } 135 | 136 | // It's the object's responsibility to delete pObj within the execute_task() method, if needed! 137 | bool task_pool::queue_task(executable_task* pObj, uint64 data, void* pData_ptr) 138 | { 139 | LZHAM_ASSERT(m_num_threads); 140 | LZHAM_ASSERT(pObj); 141 | 142 | task tsk; 143 | tsk.m_pObj = pObj; 144 | tsk.m_data = data; 145 | tsk.m_pData_ptr = pData_ptr; 146 | tsk.m_flags = cTaskFlagObject; 147 | 148 | if (!m_task_stack.try_push(tsk)) 149 | { 150 | LZHAM_LOG_ERROR(10002); 151 | return false; 152 | } 153 | 154 | atomic_increment32(&m_num_outstanding_tasks); 155 | 156 | m_tasks_available.release(1); 157 | 158 | return true; 159 | } 160 | 161 | void task_pool::process_task(task& tsk) 162 | { 163 | if (tsk.m_flags & cTaskFlagObject) 164 | tsk.m_pObj->execute_task(tsk.m_data, tsk.m_pData_ptr); 165 | else 166 | tsk.m_callback(tsk.m_data, tsk.m_pData_ptr); 167 | 168 | atomic_decrement32(&m_num_outstanding_tasks); 169 | } 170 | 171 | void task_pool::join() 172 | { 173 | while (atomic_add32(&m_num_outstanding_tasks, 0) > 0) 174 | { 175 | task tsk; 176 | if (m_task_stack.pop(tsk)) 177 | { 178 | process_task(tsk); 179 | } 180 | else 181 | { 182 | lzham_sleep(1); 183 | } 184 | } 185 | } 186 | 187 | unsigned __stdcall task_pool::thread_func(void* pContext) 188 | { 189 | task_pool* pPool = static_cast(pContext); 190 | 191 | for ( ; ; ) 192 | { 193 | if (!pPool->m_tasks_available.wait()) 194 | break; 195 | 196 | if (pPool->m_exit_flag) 197 | break; 198 | 199 | task tsk; 200 | if (pPool->m_task_stack.pop(tsk)) 201 | { 202 | pPool->process_task(tsk); 203 | } 204 | } 205 | 206 | _endthreadex(0); 207 | return 0; 208 | } 209 | 210 | static uint g_num_processors; 211 | 212 | uint lzham_get_max_helper_threads() 213 | { 214 | if (!g_num_processors) 215 | { 216 | SYSTEM_INFO system_info; 217 | GetSystemInfo(&system_info); 218 | g_num_processors = system_info.dwNumberOfProcessors; 219 | } 220 | 221 | if (g_num_processors > 1) 222 | { 223 | // use all CPU's 224 | return LZHAM_MIN((uint)task_pool::cMaxThreads, g_num_processors - 1); 225 | } 226 | 227 | return 0; 228 | } 229 | 230 | } // namespace lzham 231 | 232 | #endif // LZHAM_USE_WIN32_API 233 | -------------------------------------------------------------------------------- /lzhamdecomp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | PROJECT(lzhamdecomp) 2 | cmake_minimum_required(VERSION 2.8) 3 | option(BUILD_X64 "build 64-bit" TRUE) 4 | 5 | message("Initial BUILD_X64=${BUILD_X64}") 6 | message("Initial CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}") 7 | 8 | if( NOT CMAKE_BUILD_TYPE ) 9 | set( CMAKE_BUILD_TYPE Release ) 10 | endif( NOT CMAKE_BUILD_TYPE ) 11 | 12 | message( ${PROJECT_NAME} " build type: " ${CMAKE_BUILD_TYPE} ) 13 | 14 | if (BUILD_X64) 15 | message("Building 64-bit") 16 | else() 17 | message("Building 32-bit") 18 | endif(BUILD_X64) 19 | 20 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -Wall -Wextra") 21 | set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -Wall -Wextra") 22 | 23 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -Wextra -O3 -fomit-frame-pointer -fexpensive-optimizations") 24 | set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -Wextra") 25 | 26 | set(SRC_LIST 27 | ../include/lzham_dynamic_lib.h 28 | ../include/lzham_static_lib.h 29 | ../include/lzham.h 30 | ../include/lzham_exports.inc 31 | ../include/zlib.h 32 | lzham_assert.cpp 33 | lzham_assert.h 34 | lzham_checksum.cpp 35 | lzham_checksum.h 36 | lzham_config.h 37 | lzham_core.h 38 | lzham_decomp.h 39 | lzham_helpers.h 40 | lzham_huffman_codes.cpp 41 | lzham_huffman_codes.h 42 | lzham_lzdecompbase.cpp 43 | lzham_lzdecompbase.h 44 | lzham_lzdecomp.cpp 45 | lzham_math.h 46 | lzham_mem.cpp 47 | lzham_mem.h 48 | lzham_platform.cpp 49 | lzham_platform.h 50 | lzham_prefix_coding.cpp 51 | lzham_prefix_coding.h 52 | lzham_symbol_codec.cpp 53 | lzham_symbol_codec.h 54 | lzham_timer.cpp 55 | lzham_timer.h 56 | lzham_traits.h 57 | lzham_types.h 58 | lzham_utils.h 59 | lzham_vector.cpp 60 | lzham_vector.h) 61 | 62 | # -fno-strict-aliasing is *required* to compile LZHAM 63 | set(GCC_COMPILE_FLAGS "-fno-strict-aliasing -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64") 64 | 65 | if (NOT BUILD_X64) 66 | set(GCC_COMPILE_FLAGS "${GCC_COMPILE_FLAGS} -m32") 67 | endif() 68 | 69 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_LINK_FLAGS}") 70 | 71 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GCC_COMPILE_FLAGS}") 72 | set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${GCC_COMPILE_FLAGS} -DNDEBUG") 73 | set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${GCC_COMPILE_FLAGS} -D_DEBUG") 74 | 75 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COMPILE_FLAGS}") 76 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${GCC_COMPILE_FLAGS} -DNDEBUG") 77 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${GCC_COMPILE_FLAGS} -D_DEBUG") 78 | 79 | include_directories( 80 | ${PROJECT_SOURCE_DIR}/../lzhamdecomp 81 | ${PROJECT_SOURCE_DIR}/../include) 82 | 83 | #set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin_linux) 84 | 85 | add_library(${PROJECT_NAME} ${SRC_LIST}) 86 | install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib${LIB_SUFFIX} ARCHIVE DESTINATION lib${LIB_SUFFIX} RUNTIME DESTINATION bin) 87 | -------------------------------------------------------------------------------- /lzhamdecomp/lzham_assert.cpp: -------------------------------------------------------------------------------- 1 | // File: lzham_assert.cpp 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #include "lzham_core.h" 4 | 5 | static bool g_fail_exceptions; 6 | static bool g_exit_on_failure = true; 7 | 8 | void lzham_enable_fail_exceptions(bool enabled) 9 | { 10 | g_fail_exceptions = enabled; 11 | } 12 | 13 | void lzham_assert(const char* pExp, const char* pFile, unsigned line) 14 | { 15 | char buf[512]; 16 | 17 | sprintf_s(buf, sizeof(buf), "%s(%u): Assertion failed: \"%s\"\n", pFile, line, pExp); 18 | 19 | lzham_output_debug_string(buf); 20 | 21 | printf("%s", buf); 22 | 23 | if (lzham_is_debugger_present()) 24 | lzham_debug_break(); 25 | } 26 | 27 | void lzham_fail(const char* pExp, const char* pFile, unsigned line) 28 | { 29 | char buf[512]; 30 | 31 | sprintf_s(buf, sizeof(buf), "%s(%u): Failure: \"%s\"\n", pFile, line, pExp); 32 | 33 | lzham_output_debug_string(buf); 34 | 35 | printf("%s", buf); 36 | 37 | if (lzham_is_debugger_present()) 38 | lzham_debug_break(); 39 | 40 | #if LZHAM_USE_WIN32_API 41 | if (g_fail_exceptions) 42 | RaiseException(LZHAM_FAIL_EXCEPTION_CODE, 0, 0, NULL); 43 | else 44 | #endif 45 | if (g_exit_on_failure) 46 | exit(EXIT_FAILURE); 47 | } 48 | 49 | void lzham_trace(const char* pFmt, va_list args) 50 | { 51 | if (lzham_is_debugger_present()) 52 | { 53 | char buf[512]; 54 | vsprintf_s(buf, sizeof(buf), pFmt, args); 55 | 56 | lzham_output_debug_string(buf); 57 | } 58 | } 59 | 60 | void lzham_trace(const char* pFmt, ...) 61 | { 62 | va_list args; 63 | va_start(args, pFmt); 64 | lzham_trace(pFmt, args); 65 | va_end(args); 66 | } 67 | 68 | #if LZHAM_ERROR_LOGGING 69 | #if LZHAM_VERBOSE_ERROR_LOGGING 70 | void lzham_log_error(const char *pFunc, const char *pFile, int line, const char *pMsg, int idx) 71 | { 72 | fprintf(stderr, "\nlzham_log_error: %i %s file: %s line: %u func %s\n", idx, pMsg ? pMsg : "", pFile, line, pFunc); 73 | } 74 | #else 75 | void lzham_log_error(int idx) 76 | { 77 | fprintf(stderr, "\nlzham_log_error: %i\n", idx); 78 | } 79 | #endif 80 | #endif 81 | -------------------------------------------------------------------------------- /lzhamdecomp/lzham_assert.h: -------------------------------------------------------------------------------- 1 | // File: lzham_assert.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | 5 | #if LZHAM_ERROR_LOGGING 6 | #if LZHAM_VERBOSE_ERROR_LOGGING 7 | #define LZHAM_LOG_ERROR(idx) do { lzham_log_error(__FUNCTION__, __FILE__, __LINE__, "", idx); } while(0) 8 | #else 9 | #define LZHAM_LOG_ERROR(idx) do { lzham_log_error(idx); } while(0) 10 | #endif 11 | #else 12 | #define LZHAM_LOG_ERROR(idx) 13 | #endif 14 | 15 | #if LZHAM_ERROR_LOGGING 16 | #if LZHAM_VERBOSE_ERROR_LOGGING 17 | void lzham_log_error(const char *pFunc, const char *pFile, int line, const char *pMsg, int idx); 18 | #else 19 | void lzham_log_error(int idx); 20 | #endif 21 | #endif 22 | 23 | const unsigned int LZHAM_FAIL_EXCEPTION_CODE = 256U; 24 | void lzham_enable_fail_exceptions(bool enabled); 25 | 26 | void lzham_assert(const char* pExp, const char* pFile, unsigned line); 27 | void lzham_fail(const char* pExp, const char* pFile, unsigned line); 28 | 29 | #ifdef NDEBUG 30 | #define LZHAM_ASSERT(x) ((void)0) 31 | #else 32 | #define LZHAM_ASSERT(_exp) (void)( (!!(_exp)) || (lzham_assert(#_exp, __FILE__, __LINE__), 0) ) 33 | #define LZHAM_ASSERTS_ENABLED 1 34 | #endif 35 | 36 | #define LZHAM_VERIFY(_exp) (void)( (!!(_exp)) || (lzham_assert(#_exp, __FILE__, __LINE__), 0) ) 37 | 38 | #define LZHAM_FAIL(msg) do { lzham_fail(#msg, __FILE__, __LINE__); } while(0) 39 | 40 | #define LZHAM_ASSERT_OPEN_RANGE(x, l, h) LZHAM_ASSERT((x >= l) && (x < h)) 41 | #define LZHAM_ASSERT_CLOSED_RANGE(x, l, h) LZHAM_ASSERT((x >= l) && (x <= h)) 42 | 43 | void lzham_trace(const char* pFmt, va_list args); 44 | void lzham_trace(const char* pFmt, ...); 45 | 46 | // Borrowed from boost libraries. 47 | template struct assume_failure; 48 | template <> struct assume_failure { enum { blah = 1 }; }; 49 | template struct assume_try { }; 50 | 51 | #define LZHAM_JOINER_FINAL(a, b) a##b 52 | #define LZHAM_JOINER(a, b) LZHAM_JOINER_FINAL(a, b) 53 | #define LZHAM_JOIN(a, b) LZHAM_JOINER(a, b) 54 | #if defined(__GNUC__) 55 | #define LZHAM_ASSUME(p) typedef assume_try < sizeof(assume_failure< (bool)(p) > ) > LZHAM_JOIN(assume_typedef, __COUNTER__) __attribute__((unused)) 56 | #else 57 | #define LZHAM_ASSUME(p) typedef assume_try < sizeof(assume_failure< (bool)(p) > ) > LZHAM_JOIN(assume_typedef, __COUNTER__) 58 | #endif 59 | -------------------------------------------------------------------------------- /lzhamdecomp/lzham_checksum.cpp: -------------------------------------------------------------------------------- 1 | // File: lzham_checksum.cpp 2 | #include "lzham_core.h" 3 | #include "lzham_checksum.h" 4 | 5 | namespace lzham 6 | { 7 | // Originally from the public domain stb.h header. 8 | uint adler32(const void* pBuf, size_t buflen, uint adler32) 9 | { 10 | if (!pBuf) 11 | return cInitAdler32; 12 | 13 | const uint8* buffer = static_cast(pBuf); 14 | 15 | const unsigned long ADLER_MOD = 65521; 16 | unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16; 17 | size_t blocklen; 18 | unsigned long i; 19 | 20 | blocklen = buflen % 5552; 21 | while (buflen) 22 | { 23 | for (i=0; i + 7 < blocklen; i += 8) 24 | { 25 | s1 += buffer[0], s2 += s1; 26 | s1 += buffer[1], s2 += s1; 27 | s1 += buffer[2], s2 += s1; 28 | s1 += buffer[3], s2 += s1; 29 | s1 += buffer[4], s2 += s1; 30 | s1 += buffer[5], s2 += s1; 31 | s1 += buffer[6], s2 += s1; 32 | s1 += buffer[7], s2 += s1; 33 | 34 | buffer += 8; 35 | } 36 | 37 | for (; i < blocklen; ++i) 38 | s1 += *buffer++, s2 += s1; 39 | 40 | s1 %= ADLER_MOD, s2 %= ADLER_MOD; 41 | buflen -= blocklen; 42 | blocklen = 5552; 43 | } 44 | return static_cast((s2 << 16) + s1); 45 | } 46 | 47 | // Karl Malbrain's compact CRC-32, with pre and post conditioning. 48 | // See "A compact CCITT crc16 and crc32 C implementation that balances processor cache usage against speed": 49 | // http://www.geocities.com/malbrain/ 50 | static const lzham_uint32 s_crc32[16] = 51 | { 52 | 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, 53 | 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c 54 | }; 55 | 56 | uint crc32(uint crc, const lzham_uint8 *ptr, size_t buf_len) 57 | { 58 | if (!ptr) 59 | return cInitCRC32; 60 | 61 | crc = ~crc; 62 | while (buf_len--) 63 | { 64 | lzham_uint8 b = *ptr++; 65 | crc = (crc >> 4) ^ s_crc32[(crc & 0xF) ^ (b & 0xF)]; 66 | crc = (crc >> 4) ^ s_crc32[(crc & 0xF) ^ (b >> 4)]; 67 | } 68 | return ~crc; 69 | } 70 | 71 | 72 | } // namespace lzham 73 | 74 | -------------------------------------------------------------------------------- /lzhamdecomp/lzham_checksum.h: -------------------------------------------------------------------------------- 1 | // File: lzham_checksum.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | 5 | namespace lzham 6 | { 7 | const uint cInitAdler32 = 1U; 8 | uint adler32(const void* pBuf, size_t buflen, uint adler32 = cInitAdler32); 9 | 10 | const uint cInitCRC32 = 0U; 11 | uint crc32(uint crc, const lzham_uint8 *ptr, size_t buf_len); 12 | 13 | } // namespace lzham 14 | -------------------------------------------------------------------------------- /lzhamdecomp/lzham_config.h: -------------------------------------------------------------------------------- 1 | // File: lzham_config.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | 5 | #if defined(_DEBUG) || defined(DEBUG) 6 | #define LZHAM_BUILD_DEBUG 7 | 8 | #ifndef DEBUG 9 | #define DEBUG 10 | #endif 11 | #else 12 | #define LZHAM_BUILD_RELEASE 13 | 14 | #ifndef NDEBUG 15 | #define NDEBUG 16 | #endif 17 | 18 | #ifdef DEBUG 19 | #error DEBUG cannot be defined in LZHAM_BUILD_RELEASE 20 | #endif 21 | #endif 22 | 23 | // HACK HACK 24 | #define LZHAM_BUFFERED_PRINTF 0 25 | #define LZHAM_PERF_SECTIONS 0 -------------------------------------------------------------------------------- /lzhamdecomp/lzham_core.h: -------------------------------------------------------------------------------- 1 | // File: lzham_core.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | 5 | #if defined(_MSC_VER) 6 | #pragma warning (disable: 4127) // conditional expression is constant 7 | #endif 8 | 9 | // If LZHAM_ERROR_LOGGING is 1, LZHAM will write a short internal error codes to stderr when something goes wrong. These codes can be very useful for postmortem debugging. 10 | #ifndef LZHAM_ERROR_LOGGING 11 | #define LZHAM_ERROR_LOGGING 0 12 | #endif 13 | 14 | // If LZHAM_VERBOSE_ERROR_LOGGING, LZHAM will also write the function, file and line # along with the error code to stderr. 15 | #ifndef LZHAM_VERBOSE_ERROR_LOGGING 16 | #define LZHAM_VERBOSE_ERROR_LOGGING 0 17 | #endif 18 | 19 | // Enable this when first porting to new platforms - disables all threading and atomic ops in compressor: 20 | //#define LZHAM_ANSI_CPLUSPLUS 1 21 | 22 | #if defined(__FreeBSD__) || defined(__NetBSD__) 23 | // TODO: I compile and do minimal testing on FreeBSD v10.1 x86, but I haven't enabled threading there yet. (Should be easy because OSX is already supported with threading.) 24 | #define LZHAM_ANSI_CPLUSPLUS 1 25 | #endif 26 | 27 | #if defined(__APPLE__) && defined(__MACH__) 28 | // Apple OSX and iOS 29 | #include 30 | #endif 31 | 32 | #if defined(_XBOX) && !defined(LZHAM_ANSI_CPLUSPLUS) 33 | // --- X360 - This hasn't been tested since early an alpha. 34 | #include 35 | #define _HAS_EXCEPTIONS 0 36 | #define NOMINMAX 37 | 38 | #define LZHAM_PLATFORM_X360 1 39 | #define LZHAM_USE_WIN32_API 1 40 | #define LZHAM_USE_WIN32_ATOMIC_FUNCTIONS 1 41 | #define LZHAM_64BIT_POINTERS 0 42 | #define LZHAM_CPU_HAS_64BIT_REGISTERS 1 43 | #define LZHAM_BIG_ENDIAN_CPU 1 44 | #define LZHAM_USE_UNALIGNED_INT_LOADS 1 45 | #define LZHAM_RESTRICT __restrict 46 | #define LZHAM_FORCE_INLINE __forceinline 47 | #define LZHAM_NOTE_UNUSED(x) (void)x 48 | 49 | #define LZHAM_PRIi64 "I64i" 50 | #define LZHAM_PRIu64 "I64u" 51 | 52 | #elif defined(WIN32) && !defined(LZHAM_ANSI_CPLUSPLUS) 53 | // --- Windows: MSVC or MinGW, x86 or x64, Win32 API's for threading and Win32 Interlocked API's or GCC built-ins for atomic ops. 54 | #ifdef NDEBUG 55 | // Ensure checked iterators are disabled. 56 | #define _SECURE_SCL 0 57 | #define _HAS_ITERATOR_DEBUGGING 0 58 | #endif 59 | #ifndef _DLL 60 | // If we're using the DLL form of the run-time libs, we're also going to be enabling exceptions because we'll be building CLR apps. 61 | // Otherwise, we disable exceptions for a small speed boost. 62 | #define _HAS_EXCEPTIONS 0 63 | #endif 64 | #define NOMINMAX 65 | 66 | #ifndef _WIN32_WINNT 67 | #define _WIN32_WINNT 0x500 68 | #endif 69 | 70 | #ifndef WIN32_LEAN_AND_MEAN 71 | #define WIN32_LEAN_AND_MEAN 72 | #endif 73 | 74 | #include 75 | 76 | #define LZHAM_USE_WIN32_API 1 77 | 78 | #if defined(__MINGW32__) || defined(__MINGW64__) 79 | #define LZHAM_USE_GCC_ATOMIC_BUILTINS 1 80 | #else 81 | #define LZHAM_USE_WIN32_ATOMIC_FUNCTIONS 1 82 | #endif 83 | 84 | #define LZHAM_PLATFORM_PC 1 85 | 86 | #ifdef _WIN64 87 | #define LZHAM_PLATFORM_PC_X64 1 88 | #define LZHAM_64BIT_POINTERS 1 89 | #define LZHAM_CPU_HAS_64BIT_REGISTERS 1 90 | #define LZHAM_LITTLE_ENDIAN_CPU 1 91 | #else 92 | #define LZHAM_PLATFORM_PC_X86 1 93 | #define LZHAM_64BIT_POINTERS 0 94 | #define LZHAM_CPU_HAS_64BIT_REGISTERS 0 95 | #define LZHAM_LITTLE_ENDIAN_CPU 1 96 | #endif 97 | 98 | #define LZHAM_USE_UNALIGNED_INT_LOADS 1 99 | #define LZHAM_RESTRICT __restrict 100 | #define LZHAM_FORCE_INLINE __forceinline 101 | 102 | #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) 103 | #define LZHAM_USE_MSVC_INTRINSICS 1 104 | #endif 105 | 106 | #define LZHAM_NOTE_UNUSED(x) (void)x 107 | 108 | #define LZHAM_PRIi64 "I64i" 109 | #define LZHAM_PRIu64 "I64u" 110 | 111 | #elif defined(__APPLE__) && !defined(LZHAM_ANSI_CPLUSPLUS) 112 | // --- Apple: iOS or OSX 113 | #if (TARGET_IPHONE_SIMULATOR == 1) || (TARGET_OS_IPHONE == 1) 114 | #define LZHAM_PLATFORM_PC 0 115 | 116 | #if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) 117 | #define LZHAM_PLATFORM_PC_X64 0 118 | #define LZHAM_64BIT_POINTERS 1 119 | #define LZHAM_CPU_HAS_64BIT_REGISTERS 1 120 | #else 121 | #define LZHAM_PLATFORM_PC_X86 0 122 | #define LZHAM_64BIT_POINTERS 0 123 | #define LZHAM_CPU_HAS_64BIT_REGISTERS 0 124 | #endif 125 | 126 | #define LZHAM_USE_UNALIGNED_INT_LOADS 0 127 | 128 | #if __BIG_ENDIAN__ 129 | #define LZHAM_BIG_ENDIAN_CPU 1 130 | #else 131 | #define LZHAM_LITTLE_ENDIAN_CPU 1 132 | #endif 133 | 134 | #define LZHAM_USE_PTHREADS_API 1 135 | #define LZHAM_USE_GCC_ATOMIC_BUILTINS 1 136 | 137 | #define LZHAM_RESTRICT 138 | 139 | #if defined(__clang__) 140 | #define LZHAM_FORCE_INLINE inline 141 | #else 142 | #define LZHAM_FORCE_INLINE inline __attribute__((__always_inline__,__gnu_inline__)) 143 | #endif 144 | 145 | #define LZHAM_NOTE_UNUSED(x) (void)x 146 | 147 | #define LZHAM_PRIi64 PRIi64 148 | #define LZHAM_PRIu64 PRIu64 149 | 150 | #elif (TARGET_OS_MAC == 1) 151 | #define LZHAM_PLATFORM_PC 1 152 | 153 | #if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) 154 | #define LZHAM_PLATFORM_PC_X64 1 155 | #define LZHAM_64BIT_POINTERS 1 156 | #define LZHAM_CPU_HAS_64BIT_REGISTERS 1 157 | #else 158 | #define LZHAM_PLATFORM_PC_X86 1 159 | #define LZHAM_64BIT_POINTERS 0 160 | #define LZHAM_CPU_HAS_64BIT_REGISTERS 0 161 | #endif 162 | 163 | #define LZHAM_USE_UNALIGNED_INT_LOADS 1 164 | 165 | #if __BIG_ENDIAN__ 166 | #define LZHAM_BIG_ENDIAN_CPU 1 167 | #else 168 | #define LZHAM_LITTLE_ENDIAN_CPU 1 169 | #endif 170 | 171 | #define LZHAM_USE_PTHREADS_API 1 172 | #define LZHAM_USE_GCC_ATOMIC_BUILTINS 1 173 | 174 | #define LZHAM_RESTRICT 175 | 176 | #if defined(__clang__) 177 | #define LZHAM_FORCE_INLINE inline 178 | #else 179 | #define LZHAM_FORCE_INLINE inline __attribute__((__always_inline__,__gnu_inline__)) 180 | #endif 181 | 182 | #define LZHAM_NOTE_UNUSED(x) (void)x 183 | 184 | #define LZHAM_PRIi64 PRIi64 185 | #define LZHAM_PRIu64 PRIu64 186 | #elif 187 | #error TODO: Unknown Apple target 188 | #endif 189 | 190 | #elif defined(__linux__) && (defined(__i386__) || defined(__x86_64__)) && !defined(LZHAM_ANSI_CPLUSPLUS) 191 | // --- Generic GCC/clang path for x86/x64, clang or GCC, Linux, OSX, FreeBSD or NetBSD, pthreads for threading, GCC built-ins for atomic ops. 192 | #define LZHAM_PLATFORM_PC 1 193 | 194 | #if defined(_LP64) || defined(__LP64__) || defined(__x86_64__) 195 | // 64-bit build assumes pointers are always 64-bit 196 | #define LZHAM_PLATFORM_PC_X64 1 197 | #define LZHAM_64BIT_POINTERS 1 198 | #define LZHAM_CPU_HAS_64BIT_REGISTERS 1 199 | #else 200 | #define LZHAM_PLATFORM_PC_X86 1 201 | #define LZHAM_64BIT_POINTERS 0 202 | #define LZHAM_CPU_HAS_64BIT_REGISTERS 0 203 | #endif 204 | 205 | #define LZHAM_USE_UNALIGNED_INT_LOADS 1 206 | 207 | #if __BIG_ENDIAN__ 208 | #define LZHAM_BIG_ENDIAN_CPU 1 209 | #else 210 | #define LZHAM_LITTLE_ENDIAN_CPU 1 211 | #endif 212 | 213 | #define LZHAM_USE_PTHREADS_API 1 214 | #define LZHAM_USE_GCC_ATOMIC_BUILTINS 1 215 | 216 | #define LZHAM_RESTRICT 217 | 218 | #if defined(__clang__) 219 | #define LZHAM_FORCE_INLINE inline 220 | #else 221 | #define LZHAM_FORCE_INLINE inline __attribute__((__always_inline__,__gnu_inline__)) 222 | #endif 223 | 224 | #define LZHAM_NOTE_UNUSED(x) (void)x 225 | 226 | #define LZHAM_PRIi64 PRIi64 227 | #define LZHAM_PRIu64 PRIu64 228 | #else 229 | 230 | #ifndef _MSC_VER 231 | #warning Building as vanilla ANSI-C/C++, multi-threaded compression is disabled! Please configure lzhamdecomp/lzham_core.h. 232 | #endif 233 | 234 | // --- Vanilla ANSI-C/C++ 235 | // No threading support, unaligned loads are NOT okay, no atomic ops. 236 | #if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) 237 | #define LZHAM_64BIT_POINTERS 1 238 | #define LZHAM_CPU_HAS_64BIT_REGISTERS 1 239 | #else 240 | #define LZHAM_64BIT_POINTERS 0 241 | #define LZHAM_CPU_HAS_64BIT_REGISTERS 0 242 | #endif 243 | 244 | #define LZHAM_USE_UNALIGNED_INT_LOADS 0 245 | 246 | #if __BIG_ENDIAN__ 247 | #define LZHAM_BIG_ENDIAN_CPU 1 248 | #else 249 | #define LZHAM_LITTLE_ENDIAN_CPU 1 250 | #endif 251 | 252 | #define LZHAM_USE_GCC_ATOMIC_BUILTINS 0 253 | #define LZHAM_USE_WIN32_ATOMIC_FUNCTIONS 0 254 | 255 | #define LZHAM_RESTRICT 256 | #define LZHAM_FORCE_INLINE inline 257 | 258 | #define LZHAM_NOTE_UNUSED(x) (void)x 259 | 260 | #define LZHAM_PRIi64 PRIi64 261 | #define LZHAM_PRIu64 PRIu64 262 | #endif 263 | 264 | #if LZHAM_LITTLE_ENDIAN_CPU 265 | const bool c_lzham_little_endian_platform = true; 266 | #else 267 | const bool c_lzham_little_endian_platform = false; 268 | #endif 269 | 270 | const bool c_lzham_big_endian_platform = !c_lzham_little_endian_platform; 271 | 272 | #include 273 | #include 274 | #include 275 | #if !defined(__APPLE__) && !defined(__FreeBSD__) 276 | #include 277 | #endif 278 | #include 279 | #include 280 | #include 281 | #include 282 | #include 283 | 284 | #ifndef _MSC_VER 285 | #ifndef __STDC_FORMAT_MACROS 286 | #define __STDC_FORMAT_MACROS 287 | #endif 288 | // Needed for PRIi64 and PRIu64 289 | #include 290 | #endif 291 | 292 | #include "lzham.h" 293 | #include "lzham_config.h" 294 | #include "lzham_types.h" 295 | #include "lzham_assert.h" 296 | #include "lzham_platform.h" 297 | 298 | #include "lzham_helpers.h" 299 | #include "lzham_traits.h" 300 | #include "lzham_mem.h" 301 | #include "lzham_math.h" 302 | #include "lzham_utils.h" 303 | #include "lzham_vector.h" 304 | -------------------------------------------------------------------------------- /lzhamdecomp/lzham_decomp.h: -------------------------------------------------------------------------------- 1 | // File: lzham_decomp.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | #include "lzham.h" 5 | 6 | namespace lzham 7 | { 8 | void LZHAM_CDECL lzham_lib_set_memory_callbacks(lzham_realloc_func pRealloc, lzham_msize_func pMSize, void* pUser_data); 9 | 10 | lzham_decompress_state_ptr LZHAM_CDECL lzham_lib_decompress_init(const lzham_decompress_params *pParams); 11 | 12 | lzham_decompress_state_ptr LZHAM_CDECL lzham_lib_decompress_reinit(lzham_decompress_state_ptr pState, const lzham_decompress_params *pParams); 13 | 14 | lzham_uint32 LZHAM_CDECL lzham_lib_decompress_deinit(lzham_decompress_state_ptr pState); 15 | 16 | lzham_decompress_status_t LZHAM_CDECL lzham_lib_decompress( 17 | lzham_decompress_state_ptr pState, 18 | const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, 19 | lzham_uint8 *pOut_buf, size_t *pOut_buf_size, 20 | lzham_bool no_more_input_bytes_flag); 21 | 22 | lzham_decompress_status_t LZHAM_CDECL lzham_lib_decompress_memory(const lzham_decompress_params *pParams, 23 | lzham_uint8* pDst_buf, size_t *pDst_len, 24 | const lzham_uint8* pSrc_buf, size_t src_len, lzham_uint32 *pAdler32); 25 | 26 | int LZHAM_CDECL lzham_lib_z_inflateInit2(lzham_z_streamp pStream, int window_bits); 27 | int LZHAM_CDECL lzham_lib_z_inflateInit(lzham_z_streamp pStream); 28 | int LZHAM_CDECL lzham_lib_z_inflateReset(lzham_z_streamp pStream); 29 | int LZHAM_CDECL lzham_lib_z_inflate(lzham_z_streamp pStream, int flush); 30 | int LZHAM_CDECL lzham_lib_z_inflateEnd(lzham_z_streamp pStream); 31 | int LZHAM_CDECL lzham_lib_z_uncompress(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len); 32 | 33 | const char * LZHAM_CDECL lzham_lib_z_error(int err); 34 | lzham_z_ulong lzham_lib_z_adler32(lzham_z_ulong adler, const unsigned char *ptr, size_t buf_len); 35 | lzham_z_ulong LZHAM_CDECL lzham_lib_z_crc32(lzham_z_ulong crc, const lzham_uint8 *ptr, size_t buf_len); 36 | 37 | } // namespace lzham 38 | -------------------------------------------------------------------------------- /lzhamdecomp/lzham_helpers.h: -------------------------------------------------------------------------------- 1 | // File: lzham_helpers.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | 5 | #define LZHAM_NO_COPY_OR_ASSIGNMENT_OP(c) c(const c&); c& operator= (const c&); 6 | 7 | namespace lzham 8 | { 9 | namespace helpers 10 | { 11 | template struct rel_ops 12 | { 13 | friend inline bool operator!=(const T& x, const T& y) { return (!(x == y)); } 14 | friend inline bool operator> (const T& x, const T& y) { return (y < x); } 15 | friend inline bool operator<=(const T& x, const T& y) { return (!(y < x)); } 16 | friend inline bool operator>=(const T& x, const T& y) { return (!(x < y)); } 17 | }; 18 | 19 | template 20 | inline T* construct(T* p) 21 | { 22 | return new (static_cast(p)) T; 23 | } 24 | 25 | template 26 | inline T* construct(T* p, const U& init) 27 | { 28 | return new (static_cast(p)) T(init); 29 | } 30 | 31 | template 32 | inline void construct_array(T* p, uint n); 33 | 34 | template 35 | inline void construct_array(T* p, uint n, const U& init) 36 | { 37 | T* q = p + n; 38 | for ( ; p != q; ++p) 39 | new (static_cast(p)) T(init); 40 | } 41 | 42 | template 43 | inline void destruct(T* p) 44 | { 45 | LZHAM_NOTE_UNUSED(p); 46 | p->~T(); 47 | } 48 | 49 | template 50 | inline void destruct_array(T* p, uint n); 51 | 52 | } // namespace helpers 53 | 54 | } // namespace lzham 55 | -------------------------------------------------------------------------------- /lzhamdecomp/lzham_huffman_codes.cpp: -------------------------------------------------------------------------------- 1 | // File: huffman_codes.cpp 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #include "lzham_core.h" 4 | #include "lzham_huffman_codes.h" 5 | 6 | namespace lzham 7 | { 8 | void code_size_histogram::init(uint num_syms, const uint8* pCodesizes) 9 | { 10 | const uint8 *p = pCodesizes; 11 | 12 | for (uint i = num_syms >> 2; i; --i) 13 | { 14 | uint a = p[0]; 15 | uint b = p[1]; 16 | uint c = p[2]; 17 | uint d = p[3]; 18 | m_num_codes[a]++; 19 | m_num_codes[b]++; 20 | m_num_codes[c]++; 21 | m_num_codes[d]++; 22 | p += 4; 23 | } 24 | 25 | for (uint i = num_syms & 3; i; --i) 26 | m_num_codes[*p++]++; 27 | 28 | LZHAM_ASSERT(static_cast(p - pCodesizes) == num_syms); 29 | } 30 | 31 | struct sym_freq 32 | { 33 | uint m_freq; 34 | uint16 m_left; 35 | uint16 m_right; 36 | 37 | inline bool operator< (const sym_freq& other) const 38 | { 39 | return m_freq > other.m_freq; 40 | } 41 | }; 42 | 43 | static inline sym_freq* radix_sort_syms(uint num_syms, sym_freq* syms0, sym_freq* syms1) 44 | { 45 | const uint cMaxPasses = 2; 46 | uint hist[256 * cMaxPasses]; 47 | 48 | memset(hist, 0, sizeof(hist[0]) * 256 * cMaxPasses); 49 | 50 | { 51 | sym_freq* p = syms0; 52 | sym_freq* q = syms0 + (num_syms >> 1) * 2; 53 | 54 | for ( ; p != q; p += 2) 55 | { 56 | const uint freq0 = p[0].m_freq; 57 | const uint freq1 = p[1].m_freq; 58 | 59 | hist[ freq0 & 0xFF]++; 60 | hist[256 + ((freq0 >> 8) & 0xFF)]++; 61 | 62 | hist[ freq1 & 0xFF]++; 63 | hist[256 + ((freq1 >> 8) & 0xFF)]++; 64 | } 65 | 66 | if (num_syms & 1) 67 | { 68 | const uint freq = p->m_freq; 69 | 70 | hist[ freq & 0xFF]++; 71 | hist[256 + ((freq >> 8) & 0xFF)]++; 72 | } 73 | } 74 | 75 | sym_freq* pCur_syms = syms0; 76 | sym_freq* pNew_syms = syms1; 77 | 78 | const uint total_passes = (hist[256] == num_syms) ? 1 : cMaxPasses; 79 | 80 | for (uint pass = 0; pass < total_passes; pass++) 81 | { 82 | const uint* pHist = &hist[pass << 8]; 83 | 84 | uint offsets[256]; 85 | 86 | uint cur_ofs = 0; 87 | for (uint i = 0; i < 256; i += 2) 88 | { 89 | offsets[i] = cur_ofs; 90 | cur_ofs += pHist[i]; 91 | 92 | offsets[i+1] = cur_ofs; 93 | cur_ofs += pHist[i+1]; 94 | } 95 | 96 | const uint pass_shift = pass << 3; 97 | 98 | sym_freq* p = pCur_syms; 99 | sym_freq* q = pCur_syms + (num_syms >> 1) * 2; 100 | 101 | for ( ; p != q; p += 2) 102 | { 103 | uint c0 = p[0].m_freq; 104 | uint c1 = p[1].m_freq; 105 | 106 | if (pass) 107 | { 108 | c0 >>= 8; 109 | c1 >>= 8; 110 | } 111 | 112 | c0 &= 0xFF; 113 | c1 &= 0xFF; 114 | 115 | if (c0 == c1) 116 | { 117 | uint dst_offset0 = offsets[c0]; 118 | 119 | offsets[c0] = dst_offset0 + 2; 120 | 121 | pNew_syms[dst_offset0] = p[0]; 122 | pNew_syms[dst_offset0 + 1] = p[1]; 123 | } 124 | else 125 | { 126 | uint dst_offset0 = offsets[c0]++; 127 | uint dst_offset1 = offsets[c1]++; 128 | 129 | pNew_syms[dst_offset0] = p[0]; 130 | pNew_syms[dst_offset1] = p[1]; 131 | } 132 | } 133 | 134 | if (num_syms & 1) 135 | { 136 | uint c = ((p->m_freq) >> pass_shift) & 0xFF; 137 | 138 | uint dst_offset = offsets[c]; 139 | offsets[c] = dst_offset + 1; 140 | 141 | pNew_syms[dst_offset] = *p; 142 | } 143 | 144 | sym_freq* t = pCur_syms; 145 | pCur_syms = pNew_syms; 146 | pNew_syms = t; 147 | } 148 | 149 | #if LZHAM_ASSERTS_ENABLED 150 | uint prev_freq = 0; 151 | for (uint i = 0; i < num_syms; i++) 152 | { 153 | LZHAM_ASSERT(!(pCur_syms[i].m_freq < prev_freq)); 154 | prev_freq = pCur_syms[i].m_freq; 155 | } 156 | #endif 157 | 158 | return pCur_syms; 159 | } 160 | 161 | struct huffman_work_tables 162 | { 163 | enum { cMaxInternalNodes = cHuffmanMaxSupportedSyms }; 164 | 165 | sym_freq syms0[cHuffmanMaxSupportedSyms + 1 + cMaxInternalNodes]; 166 | sym_freq syms1[cHuffmanMaxSupportedSyms + 1 + cMaxInternalNodes]; 167 | 168 | #if !USE_CALCULATE_MINIMUM_REDUNDANCY 169 | uint16 queue[cMaxInternalNodes]; 170 | #endif 171 | }; 172 | 173 | uint get_generate_huffman_codes_table_size() 174 | { 175 | return sizeof(huffman_work_tables); 176 | } 177 | 178 | // calculate_minimum_redundancy() written by Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk November 1996. 179 | static void calculate_minimum_redundancy(int A[], int n) 180 | { 181 | int root; /* next root node to be used */ 182 | int leaf; /* next leaf to be used */ 183 | int next; /* next value to be assigned */ 184 | int avbl; /* number of available nodes */ 185 | int used; /* number of internal nodes */ 186 | int dpth; /* current depth of leaves */ 187 | 188 | /* check for pathological cases */ 189 | if (n==0) { return; } 190 | if (n==1) { A[0] = 0; return; } 191 | 192 | /* first pass, left to right, setting parent pointers */ 193 | A[0] += A[1]; root = 0; leaf = 2; 194 | for (next=1; next < n-1; next++) { 195 | /* select first item for a pairing */ 196 | if (leaf>=n || A[root]=n || (root=0; next--) 211 | A[next] = A[A[next]]+1; 212 | 213 | /* third pass, right to left, setting leaf depths */ 214 | avbl = 1; used = dpth = 0; root = n-2; next = n-1; 215 | while (avbl>0) { 216 | while (root>=0 && A[root]==dpth) { 217 | used++; root--; 218 | } 219 | while (avbl>used) { 220 | A[next--] = dpth; avbl--; 221 | } 222 | avbl = 2*used; dpth++; used = 0; 223 | } 224 | } 225 | 226 | bool generate_huffman_codes(void* pContext, uint num_syms, const uint16* pFreq, uint8* pCodesizes, uint& max_code_size, uint& total_freq_ret, code_size_histogram &code_size_hist) 227 | { 228 | if ((!num_syms) || (num_syms > cHuffmanMaxSupportedSyms)) 229 | return false; 230 | 231 | huffman_work_tables& state = *static_cast(pContext);; 232 | 233 | uint max_freq = 0; 234 | uint total_freq = 0; 235 | 236 | uint num_used_syms = 0; 237 | for (uint i = 0; i < num_syms; i++) 238 | { 239 | uint freq = pFreq[i]; 240 | 241 | if (!freq) 242 | pCodesizes[i] = 0; 243 | else 244 | { 245 | total_freq += freq; 246 | max_freq = math::maximum(max_freq, freq); 247 | 248 | sym_freq& sf = state.syms0[num_used_syms]; 249 | sf.m_left = (uint16)i; 250 | sf.m_right = cUINT16_MAX; 251 | sf.m_freq = freq; 252 | num_used_syms++; 253 | } 254 | } 255 | 256 | total_freq_ret = total_freq; 257 | 258 | if (num_used_syms == 1) 259 | { 260 | pCodesizes[state.syms0[0].m_left] = 1; 261 | return true; 262 | } 263 | 264 | sym_freq* syms = radix_sort_syms(num_used_syms, state.syms0, state.syms1); 265 | 266 | int x[cHuffmanMaxSupportedSyms]; 267 | for (uint i = 0; i < num_used_syms; i++) 268 | x[i] = syms[i].m_freq; 269 | 270 | calculate_minimum_redundancy(x, num_used_syms); 271 | 272 | uint max_len = 0; 273 | for (uint i = 0; i < num_used_syms; i++) 274 | { 275 | uint len = x[i]; 276 | max_len = math::maximum(len, max_len); 277 | code_size_hist.m_num_codes[LZHAM_MIN(len, (uint)code_size_histogram::cMaxUnlimitedHuffCodeSize)]++; 278 | pCodesizes[syms[i].m_left] = static_cast(len); 279 | } 280 | max_code_size = max_len; 281 | 282 | return true; 283 | } 284 | 285 | } // namespace lzham 286 | 287 | -------------------------------------------------------------------------------- /lzhamdecomp/lzham_huffman_codes.h: -------------------------------------------------------------------------------- 1 | // File: lzham_huffman_codes.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | 5 | namespace lzham 6 | { 7 | //const uint cHuffmanMaxSupportedSyms = 600; 8 | const uint cHuffmanMaxSupportedSyms = 1024; 9 | 10 | const uint cMaxExpectedHuffCodeSize = 16; 11 | 12 | struct code_size_histogram 13 | { 14 | enum { cMaxUnlimitedHuffCodeSize = 32 }; 15 | uint m_num_codes[cMaxUnlimitedHuffCodeSize + 1]; 16 | 17 | void clear() { utils::zero_object(m_num_codes); } 18 | 19 | void init(uint num_syms, const uint8* pCodesizes); 20 | 21 | inline void init(uint code_size0, uint total_syms0, uint code_size1, uint total_syms1) 22 | { 23 | m_num_codes[code_size0] += total_syms0; 24 | m_num_codes[code_size1] += total_syms1; 25 | } 26 | }; 27 | 28 | uint get_generate_huffman_codes_table_size(); 29 | 30 | bool generate_huffman_codes(void* pContext, uint num_syms, const uint16* pFreq, uint8* pCodesizes, uint& max_code_size, uint& total_freq_ret, code_size_histogram &code_size_hist); 31 | 32 | } // namespace lzham 33 | -------------------------------------------------------------------------------- /lzhamdecomp/lzham_lzdecompbase.cpp: -------------------------------------------------------------------------------- 1 | // File: lzham_lzdecompbase.cpp 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #include "lzham_core.h" 4 | #include "lzham_lzdecompbase.h" 5 | 6 | namespace lzham 7 | { 8 | // Keep in sync with LZHAM_DEFAULT_ADAPT_RATE, and LZHAM_DEFAULT_TABLE_UPDATE_RATE, etc. 9 | table_update_settings g_table_update_settings[] = 10 | { 11 | { 4, 32 }, // crazy slow! 12 | { 5, 33 }, 13 | { 6, 34 }, 14 | { 7, 35 }, 15 | { 8, 36 }, 16 | 17 | { 16, 48 }, 18 | { 32, 72 }, 19 | { 64, 64 }, // codec's internal default 20 | { 98, 80 }, 21 | { 128, 96 }, 22 | 23 | { 192, 112 }, 24 | { 256, 128 }, 25 | { 512, 128+16*2 }, 26 | { 1024, 128+16*4 }, 27 | { 2048, 128+16*6 }, 28 | 29 | { 2048, 128+16*8 }, 30 | { 2048, 128+16*10 }, 31 | { 2048, 128+16*12 }, 32 | { 2048, 128+16*14 }, 33 | { 2048, 128+16*16 } 34 | }; 35 | 36 | uint CLZDecompBase::m_lzx_position_base[CLZDecompBase::cLZXMaxPositionSlots] = 37 | { 38 | 0x0, 0x1, 0x2, 0x3, 0x4, 0x6, 0x8, 0xC, 0x10, 0x18, 0x20, 0x30, 0x40, 0x60, 0x80, 0xC0, 39 | 0x100, 0x180, 0x200, 0x300, 0x400, 0x600, 0x800, 0xC00, 0x1000, 0x1800, 0x2000, 0x3000, 0x4000, 0x6000, 0x8000, 0xC000, 40 | 0x10000, 0x18000, 0x20000, 0x30000, 0x40000, 0x60000, 0x80000, 0xC0000, 0x100000, 0x180000, 0x200000, 0x300000, 0x400000, 0x600000, 0x800000, 0xC00000, 41 | 0x1000000, 0x1800000, 0x2000000, 0x3000000, 0x4000000, 0x6000000, 0x8000000, 0xA000000, 0xC000000, 0xE000000, 0x10000000, 0x12000000, 0x14000000, 0x16000000, 0x18000000, 0x1A000000, 42 | 0x1C000000, 0x1E000000, 0x20000000, 0x22000000, 0x24000000, 0x26000000, 0x28000000, 0x2A000000, 0x2C000000, 0x2E000000, 0x30000000, 0x32000000, 0x34000000, 0x36000000, 0x38000000, 0x3A000000, 43 | 0x3C000000, 0x3E000000, 0x40000000, 0x42000000, 0x44000000, 0x46000000, 0x48000000, 0x4A000000, 0x4C000000, 0x4E000000, 0x50000000, 0x52000000, 0x54000000, 0x56000000, 0x58000000, 0x5A000000, 44 | 0x5C000000, 0x5E000000, 0x60000000, 0x62000000, 0x64000000, 0x66000000, 0x68000000, 0x6A000000, 0x6C000000, 0x6E000000, 0x70000000, 0x72000000, 0x74000000, 0x76000000, 0x78000000, 0x7A000000, 45 | 0x7C000000, 0x7E000000, 0x80000000, 0x82000000, 0x84000000, 0x86000000, 0x88000000, 0x8A000000, 0x8C000000, 0x8E000000, 0x90000000, 0x92000000, 0x94000000, 0x96000000, 0x98000000, 0x9A000000, 46 | }; 47 | 48 | uint CLZDecompBase::m_lzx_position_extra_mask[CLZDecompBase::cLZXMaxPositionSlots] = 49 | { 50 | 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x3, 0x3, 0x7, 0x7, 0xF, 0xF, 0x1F, 0x1F, 0x3F, 0x3F, 51 | 0x7F, 0x7F, 0xFF, 0xFF, 0x1FF, 0x1FF, 0x3FF, 0x3FF, 0x7FF, 0x7FF, 0xFFF, 0xFFF, 0x1FFF, 0x1FFF, 0x3FFF, 0x3FFF, 52 | 0x7FFF, 0x7FFF, 0xFFFF, 0xFFFF, 0x1FFFF, 0x1FFFF, 0x3FFFF, 0x3FFFF, 0x7FFFF, 0x7FFFF, 0xFFFFF, 0xFFFFF, 0x1FFFFF, 0x1FFFFF, 0x3FFFFF, 0x3FFFFF, 53 | 0x7FFFFF, 0x7FFFFF, 0xFFFFFF, 0xFFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 54 | 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 55 | 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 56 | 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 57 | 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF 58 | }; 59 | 60 | uint8 CLZDecompBase::m_lzx_position_extra_bits[CLZDecompBase::cLZXMaxPositionSlots] = 61 | { 62 | 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x2, 0x2, 0x3, 0x3, 0x4, 0x4, 0x5, 0x5, 0x6, 0x6, 63 | 0x7, 0x7, 0x8, 0x8, 0x9, 0x9, 0xA, 0xA, 0xB, 0xB, 0xC, 0xC, 0xD, 0xD, 0xE, 0xE, 64 | 0xF, 0xF, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, 0x15, 0x16, 0x16, 65 | 0x17, 0x17, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 66 | 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 67 | 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 68 | 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 69 | 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 70 | }; 71 | 72 | static const uint8 g_num_lzx_position_slots[] = { 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 58, 66 }; 73 | 74 | void CLZDecompBase::init_position_slots(uint dict_size_log2) 75 | { 76 | LZHAM_ASSERT(dict_size_log2 >= LZHAM_MIN_DICT_SIZE_LOG2); 77 | LZHAM_ASSERT(dict_size_log2 <= LZHAM_MAX_DICT_SIZE_LOG2_X64); 78 | LZHAM_ASSERT((sizeof(g_table_update_settings) / sizeof(g_table_update_settings[0])) == LZHAM_FASTEST_TABLE_UPDATE_RATE); 79 | 80 | //for (dict_size_log2 = LZHAM_MIN_DICT_SIZE_LOG2; dict_size_log2 <= LZHAM_MAX_DICT_SIZE_LOG2_X64; dict_size_log2++) { 81 | 82 | m_dict_size_log2 = dict_size_log2; 83 | m_dict_size = 1U << dict_size_log2; 84 | m_num_lzx_slots = g_num_lzx_position_slots[dict_size_log2 - LZHAM_MIN_DICT_SIZE_LOG2]; 85 | 86 | #if 0 87 | int i, j; 88 | for (i = 0, j = 0; i < cLZXMaxPositionSlots; i += 2) 89 | { 90 | m_lzx_position_extra_bits[i] = (uint8)j; 91 | m_lzx_position_extra_bits[i + 1] = (uint8)j; 92 | 93 | if ((i != 0) && (j < 25)) 94 | j++; 95 | } 96 | 97 | for (i = 0, j = 0; i < cLZXMaxPositionSlots; i++) 98 | { 99 | m_lzx_position_base[i] = j; 100 | m_lzx_position_extra_mask[i] = (1 << m_lzx_position_extra_bits[i]) - 1; 101 | j += (1 << m_lzx_position_extra_bits[i]); 102 | } 103 | 104 | for (uint i = 0; i < cLZXMaxPositionSlots; i++) 105 | { 106 | printf("0x%X, ", m_lzx_position_base[i]); 107 | if ((i & 15) == 15) printf("\n"); 108 | } 109 | #endif 110 | 111 | #if 0 112 | m_num_lzx_slots = 0; 113 | 114 | const uint largest_dist = m_dict_size - 1; 115 | for (i = 0; i < cLZXMaxPositionSlots; i++) 116 | { 117 | if ( (largest_dist >= m_lzx_position_base[i]) && 118 | (largest_dist < (m_lzx_position_base[i] + (1 << m_lzx_position_extra_bits[i])) ) ) 119 | { 120 | m_num_lzx_slots = i + 1; 121 | break; 122 | } 123 | } 124 | 125 | LZHAM_VERIFY(m_num_lzx_slots); 126 | #endif 127 | 128 | //printf("%u, ", m_num_lzx_slots); } 129 | } 130 | 131 | } //namespace lzham 132 | -------------------------------------------------------------------------------- /lzhamdecomp/lzham_lzdecompbase.h: -------------------------------------------------------------------------------- 1 | // File: lzham_lzdecompbase.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | 5 | //#define LZHAM_LZDEBUG 6 | 7 | #define LZHAM_IS_MATCH_MODEL_INDEX(cur_state) (cur_state) 8 | 9 | namespace lzham 10 | { 11 | struct table_update_settings 12 | { 13 | uint16 m_max_update_interval; 14 | uint16 m_slow_rate; 15 | }; 16 | extern table_update_settings g_table_update_settings[]; 17 | 18 | struct CLZDecompBase 19 | { 20 | enum 21 | { 22 | cMinMatchLen = 2U, 23 | cMaxMatchLen = 257U, 24 | 25 | cMaxHugeMatchLen = 65536, 26 | 27 | cMinDictSizeLog2 = 15, 28 | cMaxDictSizeLog2 = 29, 29 | 30 | cMatchHistSize = 4, 31 | cMaxLen2MatchDist = 2047 32 | }; 33 | 34 | enum 35 | { 36 | cLZXNumSecondaryLengths = 249, 37 | 38 | cNumHugeMatchCodes = 1, 39 | cMaxHugeMatchCodeBits = 16, 40 | 41 | cLZXNumSpecialLengths = 2, 42 | 43 | cLZXLowestUsableMatchSlot = 1, 44 | cLZXMaxPositionSlots = 128 45 | }; 46 | 47 | enum 48 | { 49 | cLZXSpecialCodeEndOfBlockCode = 0, 50 | cLZXSpecialCodePartialStateReset = 1 51 | }; 52 | 53 | enum 54 | { 55 | cLZHAMDebugSyncMarkerValue = 666, 56 | cLZHAMDebugSyncMarkerBits = 12 57 | }; 58 | 59 | enum 60 | { 61 | cBlockHeaderBits = 2, 62 | cBlockCheckBits = 4, 63 | cBlockFlushTypeBits = 2, 64 | 65 | cSyncBlock = 0, 66 | cCompBlock = 1, 67 | cRawBlock = 2, 68 | cEOFBlock = 3 69 | }; 70 | 71 | enum 72 | { 73 | cNumStates = 12, 74 | cNumLitStates = 7, 75 | }; 76 | 77 | uint m_dict_size_log2; 78 | uint m_dict_size; 79 | 80 | uint m_num_lzx_slots; 81 | 82 | static uint m_lzx_position_base[cLZXMaxPositionSlots]; 83 | static uint m_lzx_position_extra_mask[cLZXMaxPositionSlots]; 84 | static uint8 m_lzx_position_extra_bits[cLZXMaxPositionSlots]; 85 | 86 | void init_position_slots(uint dict_size_log2); 87 | }; 88 | 89 | } // namespace lzham 90 | -------------------------------------------------------------------------------- /lzhamdecomp/lzham_math.h: -------------------------------------------------------------------------------- 1 | // File: lzham_math.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | 5 | #if defined(LZHAM_USE_MSVC_INTRINSICS) && !defined(__MINGW32__) 6 | #include 7 | #if defined(_MSC_VER) 8 | #pragma intrinsic(_BitScanReverse) 9 | #endif 10 | #endif 11 | 12 | namespace lzham 13 | { 14 | namespace math 15 | { 16 | // Yes I know these should probably be pass by ref, not val: 17 | // http://www.stepanovpapers.com/notes.pdf 18 | // Just don't use them on non-simple (non built-in) types! 19 | template inline T minimum(T a, T b) { return (a < b) ? a : b; } 20 | 21 | template inline T minimum(T a, T b, T c) { return minimum(minimum(a, b), c); } 22 | 23 | template inline T maximum(T a, T b) { return (a > b) ? a : b; } 24 | 25 | template inline T maximum(T a, T b, T c) { return maximum(maximum(a, b), c); } 26 | 27 | template inline T clamp(T value, T low, T high) { return (value < low) ? low : ((value > high) ? high : value); } 28 | 29 | inline bool is_power_of_2(uint32 x) { return x && ((x & (x - 1U)) == 0U); } 30 | inline bool is_power_of_2(uint64 x) { return x && ((x & (x - 1U)) == 0U); } 31 | 32 | template inline T align_up_pointer(T p, uint alignment) 33 | { 34 | LZHAM_ASSERT(is_power_of_2(alignment)); 35 | ptr_bits_t q = reinterpret_cast(p); 36 | q = (q + alignment - 1) & (~((uint_ptr)alignment - 1)); 37 | return reinterpret_cast(q); 38 | } 39 | 40 | // From "Hackers Delight" 41 | // val remains unchanged if it is already a power of 2. 42 | inline uint32 next_pow2(uint32 val) 43 | { 44 | val--; 45 | val |= val >> 16; 46 | val |= val >> 8; 47 | val |= val >> 4; 48 | val |= val >> 2; 49 | val |= val >> 1; 50 | return val + 1; 51 | } 52 | 53 | // val remains unchanged if it is already a power of 2. 54 | inline uint64 next_pow2(uint64 val) 55 | { 56 | val--; 57 | val |= val >> 32; 58 | val |= val >> 16; 59 | val |= val >> 8; 60 | val |= val >> 4; 61 | val |= val >> 2; 62 | val |= val >> 1; 63 | return val + 1; 64 | } 65 | 66 | inline uint floor_log2i(uint v) 67 | { 68 | uint l = 0; 69 | while (v > 1U) 70 | { 71 | v >>= 1; 72 | l++; 73 | } 74 | return l; 75 | } 76 | 77 | inline uint ceil_log2i(uint v) 78 | { 79 | uint l = floor_log2i(v); 80 | if ((l != cIntBits) && (v > (1U << l))) 81 | l++; 82 | return l; 83 | } 84 | 85 | // Returns the total number of bits needed to encode v. 86 | inline uint total_bits(uint v) 87 | { 88 | unsigned long l = 0; 89 | #if defined(__MINGW32__) 90 | if (v) 91 | { 92 | l = 32 -__builtin_clz(v); 93 | } 94 | #elif defined(LZHAM_USE_MSVC_INTRINSICS) 95 | if (_BitScanReverse(&l, v)) 96 | { 97 | l++; 98 | } 99 | else 100 | { 101 | l = 0; 102 | } 103 | #else 104 | while (v > 0U) 105 | { 106 | v >>= 1; 107 | l++; 108 | } 109 | #endif 110 | return static_cast(l); 111 | } 112 | 113 | inline uint compute_mask_size(uint x) 114 | { 115 | uint l = 0; 116 | while (x) 117 | { 118 | x &= (x - 1); 119 | l++; 120 | } 121 | return l; 122 | } 123 | 124 | inline uint compute_mask_shift(uint x) 125 | { 126 | if (!x) 127 | return 0; 128 | 129 | uint l = 0; 130 | while ((x & 1) == 0) 131 | { 132 | x >>= 1; 133 | l++; 134 | } 135 | 136 | return l; 137 | } 138 | 139 | } 140 | 141 | } // namespace lzham 142 | 143 | -------------------------------------------------------------------------------- /lzhamdecomp/lzham_mem.h: -------------------------------------------------------------------------------- 1 | // File: lzham_mem.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | 5 | namespace lzham 6 | { 7 | typedef void *lzham_malloc_context; 8 | 9 | lzham_malloc_context lzham_create_malloc_context(uint arena_size); 10 | void lzham_destroy_malloc_context(lzham_malloc_context context); 11 | 12 | void* lzham_malloc(lzham_malloc_context context, size_t size, size_t* pActual_size = NULL); 13 | void* lzham_realloc(lzham_malloc_context context, void* p, size_t size, size_t* pActual_size = NULL, bool movable = true); 14 | void lzham_free(lzham_malloc_context context, void* p); 15 | size_t lzham_msize(lzham_malloc_context context, void* p); 16 | 17 | template 18 | inline T* lzham_new(lzham_malloc_context context) 19 | { 20 | T* p = static_cast(lzham_malloc(context, sizeof(T))); 21 | if (!p) return NULL; 22 | if (LZHAM_IS_SCALAR_TYPE(T)) 23 | return p; 24 | return helpers::construct(p); 25 | } 26 | 27 | template 28 | inline T* lzham_new(lzham_malloc_context context, const A& init0) 29 | { 30 | T* p = static_cast(lzham_malloc(context, sizeof(T))); 31 | if (!p) return NULL; 32 | return new (static_cast(p)) T(init0); 33 | } 34 | 35 | template 36 | inline T* lzham_new(lzham_malloc_context context, const A& init0, const B& init1) 37 | { 38 | T* p = static_cast(lzham_malloc(context, sizeof(T))); 39 | if (!p) return NULL; 40 | return new (static_cast(p)) T(init0, init1); 41 | } 42 | 43 | template 44 | inline T* lzham_new(lzham_malloc_context context, const A& init0, const B& init1, const C& init2) 45 | { 46 | T* p = static_cast(lzham_malloc(context, sizeof(T))); 47 | if (!p) return NULL; 48 | return new (static_cast(p)) T(init0, init1, init2); 49 | } 50 | 51 | template 52 | inline T* lzham_new(lzham_malloc_context context, const A& init0, const B& init1, const C& init2, const D& init3) 53 | { 54 | T* p = static_cast(lzham_malloc(context, sizeof(T))); 55 | if (!p) return NULL; 56 | return new (static_cast(p)) T(init0, init1, init2, init3); 57 | } 58 | 59 | template 60 | inline T* lzham_new_array(lzham_malloc_context context, uint32 num) 61 | { 62 | if (!num) num = 1; 63 | 64 | uint8* q = static_cast(lzham_malloc(context, LZHAM_MIN_ALLOC_ALIGNMENT + sizeof(T) * num)); 65 | if (!q) 66 | return NULL; 67 | 68 | T* p = reinterpret_cast(q + LZHAM_MIN_ALLOC_ALIGNMENT); 69 | 70 | reinterpret_cast(p)[-1] = num; 71 | reinterpret_cast(p)[-2] = ~num; 72 | 73 | if (!LZHAM_IS_SCALAR_TYPE(T)) 74 | { 75 | helpers::construct_array(p, num); 76 | } 77 | return p; 78 | } 79 | 80 | template 81 | inline void lzham_delete(lzham_malloc_context context, T* p) 82 | { 83 | if (p) 84 | { 85 | if (!LZHAM_IS_SCALAR_TYPE(T)) 86 | { 87 | helpers::destruct(p); 88 | } 89 | lzham_free(context, p); 90 | } 91 | } 92 | 93 | template 94 | inline void lzham_delete_array(lzham_malloc_context context, T* p) 95 | { 96 | if (p) 97 | { 98 | const uint32 num = reinterpret_cast(p)[-1]; 99 | const uint32 num_check = reinterpret_cast(p)[-2]; 100 | LZHAM_ASSERT(num && (num == ~num_check)); 101 | if (num == ~num_check) 102 | { 103 | if (!LZHAM_IS_SCALAR_TYPE(T)) 104 | { 105 | helpers::destruct_array(p, num); 106 | } 107 | 108 | lzham_free(context, reinterpret_cast(p) - LZHAM_MIN_ALLOC_ALIGNMENT); 109 | } 110 | } 111 | } 112 | 113 | void lzham_print_mem_stats(lzham_malloc_context context); 114 | 115 | } // namespace lzham 116 | -------------------------------------------------------------------------------- /lzhamdecomp/lzham_platform.cpp: -------------------------------------------------------------------------------- 1 | // File: platform.cpp 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #include "lzham_core.h" 4 | #include "lzham_timer.h" 5 | #include 6 | 7 | #if LZHAM_PLATFORM_X360 8 | #include 9 | #endif 10 | 11 | #define LZHAM_FORCE_DEBUGGER_PRESENT 0 12 | 13 | #ifndef _MSC_VER 14 | int sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...) 15 | { 16 | if (!sizeOfBuffer) 17 | return 0; 18 | 19 | va_list args; 20 | va_start(args, format); 21 | int c = vsnprintf(buffer, sizeOfBuffer, format, args); 22 | va_end(args); 23 | 24 | buffer[sizeOfBuffer - 1] = '\0'; 25 | 26 | if (c < 0) 27 | return static_cast(sizeOfBuffer - 1); 28 | 29 | return LZHAM_MIN(c, (int)sizeOfBuffer - 1); 30 | } 31 | int vsprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, va_list args) 32 | { 33 | if (!sizeOfBuffer) 34 | return 0; 35 | 36 | int c = vsnprintf(buffer, sizeOfBuffer, format, args); 37 | 38 | buffer[sizeOfBuffer - 1] = '\0'; 39 | 40 | if (c < 0) 41 | return static_cast(sizeOfBuffer - 1); 42 | 43 | return LZHAM_MIN(c, (int)sizeOfBuffer - 1); 44 | } 45 | #endif // __GNUC__ 46 | 47 | bool lzham_is_debugger_present(void) 48 | { 49 | #if LZHAM_PLATFORM_X360 50 | return DmIsDebuggerPresent() != 0; 51 | #elif LZHAM_USE_WIN32_API 52 | return IsDebuggerPresent() != 0; 53 | #elif LZHAM_FORCE_DEBUGGER_PRESENT 54 | return true; 55 | #else 56 | return false; 57 | #endif 58 | } 59 | 60 | void lzham_debug_break(void) 61 | { 62 | #if LZHAM_USE_WIN32_API 63 | DebugBreak(); 64 | #elif (TARGET_OS_MAC == 1) && (TARGET_IPHONE_SIMULATOR == 0) && (TARGET_OS_IPHONE == 0) 65 | // __asm {int 3} 66 | // __asm("int $3") 67 | assert(0); 68 | #else 69 | assert(0); 70 | #endif 71 | } 72 | 73 | void lzham_output_debug_string(const char* p) 74 | { 75 | LZHAM_NOTE_UNUSED(p); 76 | #if LZHAM_USE_WIN32_API 77 | OutputDebugStringA(p); 78 | #else 79 | fputs(p, stderr); 80 | #endif 81 | } 82 | 83 | #if LZHAM_BUFFERED_PRINTF 84 | #include 85 | // This stuff was a quick hack only intended for debugging/development. 86 | namespace lzham 87 | { 88 | struct buffered_str 89 | { 90 | enum { cBufSize = 256 }; 91 | char m_buf[cBufSize]; 92 | }; 93 | 94 | static std::vector g_buffered_strings; 95 | static volatile long g_buffered_string_locked; 96 | 97 | static void lock_buffered_strings() 98 | { 99 | while (atomic_exchange32(&g_buffered_string_locked, 1) == 1) 100 | { 101 | lzham_yield_processor(); 102 | lzham_yield_processor(); 103 | lzham_yield_processor(); 104 | lzham_yield_processor(); 105 | } 106 | 107 | LZHAM_MEMORY_IMPORT_BARRIER 108 | } 109 | 110 | static void unlock_buffered_strings() 111 | { 112 | LZHAM_MEMORY_EXPORT_BARRIER 113 | 114 | atomic_exchange32(&g_buffered_string_locked, 0); 115 | } 116 | 117 | void lzham_buffered_printf(const char *format, ...) 118 | { 119 | format; 120 | 121 | char buf[lzham::buffered_str::cBufSize]; 122 | 123 | va_list args; 124 | va_start(args, format); 125 | vsnprintf_s(buf, sizeof(buf), sizeof(buf), format, args); 126 | va_end(args); 127 | 128 | buf[sizeof(buf) - 1] = '\0'; 129 | 130 | lzham::lock_buffered_strings(); 131 | 132 | if (!lzham::g_buffered_strings.capacity()) 133 | { 134 | lzham::g_buffered_strings.reserve(2048); 135 | } 136 | 137 | lzham::g_buffered_strings.resize(lzham::g_buffered_strings.size() + 1); 138 | memcpy(lzham::g_buffered_strings.back().m_buf, buf, sizeof(buf)); 139 | 140 | lzham::unlock_buffered_strings(); 141 | } 142 | 143 | void lzham_flush_buffered_printf() 144 | { 145 | lzham::lock_buffered_strings(); 146 | 147 | for (lzham::uint i = 0; i < lzham::g_buffered_strings.size(); i++) 148 | { 149 | printf("%s", lzham::g_buffered_strings[i].m_buf); 150 | } 151 | 152 | lzham::g_buffered_strings.resize(0); 153 | 154 | lzham::unlock_buffered_strings(); 155 | } 156 | 157 | } // namespace lzham 158 | #endif 159 | 160 | -------------------------------------------------------------------------------- /lzhamdecomp/lzham_prefix_coding.h: -------------------------------------------------------------------------------- 1 | // File: lzham_prefix_coding.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | #include "lzham_huffman_codes.h" 5 | 6 | namespace lzham 7 | { 8 | namespace prefix_coding 9 | { 10 | const uint cMaxSupportedSyms = 1024; 11 | 12 | // This value can be tuned for a specific CPU. 13 | const uint cMaxTableBits = 11; 14 | 15 | bool limit_max_code_size(uint num_syms, uint8* pCodesizes, uint max_code_size); 16 | 17 | bool generate_codes(uint num_syms, const uint8* pCodesizes, uint16* pCodes); 18 | 19 | class decoder_tables 20 | { 21 | public: 22 | inline decoder_tables(lzham_malloc_context malloc_context) : 23 | m_malloc_context(malloc_context), 24 | m_table_shift(0), m_table_max_code(0), m_decode_start_code_size(0), m_cur_lookup_size(0), m_lookup(NULL), m_cur_sorted_symbol_order_size(0), m_sorted_symbol_order(NULL) 25 | { 26 | } 27 | 28 | inline decoder_tables(const decoder_tables& other) : 29 | m_malloc_context(other.m_malloc_context), 30 | m_table_shift(0), m_table_max_code(0), m_decode_start_code_size(0), m_cur_lookup_size(0), m_lookup(NULL), m_cur_sorted_symbol_order_size(0), m_sorted_symbol_order(NULL) 31 | { 32 | *this = other; 33 | } 34 | 35 | inline decoder_tables& operator= (const decoder_tables& rhs) 36 | { 37 | assign(rhs); 38 | return *this; 39 | } 40 | 41 | inline bool assign(const decoder_tables& rhs) 42 | { 43 | if (this == &rhs) 44 | return true; 45 | 46 | if (m_malloc_context != rhs.m_malloc_context) 47 | { 48 | clear(); 49 | 50 | m_malloc_context = rhs.m_malloc_context; 51 | } 52 | 53 | uint32* pCur_lookup = m_lookup; 54 | uint16* pCur_sorted_symbol_order = m_sorted_symbol_order; 55 | 56 | memcpy(this, &rhs, sizeof(*this)); 57 | 58 | if ((pCur_lookup) && (pCur_sorted_symbol_order) && (rhs.m_cur_lookup_size == m_cur_lookup_size) && (rhs.m_cur_sorted_symbol_order_size == m_cur_sorted_symbol_order_size)) 59 | { 60 | m_lookup = pCur_lookup; 61 | m_sorted_symbol_order = pCur_sorted_symbol_order; 62 | 63 | memcpy(m_lookup, rhs.m_lookup, sizeof(m_lookup[0]) * m_cur_lookup_size); 64 | memcpy(m_sorted_symbol_order, rhs.m_sorted_symbol_order, sizeof(m_sorted_symbol_order[0]) * m_cur_sorted_symbol_order_size); 65 | } 66 | else 67 | { 68 | lzham_delete_array(m_malloc_context, pCur_lookup); 69 | m_lookup = NULL; 70 | 71 | if (rhs.m_lookup) 72 | { 73 | m_lookup = lzham_new_array(m_malloc_context, m_cur_lookup_size); 74 | if (!m_lookup) 75 | return false; 76 | memcpy(m_lookup, rhs.m_lookup, sizeof(m_lookup[0]) * m_cur_lookup_size); 77 | } 78 | 79 | lzham_delete_array(m_malloc_context, pCur_sorted_symbol_order); 80 | m_sorted_symbol_order = NULL; 81 | 82 | if (rhs.m_sorted_symbol_order) 83 | { 84 | m_sorted_symbol_order = lzham_new_array(m_malloc_context, m_cur_sorted_symbol_order_size); 85 | if (!m_sorted_symbol_order) 86 | return false; 87 | memcpy(m_sorted_symbol_order, rhs.m_sorted_symbol_order, sizeof(m_sorted_symbol_order[0]) * m_cur_sorted_symbol_order_size); 88 | } 89 | } 90 | 91 | return true; 92 | } 93 | 94 | inline void clear() 95 | { 96 | if (m_lookup) 97 | { 98 | lzham_delete_array(m_malloc_context, m_lookup); 99 | m_lookup = 0; 100 | m_cur_lookup_size = 0; 101 | } 102 | 103 | if (m_sorted_symbol_order) 104 | { 105 | lzham_delete_array(m_malloc_context, m_sorted_symbol_order); 106 | m_sorted_symbol_order = NULL; 107 | m_cur_sorted_symbol_order_size = 0; 108 | } 109 | } 110 | 111 | inline ~decoder_tables() 112 | { 113 | if (m_lookup) 114 | lzham_delete_array(m_malloc_context, m_lookup); 115 | 116 | if (m_sorted_symbol_order) 117 | lzham_delete_array(m_malloc_context, m_sorted_symbol_order); 118 | } 119 | 120 | // DO NOT use any complex classes here - it is bitwise copied. 121 | 122 | lzham_malloc_context m_malloc_context; 123 | 124 | uint m_num_syms; 125 | uint m_total_used_syms; 126 | uint m_table_bits; 127 | uint m_table_shift; 128 | uint m_table_max_code; 129 | uint m_decode_start_code_size; 130 | 131 | uint8 m_min_code_size; 132 | uint8 m_max_code_size; 133 | 134 | uint m_max_codes[cMaxExpectedHuffCodeSize + 1]; 135 | int m_val_ptrs[cMaxExpectedHuffCodeSize + 1]; 136 | 137 | uint m_cur_lookup_size; 138 | uint32* m_lookup; 139 | 140 | uint m_cur_sorted_symbol_order_size; 141 | uint16* m_sorted_symbol_order; 142 | 143 | inline uint get_unshifted_max_code(uint len) const 144 | { 145 | LZHAM_ASSERT( (len >= 1) && (len <= cMaxExpectedHuffCodeSize) ); 146 | uint k = m_max_codes[len - 1]; 147 | if (!k) 148 | return UINT_MAX; 149 | return (k - 1) >> (16 - len); 150 | } 151 | }; 152 | 153 | bool generate_decoder_tables(uint num_syms, const uint8* pCodesizes, decoder_tables* pTables, uint table_bits, const code_size_histogram &code_size_histo, bool sym_freq_all_ones); 154 | 155 | } // namespace prefix_coding 156 | 157 | } // namespace lzham 158 | -------------------------------------------------------------------------------- /lzhamdecomp/lzham_timer.cpp: -------------------------------------------------------------------------------- 1 | // File: lzham_timer.cpp 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #include "lzham_core.h" 4 | #include "lzham_timer.h" 5 | 6 | #ifndef LZHAM_USE_WIN32_API 7 | #include 8 | #endif 9 | 10 | namespace lzham 11 | { 12 | unsigned long long lzham_timer::g_init_ticks; 13 | unsigned long long lzham_timer::g_freq; 14 | double lzham_timer::g_inv_freq; 15 | 16 | #if LZHAM_USE_WIN32_API 17 | inline void query_counter(timer_ticks *pTicks) 18 | { 19 | QueryPerformanceCounter(reinterpret_cast(pTicks)); 20 | } 21 | inline void query_counter_frequency(timer_ticks *pTicks) 22 | { 23 | QueryPerformanceFrequency(reinterpret_cast(pTicks)); 24 | } 25 | #else 26 | inline void query_counter(timer_ticks *pTicks) 27 | { 28 | *pTicks = clock(); 29 | } 30 | inline void query_counter_frequency(timer_ticks *pTicks) 31 | { 32 | *pTicks = CLOCKS_PER_SEC; 33 | } 34 | #endif 35 | 36 | lzham_timer::lzham_timer() : 37 | m_start_time(0), 38 | m_stop_time(0), 39 | m_started(false), 40 | m_stopped(false) 41 | { 42 | if (!g_inv_freq) 43 | init(); 44 | } 45 | 46 | lzham_timer::lzham_timer(timer_ticks start_ticks) 47 | { 48 | if (!g_inv_freq) 49 | init(); 50 | 51 | m_start_time = start_ticks; 52 | 53 | m_started = true; 54 | m_stopped = false; 55 | } 56 | 57 | void lzham_timer::start(timer_ticks start_ticks) 58 | { 59 | m_start_time = start_ticks; 60 | 61 | m_started = true; 62 | m_stopped = false; 63 | } 64 | 65 | void lzham_timer::start() 66 | { 67 | query_counter(&m_start_time); 68 | 69 | m_started = true; 70 | m_stopped = false; 71 | } 72 | 73 | void lzham_timer::stop() 74 | { 75 | LZHAM_ASSERT(m_started); 76 | 77 | query_counter(&m_stop_time); 78 | 79 | m_stopped = true; 80 | } 81 | 82 | double lzham_timer::get_elapsed_secs() const 83 | { 84 | LZHAM_ASSERT(m_started); 85 | if (!m_started) 86 | return 0; 87 | 88 | timer_ticks stop_time = m_stop_time; 89 | if (!m_stopped) 90 | query_counter(&stop_time); 91 | 92 | timer_ticks delta = stop_time - m_start_time; 93 | return delta * g_inv_freq; 94 | } 95 | 96 | timer_ticks lzham_timer::get_elapsed_us() const 97 | { 98 | LZHAM_ASSERT(m_started); 99 | if (!m_started) 100 | return 0; 101 | 102 | timer_ticks stop_time = m_stop_time; 103 | if (!m_stopped) 104 | query_counter(&stop_time); 105 | 106 | timer_ticks delta = stop_time - m_start_time; 107 | return (delta * 1000000ULL + (g_freq >> 1U)) / g_freq; 108 | } 109 | 110 | void lzham_timer::init() 111 | { 112 | if (!g_inv_freq) 113 | { 114 | query_counter_frequency(&g_freq); 115 | g_inv_freq = 1.0f / g_freq; 116 | 117 | query_counter(&g_init_ticks); 118 | } 119 | } 120 | 121 | timer_ticks lzham_timer::get_init_ticks() 122 | { 123 | if (!g_inv_freq) 124 | init(); 125 | 126 | return g_init_ticks; 127 | } 128 | 129 | timer_ticks lzham_timer::get_ticks() 130 | { 131 | if (!g_inv_freq) 132 | init(); 133 | 134 | timer_ticks ticks; 135 | query_counter(&ticks); 136 | return ticks - g_init_ticks; 137 | } 138 | 139 | double lzham_timer::ticks_to_secs(timer_ticks ticks) 140 | { 141 | if (!g_inv_freq) 142 | init(); 143 | 144 | return ticks * g_inv_freq; 145 | } 146 | 147 | } // namespace lzham -------------------------------------------------------------------------------- /lzhamdecomp/lzham_timer.h: -------------------------------------------------------------------------------- 1 | // File: lzham_timer.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | 5 | namespace lzham 6 | { 7 | typedef unsigned long long timer_ticks; 8 | 9 | class lzham_timer 10 | { 11 | public: 12 | lzham_timer(); 13 | lzham_timer(timer_ticks start_ticks); 14 | 15 | void start(); 16 | void start(timer_ticks start_ticks); 17 | 18 | void stop(); 19 | 20 | double get_elapsed_secs() const; 21 | inline double get_elapsed_ms() const { return get_elapsed_secs() * 1000.0f; } 22 | timer_ticks get_elapsed_us() const; 23 | 24 | static void init(); 25 | static inline timer_ticks get_ticks_per_sec() { return g_freq; } 26 | static timer_ticks get_init_ticks(); 27 | static timer_ticks get_ticks(); 28 | static double ticks_to_secs(timer_ticks ticks); 29 | static inline double ticks_to_ms(timer_ticks ticks) { return ticks_to_secs(ticks) * 1000.0f; } 30 | static inline double get_secs() { return ticks_to_secs(get_ticks()); } 31 | static inline double get_ms() { return ticks_to_ms(get_ticks()); } 32 | 33 | private: 34 | static timer_ticks g_init_ticks; 35 | static timer_ticks g_freq; 36 | static double g_inv_freq; 37 | 38 | timer_ticks m_start_time; 39 | timer_ticks m_stop_time; 40 | 41 | bool m_started : 1; 42 | bool m_stopped : 1; 43 | }; 44 | 45 | enum var_args_t { cVarArgs }; 46 | 47 | #if LZHAM_PERF_SECTIONS 48 | class scoped_perf_section 49 | { 50 | public: 51 | inline scoped_perf_section() : 52 | m_start_ticks(lzham_timer::get_ticks()) 53 | { 54 | m_name[0] = '?'; 55 | m_name[1] = '\0'; 56 | } 57 | 58 | inline scoped_perf_section(const char *pName) : 59 | m_start_ticks(lzham_timer::get_ticks()) 60 | { 61 | strcpy_s(m_name, pName); 62 | 63 | lzham_buffered_printf("Thread: 0x%08X, BEGIN Time: %3.3fms, %s\n", GetCurrentThreadId(), lzham_timer::ticks_to_ms(m_start_ticks), m_name); 64 | } 65 | 66 | inline scoped_perf_section(var_args_t, const char *pName, ...) : 67 | m_start_ticks(lzham_timer::get_ticks()) 68 | { 69 | va_list args; 70 | va_start(args, pName); 71 | vsprintf_s(m_name, sizeof(m_name), pName, args); 72 | va_end(args); 73 | 74 | lzham_buffered_printf("Thread: 0x%08X, BEGIN Time: %3.3fms, %s\n", GetCurrentThreadId(), lzham_timer::ticks_to_ms(m_start_ticks), m_name); 75 | } 76 | 77 | inline ~scoped_perf_section() 78 | { 79 | double end_ms = lzham_timer::get_ms(); 80 | double start_ms = lzham_timer::ticks_to_ms(m_start_ticks); 81 | 82 | lzham_buffered_printf("Thread: 0x%08X, END Time: %3.3fms, %s, Total: %3.3fms\n", GetCurrentThreadId(), end_ms, m_name, end_ms - start_ms); 83 | } 84 | 85 | private: 86 | char m_name[64]; 87 | timer_ticks m_start_ticks; 88 | }; 89 | #else 90 | class scoped_perf_section 91 | { 92 | public: 93 | inline scoped_perf_section() { } 94 | inline scoped_perf_section(const char *pName) { (void)pName; } 95 | inline scoped_perf_section(var_args_t, const char *pName, ...) { (void)pName; } 96 | }; 97 | #endif // LZHAM_PERF_SECTIONS 98 | 99 | } // namespace lzham 100 | -------------------------------------------------------------------------------- /lzhamdecomp/lzham_traits.h: -------------------------------------------------------------------------------- 1 | // File: lzham_traits.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | 5 | namespace lzham 6 | { 7 | template 8 | struct scalar_type 9 | { 10 | enum { cFlag = false }; 11 | static inline void construct(T* p) { helpers::construct(p); } 12 | static inline void construct(T* p, const T& init) { helpers::construct(p, init); } 13 | static inline void construct_array(T* p, uint n) { helpers::construct_array(p, n); } 14 | static inline void destruct(T* p) { helpers::destruct(p); } 15 | static inline void destruct_array(T* p, uint n) { helpers::destruct_array(p, n); } 16 | }; 17 | 18 | template struct scalar_type 19 | { 20 | enum { cFlag = true }; 21 | static inline void construct(T** p) { memset(p, 0, sizeof(T*)); } 22 | static inline void construct(T** p, T* init) { *p = init; } 23 | static inline void construct_array(T** p, uint n) { memset(p, 0, sizeof(T*) * n); } 24 | static inline void destruct(T** p) { LZHAM_NOTE_UNUSED(p); } 25 | static inline void destruct_array(T** p, uint n) { LZHAM_NOTE_UNUSED(p); LZHAM_NOTE_UNUSED(n); } 26 | }; 27 | 28 | #define LZHAM_DEFINE_BUILT_IN_TYPE(X) \ 29 | template<> struct scalar_type { \ 30 | enum { cFlag = true }; \ 31 | static inline void construct(X* p) { memset(p, 0, sizeof(X)); } \ 32 | static inline void construct(X* p, const X& init) { memcpy(p, &init, sizeof(X)); } \ 33 | static inline void construct_array(X* p, uint n) { memset(p, 0, sizeof(X) * n); } \ 34 | static inline void destruct(X* p) { LZHAM_NOTE_UNUSED(p); } \ 35 | static inline void destruct_array(X* p, uint n) { LZHAM_NOTE_UNUSED(p); LZHAM_NOTE_UNUSED(n); } }; 36 | 37 | LZHAM_DEFINE_BUILT_IN_TYPE(bool) 38 | LZHAM_DEFINE_BUILT_IN_TYPE(char) 39 | LZHAM_DEFINE_BUILT_IN_TYPE(unsigned char) 40 | LZHAM_DEFINE_BUILT_IN_TYPE(short) 41 | LZHAM_DEFINE_BUILT_IN_TYPE(unsigned short) 42 | LZHAM_DEFINE_BUILT_IN_TYPE(int) 43 | LZHAM_DEFINE_BUILT_IN_TYPE(unsigned int) 44 | LZHAM_DEFINE_BUILT_IN_TYPE(long) 45 | LZHAM_DEFINE_BUILT_IN_TYPE(unsigned long) 46 | LZHAM_DEFINE_BUILT_IN_TYPE(float) 47 | LZHAM_DEFINE_BUILT_IN_TYPE(double) 48 | LZHAM_DEFINE_BUILT_IN_TYPE(long double) 49 | #if defined(WIN32) 50 | LZHAM_DEFINE_BUILT_IN_TYPE(__int64) 51 | LZHAM_DEFINE_BUILT_IN_TYPE(unsigned __int64) 52 | #endif 53 | 54 | #undef LZHAM_DEFINE_BUILT_IN_TYPE 55 | 56 | // See: http://erdani.org/publications/cuj-2004-06.pdf 57 | 58 | template 59 | struct bitwise_movable { enum { cFlag = false }; }; 60 | 61 | // Defines type Q as bitwise movable. 62 | #define LZHAM_DEFINE_BITWISE_MOVABLE(Q) template<> struct bitwise_movable { enum { cFlag = true }; }; 63 | 64 | template 65 | struct bitwise_copyable { enum { cFlag = false }; }; 66 | 67 | // Defines type Q as bitwise copyable. 68 | #define LZHAM_DEFINE_BITWISE_COPYABLE(Q) template<> struct bitwise_copyable { enum { cFlag = true }; }; 69 | 70 | #if (defined(__APPLE__) && (TARGET_OS_MAC != 1)) || defined(__NetBSD__) 71 | #define LZHAM_IS_POD(T) std::is_pod::value 72 | #else 73 | #define LZHAM_IS_POD(T) __is_pod(T) 74 | #endif 75 | 76 | #define LZHAM_IS_SCALAR_TYPE(T) (scalar_type::cFlag) 77 | 78 | #define LZHAM_IS_BITWISE_COPYABLE(T) ((scalar_type::cFlag) || (bitwise_copyable::cFlag) || LZHAM_IS_POD(T)) 79 | 80 | #define LZHAM_IS_BITWISE_MOVABLE(T) (LZHAM_IS_BITWISE_COPYABLE(T) || (bitwise_movable::cFlag)) 81 | 82 | #define LZHAM_HAS_DESTRUCTOR(T) ((!scalar_type::cFlag) && (!LZHAM_IS_POD(T))) 83 | 84 | // From yasli_traits.h: 85 | // Credit goes to Boost; 86 | // also found in the C++ Templates book by Vandevoorde and Josuttis 87 | 88 | typedef char (&yes_t)[1]; 89 | typedef char (&no_t)[2]; 90 | 91 | template yes_t class_test(int U::*); 92 | template no_t class_test(...); 93 | 94 | template struct is_class 95 | { 96 | enum { value = (sizeof(class_test(0)) == sizeof(yes_t)) }; 97 | }; 98 | 99 | template struct is_pointer 100 | { 101 | enum { value = false }; 102 | }; 103 | 104 | template struct is_pointer 105 | { 106 | enum { value = true }; 107 | }; 108 | 109 | LZHAM_DEFINE_BITWISE_COPYABLE(empty_type); 110 | LZHAM_DEFINE_BITWISE_MOVABLE(empty_type); 111 | 112 | namespace helpers 113 | { 114 | template 115 | inline void construct_array(T* p, uint n) 116 | { 117 | if (LZHAM_IS_SCALAR_TYPE(T)) 118 | { 119 | memset(p, 0, sizeof(T) * n); 120 | } 121 | else 122 | { 123 | T* q = p + n; 124 | for ( ; p != q; ++p) 125 | new (static_cast(p)) T; 126 | } 127 | } 128 | 129 | template 130 | inline void destruct_array(T* p, uint n) 131 | { 132 | if ( LZHAM_HAS_DESTRUCTOR(T) ) 133 | { 134 | T* q = p + n; 135 | for ( ; p != q; ++p) 136 | p->~T(); 137 | } 138 | } 139 | } 140 | 141 | } // namespace lzham 142 | -------------------------------------------------------------------------------- /lzhamdecomp/lzham_types.h: -------------------------------------------------------------------------------- 1 | // File: types.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | 5 | namespace lzham 6 | { 7 | typedef unsigned char uint8; 8 | typedef signed char int8; 9 | typedef unsigned char uint8; 10 | typedef unsigned short uint16; 11 | typedef signed short int16; 12 | typedef unsigned int uint32; 13 | typedef uint32 uint; 14 | typedef signed int int32; 15 | 16 | #ifdef _MSC_VER 17 | typedef unsigned __int64 uint64; 18 | typedef signed __int64 int64; 19 | #else 20 | typedef unsigned long long uint64; 21 | typedef long long int64; 22 | #endif 23 | 24 | const uint8 cUINT8_MIN = 0; 25 | const uint8 cUINT8_MAX = 0xFFU; 26 | const uint16 cUINT16_MIN = 0; 27 | const uint16 cUINT16_MAX = 0xFFFFU; 28 | const uint32 cUINT32_MIN = 0; 29 | const uint32 cUINT32_MAX = 0xFFFFFFFFU; 30 | const uint64 cUINT64_MIN = 0; 31 | const uint64 cUINT64_MAX = 0xFFFFFFFFFFFFFFFFULL; //0xFFFFFFFFFFFFFFFFui64; 32 | 33 | const int8 cINT8_MIN = -128; 34 | const int8 cINT8_MAX = 127; 35 | const int16 cINT16_MIN = -32768; 36 | const int16 cINT16_MAX = 32767; 37 | const int32 cINT32_MIN = (-2147483647 - 1); 38 | const int32 cINT32_MAX = 2147483647; 39 | const int64 cINT64_MIN = (int64)0x8000000000000000ULL; //(-9223372036854775807i64 - 1); 40 | const int64 cINT64_MAX = (int64)0x7FFFFFFFFFFFFFFFULL; //9223372036854775807i64; 41 | 42 | #if LZHAM_64BIT_POINTERS 43 | typedef uint64 uint_ptr; 44 | typedef uint64 uint32_ptr; 45 | typedef int64 signed_size_t; 46 | typedef uint64 ptr_bits_t; 47 | #else 48 | typedef unsigned int uint_ptr; 49 | typedef unsigned int uint32_ptr; 50 | typedef signed int signed_size_t; 51 | typedef uint32 ptr_bits_t; 52 | #endif 53 | 54 | enum 55 | { 56 | cInvalidIndex = -1 57 | }; 58 | 59 | const uint cIntBits = sizeof(uint) * CHAR_BIT; 60 | 61 | template struct int_traits { enum { cMin = INT_MIN, cMax = INT_MAX, cSigned = true }; }; 62 | template<> struct int_traits { enum { cMin = cINT8_MIN, cMax = cINT8_MAX, cSigned = true }; }; 63 | template<> struct int_traits { enum { cMin = cINT16_MIN, cMax = cINT16_MAX, cSigned = true }; }; 64 | template<> struct int_traits { enum { cMin = cINT32_MIN, cMax = cINT32_MAX, cSigned = true }; }; 65 | 66 | template<> struct int_traits { enum { cMin = 0, cMax = UINT_MAX, cSigned = false }; }; 67 | template<> struct int_traits { enum { cMin = 0, cMax = cUINT8_MAX, cSigned = false }; }; 68 | template<> struct int_traits { enum { cMin = 0, cMax = cUINT16_MAX, cSigned = false }; }; 69 | 70 | struct empty_type { }; 71 | 72 | } // namespace lzham 73 | -------------------------------------------------------------------------------- /lzhamdecomp/lzham_utils.h: -------------------------------------------------------------------------------- 1 | // File: lzham_utils.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | 5 | #define LZHAM_GET_ALIGNMENT(v) ((!sizeof(v)) ? 1 : (__alignof(v) ? __alignof(v) : sizeof(uint32))) 6 | 7 | #define LZHAM_MIN(a, b) (((a) < (b)) ? (a) : (b)) 8 | #define LZHAM_MAX(a, b) (((a) < (b)) ? (b) : (a)) 9 | 10 | template T decay_array_to_subtype(T (&a)[N]); 11 | #define LZHAM_ARRAY_SIZE(X) (sizeof(X) / sizeof(decay_array_to_subtype(X))) 12 | 13 | namespace lzham 14 | { 15 | namespace utils 16 | { 17 | template inline void swap(T& l, T& r) 18 | { 19 | T temp(l); 20 | l = r; 21 | r = temp; 22 | } 23 | 24 | template inline void zero_object(T& obj) 25 | { 26 | memset(&obj, 0, sizeof(obj)); 27 | } 28 | 29 | static inline uint32 swap32(uint32 x) { return ((x << 24U) | ((x << 8U) & 0x00FF0000U) | ((x >> 8U) & 0x0000FF00U) | (x >> 24U)); } 30 | 31 | inline uint count_leading_zeros16(uint v) 32 | { 33 | LZHAM_ASSERT(v < 0x10000); 34 | 35 | uint temp; 36 | uint n = 16; 37 | 38 | temp = v >> 8; 39 | if (temp) { n -= 8; v = temp; } 40 | 41 | temp = v >> 4; 42 | if (temp) { n -= 4; v = temp; } 43 | 44 | temp = v >> 2; 45 | if (temp) { n -= 2; v = temp; } 46 | 47 | temp = v >> 1; 48 | if (temp) { n -= 1; v = temp; } 49 | 50 | if (v & 1) n--; 51 | 52 | return n; 53 | } 54 | 55 | } // namespace utils 56 | 57 | } // namespace lzham 58 | 59 | -------------------------------------------------------------------------------- /lzhamdecomp/lzham_vector.cpp: -------------------------------------------------------------------------------- 1 | // File: lzham_vector.cpp 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #include "lzham_core.h" 4 | #include "lzham_vector.h" 5 | 6 | namespace lzham 7 | { 8 | bool elemental_vector::increase_capacity(uint min_new_capacity, bool grow_hint, uint element_size, object_mover pMover, bool nofail) 9 | { 10 | LZHAM_ASSERT(m_size <= m_capacity); 11 | 12 | #if LZHAM_64BIT_POINTERS 13 | LZHAM_ASSUME(sizeof(void*) == sizeof(uint64)); 14 | LZHAM_ASSERT(min_new_capacity < (0x400000000ULL / element_size)); 15 | #else 16 | LZHAM_ASSUME(sizeof(void*) == sizeof(uint32)); 17 | LZHAM_ASSERT(min_new_capacity < (0x7FFF0000U / element_size)); 18 | #endif 19 | 20 | if (m_capacity >= min_new_capacity) 21 | return true; 22 | 23 | // new_capacity must be 64-bit when compiling on x64. 24 | size_t new_capacity = (size_t)min_new_capacity; 25 | if ((grow_hint) && (!math::is_power_of_2(static_cast(new_capacity)))) 26 | new_capacity = static_cast(math::next_pow2(static_cast(new_capacity))); 27 | 28 | LZHAM_ASSERT(new_capacity && (new_capacity > m_capacity)); 29 | 30 | const size_t desired_size = element_size * new_capacity; 31 | size_t actual_size; 32 | if (!pMover) 33 | { 34 | void* new_p = lzham_realloc(m_malloc_context, m_p, desired_size, &actual_size, true); 35 | if (!new_p) 36 | { 37 | if (nofail) 38 | { 39 | LZHAM_LOG_ERROR(5000); 40 | return false; 41 | } 42 | 43 | char buf[256]; 44 | sprintf_s(buf, sizeof(buf), "vector: lzham_realloc() failed allocating %u bytes", desired_size); 45 | LZHAM_FAIL(buf); 46 | } 47 | m_p = new_p; 48 | } 49 | else 50 | { 51 | void* new_p = lzham_malloc(m_malloc_context, desired_size, &actual_size); 52 | if (!new_p) 53 | { 54 | if (nofail) 55 | { 56 | LZHAM_LOG_ERROR(5001); 57 | return false; 58 | } 59 | 60 | LZHAM_LOG_ERROR(5002); 61 | 62 | char buf[256]; 63 | sprintf_s(buf, sizeof(buf), "vector: lzham_malloc() failed allocating %u bytes", desired_size); 64 | LZHAM_FAIL(buf); 65 | } 66 | 67 | (*pMover)(new_p, m_p, m_size); 68 | 69 | if (m_p) 70 | lzham_free(m_malloc_context, m_p); 71 | 72 | m_p = new_p; 73 | } 74 | 75 | if (actual_size > desired_size) 76 | m_capacity = static_cast(actual_size / element_size); 77 | else 78 | m_capacity = static_cast(new_capacity); 79 | 80 | return true; 81 | } 82 | 83 | } // namespace lzham 84 | -------------------------------------------------------------------------------- /lzhamdll/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | PROJECT(lzhamdll) 2 | cmake_minimum_required(VERSION 2.8) 3 | option(BUILD_X64 "build 64-bit" TRUE) 4 | 5 | message("Initial BUILD_X64=${BUILD_X64}") 6 | message("Initial CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}") 7 | 8 | if( NOT CMAKE_BUILD_TYPE ) 9 | set( CMAKE_BUILD_TYPE Release ) 10 | endif( NOT CMAKE_BUILD_TYPE ) 11 | 12 | message( ${PROJECT_NAME} " build type: " ${CMAKE_BUILD_TYPE} ) 13 | 14 | if (BUILD_X64) 15 | message("Building 64-bit") 16 | else() 17 | message("Building 32-bit") 18 | endif(BUILD_X64) 19 | 20 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -Wall -Wextra") 21 | set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -Wall -Wextra") 22 | 23 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -Wextra -O3 -fomit-frame-pointer -fexpensive-optimizations") 24 | set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -Wextra") 25 | 26 | set(SRC_LIST 27 | lzham_api.cpp) 28 | 29 | # -fno-strict-aliasing is *required* to compile LZHAM 30 | set(GCC_COMPILE_FLAGS "-fno-strict-aliasing -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64") 31 | 32 | if (NOT BUILD_X64) 33 | set(GCC_COMPILE_FLAGS "${GCC_COMPILE_FLAGS} -m32") 34 | endif() 35 | 36 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_LINK_FLAGS}") 37 | 38 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GCC_COMPILE_FLAGS}") 39 | set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${GCC_COMPILE_FLAGS} -DNDEBUG") 40 | set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${GCC_COMPILE_FLAGS} -D_DEBUG") 41 | 42 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COMPILE_FLAGS}") 43 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${GCC_COMPILE_FLAGS} -DNDEBUG") 44 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${GCC_COMPILE_FLAGS} -D_DEBUG") 45 | 46 | include_directories( 47 | ${PROJECT_SOURCE_DIR}/../lzhamdecomp 48 | ${PROJECT_SOURCE_DIR}/../lzhamcomp 49 | ${PROJECT_SOURCE_DIR}/../include) 50 | 51 | #set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin_linux) 52 | 53 | add_library(${PROJECT_NAME} ${SRC_LIST}) 54 | target_link_libraries(${PROJECT_NAME} lzhamcomp) 55 | install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib${LIB_SUFFIX} ARCHIVE DESTINATION lib${LIB_SUFFIX} RUNTIME DESTINATION bin) 56 | 57 | -------------------------------------------------------------------------------- /lzhamdll/lzham_api.cpp: -------------------------------------------------------------------------------- 1 | // File: lzham_api.cpp - Dynamic DLL entrypoints. 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #include "lzham_core.h" 4 | #include "lzham_decomp.h" 5 | #include "lzham_comp.h" 6 | 7 | extern "C" LZHAM_DLL_EXPORT lzham_uint32 lzham_get_version(void) 8 | { 9 | return LZHAM_DLL_VERSION; 10 | } 11 | 12 | extern "C" LZHAM_DLL_EXPORT void lzham_set_memory_callbacks(lzham_realloc_func pRealloc, lzham_msize_func pMSize, void* pUser_data) 13 | { 14 | lzham::lzham_lib_set_memory_callbacks(pRealloc, pMSize, pUser_data); 15 | } 16 | 17 | extern "C" LZHAM_DLL_EXPORT lzham_decompress_state_ptr lzham_decompress_init(const lzham_decompress_params *pParams) 18 | { 19 | return lzham::lzham_lib_decompress_init(pParams); 20 | } 21 | 22 | extern "C" LZHAM_DLL_EXPORT lzham_decompress_state_ptr lzham_decompress_reinit(lzham_decompress_state_ptr p, const lzham_decompress_params *pParams) 23 | { 24 | return lzham::lzham_lib_decompress_reinit(p, pParams); 25 | } 26 | 27 | extern "C" LZHAM_DLL_EXPORT lzham_uint32 lzham_decompress_deinit(lzham_decompress_state_ptr p) 28 | { 29 | return lzham::lzham_lib_decompress_deinit(p); 30 | } 31 | 32 | extern "C" LZHAM_DLL_EXPORT lzham_decompress_status_t lzham_decompress( 33 | lzham_decompress_state_ptr p, 34 | const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, 35 | lzham_uint8 *pOut_buf, size_t *pOut_buf_size, 36 | lzham_bool no_more_input_bytes_flag) 37 | { 38 | return lzham::lzham_lib_decompress(p, pIn_buf, pIn_buf_size, pOut_buf, pOut_buf_size, no_more_input_bytes_flag); 39 | } 40 | 41 | extern "C" LZHAM_DLL_EXPORT lzham_decompress_status_t lzham_decompress_memory(const lzham_decompress_params *pParams, lzham_uint8* pDst_buf, size_t *pDst_len, const lzham_uint8* pSrc_buf, size_t src_len, lzham_uint32 *pAdler32) 42 | { 43 | return lzham::lzham_lib_decompress_memory(pParams, pDst_buf, pDst_len, pSrc_buf, src_len, pAdler32); 44 | } 45 | 46 | extern "C" LZHAM_DLL_EXPORT lzham_compress_state_ptr lzham_compress_init(const lzham_compress_params *pParams) 47 | { 48 | return lzham::lzham_lib_compress_init(pParams); 49 | } 50 | 51 | extern "C" LZHAM_DLL_EXPORT lzham_compress_state_ptr lzham_compress_reinit(lzham_compress_state_ptr p) 52 | { 53 | return lzham::lzham_lib_compress_reinit(p); 54 | } 55 | 56 | extern "C" LZHAM_DLL_EXPORT lzham_uint32 lzham_compress_deinit(lzham_compress_state_ptr p) 57 | { 58 | return lzham::lzham_lib_compress_deinit(p); 59 | } 60 | 61 | extern "C" LZHAM_DLL_EXPORT lzham_compress_status_t lzham_compress( 62 | lzham_compress_state_ptr p, 63 | const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, 64 | lzham_uint8 *pOut_buf, size_t *pOut_buf_size, 65 | lzham_bool no_more_input_bytes_flag) 66 | { 67 | return lzham::lzham_lib_compress(p, pIn_buf, pIn_buf_size, pOut_buf, pOut_buf_size, no_more_input_bytes_flag); 68 | } 69 | 70 | extern "C" LZHAM_DLL_EXPORT lzham_compress_status_t lzham_compress2( 71 | lzham_compress_state_ptr p, 72 | const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, 73 | lzham_uint8 *pOut_buf, size_t *pOut_buf_size, 74 | lzham_flush_t flush_type) 75 | { 76 | return lzham::lzham_lib_compress2(p, pIn_buf, pIn_buf_size, pOut_buf, pOut_buf_size, flush_type); 77 | } 78 | 79 | extern "C" LZHAM_DLL_EXPORT lzham_compress_status_t lzham_compress_memory(const lzham_compress_params *pParams, lzham_uint8* pDst_buf, size_t *pDst_len, const lzham_uint8* pSrc_buf, size_t src_len, lzham_uint32 *pAdler32) 80 | { 81 | return lzham::lzham_lib_compress_memory(pParams, pDst_buf, pDst_len, pSrc_buf, src_len, pAdler32); 82 | } 83 | 84 | // ----------------- zlib-style API's 85 | 86 | extern "C" LZHAM_DLL_EXPORT const char *lzham_z_version(void) 87 | { 88 | return LZHAM_Z_VERSION; 89 | } 90 | 91 | extern "C" lzham_z_ulong LZHAM_DLL_EXPORT lzham_z_adler32(lzham_z_ulong adler, const unsigned char *ptr, size_t buf_len) 92 | { 93 | return lzham::lzham_lib_z_adler32(adler, ptr, buf_len); 94 | } 95 | 96 | extern "C" lzham_z_ulong LZHAM_DLL_EXPORT lzham_z_crc32(lzham_z_ulong crc, const lzham_uint8 *ptr, size_t buf_len) 97 | { 98 | return lzham::lzham_lib_z_crc32(crc, ptr, buf_len); 99 | } 100 | 101 | extern "C" LZHAM_DLL_EXPORT int lzham_z_deflateInit(lzham_z_streamp pStream, int level) 102 | { 103 | return lzham::lzham_lib_z_deflateInit(pStream, level); 104 | } 105 | 106 | extern "C" LZHAM_DLL_EXPORT int lzham_z_deflateInit2(lzham_z_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy) 107 | { 108 | return lzham::lzham_lib_z_deflateInit2(pStream, level, method, window_bits, mem_level, strategy); 109 | } 110 | 111 | extern "C" LZHAM_DLL_EXPORT int lzham_z_deflateReset(lzham_z_streamp pStream) 112 | { 113 | return lzham::lzham_lib_z_deflateReset(pStream); 114 | } 115 | 116 | extern "C" LZHAM_DLL_EXPORT int lzham_z_deflate(lzham_z_streamp pStream, int flush) 117 | { 118 | return lzham::lzham_lib_z_deflate(pStream, flush); 119 | } 120 | 121 | extern "C" LZHAM_DLL_EXPORT int lzham_z_deflateEnd(lzham_z_streamp pStream) 122 | { 123 | return lzham::lzham_lib_z_deflateEnd(pStream); 124 | } 125 | 126 | extern "C" LZHAM_DLL_EXPORT lzham_z_ulong lzham_z_deflateBound(lzham_z_streamp pStream, lzham_z_ulong source_len) 127 | { 128 | return lzham::lzham_lib_z_deflateBound(pStream, source_len); 129 | } 130 | 131 | extern "C" LZHAM_DLL_EXPORT int lzham_z_compress(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len) 132 | { 133 | return lzham::lzham_lib_z_compress(pDest, pDest_len, pSource, source_len); 134 | } 135 | 136 | extern "C" LZHAM_DLL_EXPORT int lzham_z_compress2(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len, int level) 137 | { 138 | return lzham::lzham_lib_z_compress2(pDest, pDest_len, pSource, source_len, level); 139 | } 140 | 141 | extern "C" LZHAM_DLL_EXPORT lzham_z_ulong lzham_z_compressBound(lzham_z_ulong source_len) 142 | { 143 | return lzham::lzham_lib_z_compressBound(source_len); 144 | } 145 | 146 | extern "C" LZHAM_DLL_EXPORT int lzham_z_inflateInit(lzham_z_streamp pStream) 147 | { 148 | return lzham::lzham_lib_z_inflateInit(pStream); 149 | } 150 | 151 | extern "C" LZHAM_DLL_EXPORT int lzham_z_inflateInit2(lzham_z_streamp pStream, int window_bits) 152 | { 153 | return lzham::lzham_lib_z_inflateInit2(pStream, window_bits); 154 | } 155 | 156 | extern "C" LZHAM_DLL_EXPORT int lzham_z_inflateReset(lzham_z_streamp pStream) 157 | { 158 | return lzham::lzham_lib_z_inflateReset(pStream); 159 | } 160 | 161 | extern "C" LZHAM_DLL_EXPORT int lzham_z_inflate(lzham_z_streamp pStream, int flush) 162 | { 163 | return lzham::lzham_lib_z_inflate(pStream, flush); 164 | } 165 | 166 | extern "C" LZHAM_DLL_EXPORT int lzham_z_inflateEnd(lzham_z_streamp pStream) 167 | { 168 | return lzham::lzham_lib_z_inflateEnd(pStream); 169 | } 170 | 171 | extern "C" LZHAM_DLL_EXPORT int lzham_z_uncompress(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len) 172 | { 173 | return lzham::lzham_lib_z_uncompress(pDest, pDest_len, pSource, source_len); 174 | } 175 | 176 | extern "C" LZHAM_DLL_EXPORT const char *lzham_z_error(int err) 177 | { 178 | return lzham::lzham_lib_z_error(err); 179 | } 180 | -------------------------------------------------------------------------------- /lzhamdll/lzham_dll_main.cpp: -------------------------------------------------------------------------------- 1 | // File: lzham_dll_main.cpp 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #include "lzham_core.h" 4 | 5 | #if !LZHAM_ANSI_CPLUSPLUS 6 | 7 | BOOL APIENTRY DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpReserved) 8 | { 9 | hModule, fdwReason, lpReserved; 10 | 11 | switch( fdwReason ) 12 | { 13 | case DLL_PROCESS_ATTACH: 14 | { 15 | break; 16 | } 17 | case DLL_PROCESS_DETACH: 18 | { 19 | break; 20 | } 21 | } 22 | 23 | return TRUE; 24 | } 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /lzhamdll/lzhamdll.def: -------------------------------------------------------------------------------- 1 | LIBRARY lzhamdll 2 | EXPORTS 3 | lzham_get_version @1 4 | lzham_set_memory_callbacks @2 5 | lzham_compress_init @3 6 | lzham_compress_reinit @4 7 | lzham_compress @5 8 | lzham_compress_deinit @6 9 | lzham_compress_memory @7 10 | lzham_decompress_init @8 11 | lzham_decompress @9 12 | lzham_decompress_deinit @10 13 | lzham_decompress_memory @11 14 | lzham_decompress_reinit @12 15 | -------------------------------------------------------------------------------- /lzhamlib/lzham_lib.cpp: -------------------------------------------------------------------------------- 1 | // File: lzham_lib.cpp - Static library entrypoints. 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #include "lzham_core.h" 4 | #include "lzham_decomp.h" 5 | #include "lzham_comp.h" 6 | 7 | extern "C" lzham_uint32 LZHAM_CDECL lzham_get_version(void) 8 | { 9 | return LZHAM_DLL_VERSION; 10 | } 11 | 12 | extern "C" void LZHAM_CDECL lzham_set_memory_callbacks(lzham_realloc_func pRealloc, lzham_msize_func pMSize, void* pUser_data) 13 | { 14 | lzham::lzham_lib_set_memory_callbacks(pRealloc, pMSize, pUser_data); 15 | } 16 | 17 | extern "C" lzham_decompress_state_ptr LZHAM_CDECL lzham_decompress_init(const lzham_decompress_params *pParams) 18 | { 19 | return lzham::lzham_lib_decompress_init(pParams); 20 | } 21 | 22 | extern "C" lzham_decompress_state_ptr LZHAM_CDECL lzham_decompress_reinit(lzham_decompress_state_ptr p, const lzham_decompress_params *pParams) 23 | { 24 | return lzham::lzham_lib_decompress_reinit(p, pParams); 25 | } 26 | 27 | extern "C" lzham_uint32 LZHAM_CDECL lzham_decompress_deinit(lzham_decompress_state_ptr p) 28 | { 29 | return lzham::lzham_lib_decompress_deinit(p); 30 | } 31 | 32 | extern "C" lzham_decompress_status_t LZHAM_CDECL lzham_decompress( 33 | lzham_decompress_state_ptr p, 34 | const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, 35 | lzham_uint8 *pOut_buf, size_t *pOut_buf_size, 36 | lzham_bool no_more_input_bytes_flag) 37 | { 38 | return lzham::lzham_lib_decompress(p, pIn_buf, pIn_buf_size, pOut_buf, pOut_buf_size, no_more_input_bytes_flag); 39 | } 40 | 41 | extern "C" lzham_decompress_status_t LZHAM_CDECL lzham_decompress_memory(const lzham_decompress_params *pParams, lzham_uint8* pDst_buf, size_t *pDst_len, const lzham_uint8* pSrc_buf, size_t src_len, lzham_uint32 *pAdler32) 42 | { 43 | return lzham::lzham_lib_decompress_memory(pParams, pDst_buf, pDst_len, pSrc_buf, src_len, pAdler32); 44 | } 45 | 46 | extern "C" lzham_compress_state_ptr LZHAM_CDECL lzham_compress_init(const lzham_compress_params *pParams) 47 | { 48 | return lzham::lzham_lib_compress_init(pParams); 49 | } 50 | 51 | extern "C" lzham_compress_state_ptr LZHAM_CDECL lzham_compress_reinit(lzham_compress_state_ptr p) 52 | { 53 | return lzham::lzham_lib_compress_reinit(p); 54 | } 55 | 56 | extern "C" lzham_uint32 LZHAM_CDECL lzham_compress_deinit(lzham_compress_state_ptr p) 57 | { 58 | return lzham::lzham_lib_compress_deinit(p); 59 | } 60 | 61 | extern "C" lzham_compress_status_t LZHAM_CDECL lzham_compress( 62 | lzham_compress_state_ptr p, 63 | const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, 64 | lzham_uint8 *pOut_buf, size_t *pOut_buf_size, 65 | lzham_bool no_more_input_bytes_flag) 66 | { 67 | return lzham::lzham_lib_compress(p, pIn_buf, pIn_buf_size, pOut_buf, pOut_buf_size, no_more_input_bytes_flag); 68 | } 69 | 70 | extern "C" lzham_compress_status_t LZHAM_CDECL lzham_compress2( 71 | lzham_compress_state_ptr p, 72 | const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, 73 | lzham_uint8 *pOut_buf, size_t *pOut_buf_size, 74 | lzham_flush_t flush_type) 75 | { 76 | return lzham::lzham_lib_compress2(p, pIn_buf, pIn_buf_size, pOut_buf, pOut_buf_size, flush_type); 77 | } 78 | 79 | extern "C" lzham_compress_status_t LZHAM_CDECL lzham_compress_memory(const lzham_compress_params *pParams, lzham_uint8* pDst_buf, size_t *pDst_len, const lzham_uint8* pSrc_buf, size_t src_len, lzham_uint32 *pAdler32) 80 | { 81 | return lzham::lzham_lib_compress_memory(pParams, pDst_buf, pDst_len, pSrc_buf, src_len, pAdler32); 82 | } 83 | 84 | // ----------------- zlib-style API's 85 | 86 | extern "C" const char * LZHAM_CDECL lzham_z_version(void) 87 | { 88 | return LZHAM_Z_VERSION; 89 | } 90 | 91 | extern "C" lzham_z_ulong LZHAM_CDECL lzham_z_adler32(lzham_z_ulong adler, const unsigned char *ptr, size_t buf_len) 92 | { 93 | return lzham::lzham_lib_z_adler32(adler, ptr, buf_len); 94 | } 95 | 96 | extern "C" lzham_z_ulong LZHAM_CDECL lzham_z_crc32(lzham_z_ulong crc, const lzham_uint8 *ptr, size_t buf_len) 97 | { 98 | return lzham::lzham_lib_z_crc32(crc, ptr, buf_len); 99 | } 100 | 101 | extern "C" int LZHAM_CDECL lzham_z_deflateInit(lzham_z_streamp pStream, int level) 102 | { 103 | return lzham::lzham_lib_z_deflateInit(pStream, level); 104 | } 105 | 106 | extern "C" int LZHAM_CDECL lzham_z_deflateInit2(lzham_z_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy) 107 | { 108 | return lzham::lzham_lib_z_deflateInit2(pStream, level, method, window_bits, mem_level, strategy); 109 | } 110 | 111 | extern "C" int LZHAM_CDECL lzham_z_deflateReset(lzham_z_streamp pStream) 112 | { 113 | return lzham::lzham_lib_z_deflateReset(pStream); 114 | } 115 | 116 | extern "C" int LZHAM_CDECL lzham_z_deflate(lzham_z_streamp pStream, int flush) 117 | { 118 | return lzham::lzham_lib_z_deflate(pStream, flush); 119 | } 120 | 121 | extern "C" int LZHAM_CDECL lzham_z_deflateEnd(lzham_z_streamp pStream) 122 | { 123 | return lzham::lzham_lib_z_deflateEnd(pStream); 124 | } 125 | 126 | extern "C" lzham_z_ulong LZHAM_CDECL lzham_z_deflateBound(lzham_z_streamp pStream, lzham_z_ulong source_len) 127 | { 128 | return lzham::lzham_lib_z_deflateBound(pStream, source_len); 129 | } 130 | 131 | extern "C" int LZHAM_CDECL lzham_z_compress(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len) 132 | { 133 | return lzham::lzham_lib_z_compress(pDest, pDest_len, pSource, source_len); 134 | } 135 | 136 | extern "C" int LZHAM_CDECL lzham_z_compress2(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len, int level) 137 | { 138 | return lzham::lzham_lib_z_compress2(pDest, pDest_len, pSource, source_len, level); 139 | } 140 | 141 | extern "C" lzham_z_ulong LZHAM_CDECL lzham_z_compressBound(lzham_z_ulong source_len) 142 | { 143 | return lzham::lzham_lib_z_compressBound(source_len); 144 | } 145 | 146 | extern "C" int LZHAM_CDECL lzham_z_inflateInit(lzham_z_streamp pStream) 147 | { 148 | return lzham::lzham_lib_z_inflateInit(pStream); 149 | } 150 | 151 | extern "C" int LZHAM_CDECL lzham_z_inflateInit2(lzham_z_streamp pStream, int window_bits) 152 | { 153 | return lzham::lzham_lib_z_inflateInit2(pStream, window_bits); 154 | } 155 | 156 | extern "C" int LZHAM_CDECL lzham_z_inflateReset(lzham_z_streamp pStream) 157 | { 158 | return lzham::lzham_lib_z_inflateReset(pStream); 159 | } 160 | 161 | extern "C" int LZHAM_CDECL lzham_z_inflate(lzham_z_streamp pStream, int flush) 162 | { 163 | return lzham::lzham_lib_z_inflate(pStream, flush); 164 | } 165 | 166 | extern "C" int LZHAM_CDECL lzham_z_inflateEnd(lzham_z_streamp pStream) 167 | { 168 | return lzham::lzham_lib_z_inflateEnd(pStream); 169 | } 170 | 171 | extern "C" int LZHAM_CDECL lzham_z_uncompress(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len) 172 | { 173 | return lzham::lzham_lib_z_uncompress(pDest, pDest_len, pSource, source_len); 174 | } 175 | 176 | extern "C" const char * LZHAM_CDECL lzham_z_error(int err) 177 | { 178 | return lzham::lzham_lib_z_error(err); 179 | } 180 | -------------------------------------------------------------------------------- /lzhamtest/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | PROJECT(lzhamtest) 2 | cmake_minimum_required(VERSION 2.8) 3 | option(BUILD_X64 "build 64-bit" TRUE) 4 | 5 | message("Initial BUILD_X64=${BUILD_X64}") 6 | message("Initial CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}") 7 | 8 | if( NOT CMAKE_BUILD_TYPE ) 9 | set( CMAKE_BUILD_TYPE Release ) 10 | endif( NOT CMAKE_BUILD_TYPE ) 11 | 12 | message( ${PROJECT_NAME} " build type: " ${CMAKE_BUILD_TYPE} ) 13 | 14 | if (BUILD_X64) 15 | message("Building 64-bit") 16 | else() 17 | message("Building 32-bit") 18 | endif(BUILD_X64) 19 | 20 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -Wall -Wextra") 21 | set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -Wall -Wextra") 22 | 23 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -Wextra -O3 -fomit-frame-pointer -fexpensive-optimizations") 24 | set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -Wextra") 25 | 26 | set(SRC_LIST 27 | timer.cpp 28 | timer.h 29 | lzhamtest.cpp) 30 | 31 | # -fno-strict-aliasing is *required* to compile LZHAM 32 | set(GCC_COMPILE_FLAGS "-fno-strict-aliasing -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64") 33 | 34 | if (NOT BUILD_X64) 35 | set(GCC_COMPILE_FLAGS "${GCC_COMPILE_FLAGS} -m32") 36 | endif() 37 | 38 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_LINK_FLAGS}") 39 | 40 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GCC_COMPILE_FLAGS}") 41 | set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${GCC_COMPILE_FLAGS} -DNDEBUG") 42 | set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${GCC_COMPILE_FLAGS} -D_DEBUG") 43 | 44 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COMPILE_FLAGS}") 45 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${GCC_COMPILE_FLAGS} -DNDEBUG") 46 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${GCC_COMPILE_FLAGS} -D_DEBUG") 47 | 48 | include_directories( 49 | ${PROJECT_SOURCE_DIR}/../lzhamdecomp 50 | ${PROJECT_SOURCE_DIR}/../lzhamcomp 51 | ${PROJECT_SOURCE_DIR}/../include) 52 | 53 | if (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) 54 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin_linux) 55 | endif() 56 | 57 | add_executable(${PROJECT_NAME} ${SRC_LIST}) 58 | 59 | target_link_libraries(${PROJECT_NAME} 60 | lzhamdll) 61 | -------------------------------------------------------------------------------- /lzhamtest/timer.cpp: -------------------------------------------------------------------------------- 1 | // File: timer.cpp 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "timer.h" 9 | 10 | #if defined(WIN32) 11 | #include 12 | #elif defined(_XBOX) 13 | #include 14 | #endif 15 | 16 | unsigned long long timer::g_init_ticks; 17 | unsigned long long timer::g_freq; 18 | double timer::g_inv_freq; 19 | 20 | #if defined(WIN32) || defined(_XBOX) 21 | inline void query_counter(timer_ticks *pTicks) 22 | { 23 | QueryPerformanceCounter(reinterpret_cast(pTicks)); 24 | } 25 | inline void query_counter_frequency(timer_ticks *pTicks) 26 | { 27 | QueryPerformanceFrequency(reinterpret_cast(pTicks)); 28 | } 29 | #elif defined(__GNUC__) 30 | #if defined(__APPLE__) || defined(__FreeBSD__) 31 | #include 32 | #else 33 | #include 34 | #endif 35 | inline void query_counter(timer_ticks *pTicks) 36 | { 37 | struct timeval cur_time; 38 | gettimeofday(&cur_time, NULL); 39 | *pTicks = static_cast(cur_time.tv_sec)*1000000ULL + static_cast(cur_time.tv_usec); 40 | } 41 | inline void query_counter_frequency(timer_ticks *pTicks) 42 | { 43 | *pTicks = 1000000; 44 | } 45 | #endif 46 | 47 | timer::timer() : 48 | m_start_time(0), 49 | m_stop_time(0), 50 | m_started(false), 51 | m_stopped(false) 52 | { 53 | if (!g_inv_freq) 54 | init(); 55 | } 56 | 57 | timer::timer(timer_ticks start_ticks) 58 | { 59 | if (!g_inv_freq) 60 | init(); 61 | 62 | m_start_time = start_ticks; 63 | 64 | m_started = true; 65 | m_stopped = false; 66 | } 67 | 68 | void timer::start(timer_ticks start_ticks) 69 | { 70 | m_start_time = start_ticks; 71 | 72 | m_started = true; 73 | m_stopped = false; 74 | } 75 | 76 | void timer::start() 77 | { 78 | query_counter(&m_start_time); 79 | 80 | m_started = true; 81 | m_stopped = false; 82 | } 83 | 84 | void timer::stop() 85 | { 86 | assert(m_started); 87 | 88 | query_counter(&m_stop_time); 89 | 90 | m_stopped = true; 91 | } 92 | 93 | double timer::get_elapsed_secs() const 94 | { 95 | assert(m_started); 96 | if (!m_started) 97 | return 0; 98 | 99 | timer_ticks stop_time = m_stop_time; 100 | if (!m_stopped) 101 | query_counter(&stop_time); 102 | 103 | timer_ticks delta = stop_time - m_start_time; 104 | return delta * g_inv_freq; 105 | } 106 | 107 | timer_ticks timer::get_elapsed_us() const 108 | { 109 | assert(m_started); 110 | if (!m_started) 111 | return 0; 112 | 113 | timer_ticks stop_time = m_stop_time; 114 | if (!m_stopped) 115 | query_counter(&stop_time); 116 | 117 | timer_ticks delta = stop_time - m_start_time; 118 | return (delta * 1000000ULL + (g_freq >> 1U)) / g_freq; 119 | } 120 | 121 | void timer::init() 122 | { 123 | if (!g_inv_freq) 124 | { 125 | query_counter_frequency(&g_freq); 126 | g_inv_freq = 1.0f / g_freq; 127 | 128 | query_counter(&g_init_ticks); 129 | } 130 | } 131 | 132 | timer_ticks timer::get_init_ticks() 133 | { 134 | if (!g_inv_freq) 135 | init(); 136 | 137 | return g_init_ticks; 138 | } 139 | 140 | timer_ticks timer::get_ticks() 141 | { 142 | if (!g_inv_freq) 143 | init(); 144 | 145 | timer_ticks ticks; 146 | query_counter(&ticks); 147 | return ticks - g_init_ticks; 148 | } 149 | 150 | double timer::ticks_to_secs(timer_ticks ticks) 151 | { 152 | if (!g_inv_freq) 153 | init(); 154 | 155 | return ticks * g_inv_freq; 156 | } 157 | 158 | -------------------------------------------------------------------------------- /lzhamtest/timer.h: -------------------------------------------------------------------------------- 1 | // File: timer.h 2 | // See Copyright Notice and license at the end of include/lzham.h 3 | #pragma once 4 | 5 | typedef unsigned long long timer_ticks; 6 | 7 | class timer 8 | { 9 | public: 10 | timer(); 11 | timer(timer_ticks start_ticks); 12 | 13 | void start(); 14 | void start(timer_ticks start_ticks); 15 | 16 | void stop(); 17 | 18 | double get_elapsed_secs() const; 19 | inline double get_elapsed_ms() const { return get_elapsed_secs() * 1000.0f; } 20 | timer_ticks get_elapsed_us() const; 21 | 22 | static void init(); 23 | static inline timer_ticks get_ticks_per_sec() { return g_freq; } 24 | static timer_ticks get_init_ticks(); 25 | static timer_ticks get_ticks(); 26 | static double ticks_to_secs(timer_ticks ticks); 27 | static inline double ticks_to_ms(timer_ticks ticks) { return ticks_to_secs(ticks) * 1000.0f; } 28 | static inline double get_secs() { return ticks_to_secs(get_ticks()); } 29 | static inline double get_ms() { return ticks_to_ms(get_ticks()); } 30 | 31 | private: 32 | static timer_ticks g_init_ticks; 33 | static timer_ticks g_freq; 34 | static double g_inv_freq; 35 | 36 | timer_ticks m_start_time; 37 | timer_ticks m_stop_time; 38 | 39 | bool m_started : 1; 40 | bool m_stopped : 1; 41 | }; 42 | --------------------------------------------------------------------------------