-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Alex Ionescu
committed
Apr 16, 2020
1 parent
8b1bdaf
commit 2ee81c1
Showing
15 changed files
with
2,451 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,3 +9,4 @@ install_manifest.txt | |
compile_commands.json | ||
CTestTestfile.cmake | ||
_deps | ||
.vs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
cmake_minimum_required (VERSION 3.8) | ||
project (minlzma) | ||
|
||
add_subdirectory(minlzlib) | ||
add_subdirectory(minlzdec) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
{ | ||
"configurations": [ | ||
{ | ||
"name": "win-amd64", | ||
"generator": "Ninja", | ||
"configurationType": "Debug", | ||
"inheritEnvironments": [ "msvc_x64_x64" ], | ||
"buildRoot": "${projectDir}\\out\\build\\${name}", | ||
"installRoot": "${projectDir}\\out\\install\\${name}", | ||
"cmakeCommandArgs": "", | ||
"buildCommandArgs": "-v", | ||
"ctestCommandArgs": "", | ||
"variables": [] | ||
}, | ||
{ | ||
"name": "wsl-amd64", | ||
"generator": "Ninja", | ||
"configurationType": "Debug", | ||
"buildRoot": "${projectDir}\\out\\build\\${name}", | ||
"installRoot": "${projectDir}\\out\\install\\${name}", | ||
"cmakeExecutable": "/usr/bin/cmake", | ||
"cmakeCommandArgs": "", | ||
"buildCommandArgs": "", | ||
"ctestCommandArgs": "", | ||
"inheritEnvironments": [ "linux_clang_x64" ], | ||
"wslPath": "${defaultWSLPath}", | ||
"addressSanitizerRuntimeFlags": "detect_leaks=0", | ||
"variables": [] | ||
}, | ||
{ | ||
"name": "win-release-amd64", | ||
"generator": "Ninja", | ||
"configurationType": "RelWithDebInfo", | ||
"buildRoot": "${projectDir}\\out\\build\\${name}", | ||
"installRoot": "${projectDir}\\out\\install\\${name}", | ||
"cmakeCommandArgs": "", | ||
"buildCommandArgs": "-v", | ||
"ctestCommandArgs": "", | ||
"inheritEnvironments": [ "msvc_x64_x64" ], | ||
"variables": [] | ||
}, | ||
{ | ||
"name": "wsl-release-amd64", | ||
"generator": "Ninja", | ||
"configurationType": "RelWithDebInfo", | ||
"buildRoot": "${projectDir}\\out\\build\\${name}", | ||
"installRoot": "${projectDir}\\out\\install\\${name}", | ||
"cmakeExecutable": "/usr/bin/cmake", | ||
"cmakeCommandArgs": "", | ||
"buildCommandArgs": "", | ||
"ctestCommandArgs": "", | ||
"inheritEnvironments": [ "linux_clang_x64" ], | ||
"wslPath": "${defaultWSLPath}", | ||
"addressSanitizerRuntimeFlags": "detect_leaks=0", | ||
"variables": [] | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
cmake_minimum_required (VERSION 3.8) | ||
|
||
if(!MSVC) | ||
add_compile_options(-Wno-undefined-inline) | ||
endif() | ||
|
||
add_library (minlzlib STATIC "inputbuf.c" "dictbuf.c" "lzma2dec.c" "lzmadec.c" "rangedec.c" "xzstream.c" "lzmadec.h" "xzstream.h" "minlzlib.h") | ||
set_target_properties(minlzlib PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED YES C_EXTENSIONS NO) | ||
target_include_directories (minlzlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) | ||
|
||
if(MSVC) | ||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "/Ox /Ob2 /Oi /Ot /Oy /GF /GL /Gy /MD /Zi /DNDEBUG") | ||
endif() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
{ | ||
"configurations": [ | ||
{ | ||
"name": "x64-Debug", | ||
"generator": "Ninja", | ||
"configurationType": "Debug", | ||
"inheritEnvironments": [ "msvc_x64_x64" ], | ||
"buildRoot": "${projectDir}\\out\\build\\${name}", | ||
"installRoot": "${projectDir}\\out\\install\\${name}", | ||
"cmakeCommandArgs": "", | ||
"buildCommandArgs": "-v", | ||
"ctestCommandArgs": "", | ||
"variables": [] | ||
}, | ||
{ | ||
"name": "WSL-Clang-Debug", | ||
"generator": "Ninja", | ||
"configurationType": "Debug", | ||
"buildRoot": "${projectDir}\\out\\build\\${name}", | ||
"installRoot": "${projectDir}\\out\\install\\${name}", | ||
"cmakeExecutable": "/usr/bin/cmake", | ||
"cmakeCommandArgs": "", | ||
"buildCommandArgs": "", | ||
"ctestCommandArgs": "", | ||
"inheritEnvironments": [ "linux_clang_x64" ], | ||
"wslPath": "${defaultWSLPath}", | ||
"addressSanitizerRuntimeFlags": "detect_leaks=0", | ||
"variables": [] | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
/*++ | ||
Copyright (c) Alex Ionescu. All rights reserved. | ||
Module Name: | ||
dictbuf.c | ||
Abstract: | ||
This module implements the management of the LZMA "history buffer" which is | ||
often called the "dictionary". Routines for writing into the history buffer | ||
as well as for reading back from it are implemented, as well as mechanisms | ||
for repeating previous symbols forward into the dictionary. This forms the | ||
basis for LZMA match distance-length pairs that are found and decompressed. | ||
Note that for simplicity's sake, the dictionary is stored directly in the | ||
output buffer, such that no "flushing" or copying is needed back and forth. | ||
Author: | ||
Alex Ionescu (@aionescu) 15-Apr-2020 - Initial version | ||
Environment: | ||
Windows & Linux, user mode and kernel mode. | ||
--*/ | ||
|
||
#include "minlzlib.h" | ||
|
||
// | ||
// State used for the history buffer (dictionary) | ||
// | ||
typedef struct _DICTIONARY_STATE | ||
{ | ||
// | ||
// Buffer, start position, current position, and offset limit in the buffer | ||
// | ||
uint8_t* Buffer; | ||
uint32_t Start; | ||
uint32_t Offset; | ||
uint32_t Limit; | ||
uint32_t Size; | ||
} DICTIONARY_STATE, *PDICTIONARY_STATE; | ||
DICTIONARY_STATE g_Dictionary; | ||
PDICTIONARY_STATE Dictionary = &g_Dictionary; | ||
|
||
void | ||
DtInitialize ( | ||
uint8_t* HistoryBuffer, | ||
uint32_t Size | ||
) | ||
{ | ||
// | ||
// Initialize the buffer and reset the position | ||
// | ||
Dictionary->Buffer = HistoryBuffer; | ||
Dictionary->Offset = 0; | ||
Dictionary->Size = Size; | ||
} | ||
|
||
bool | ||
DtSetLimit ( | ||
uint32_t Limit | ||
) | ||
{ | ||
// | ||
// Make sure that the passed in dictionary limit fits within the size, and | ||
// then set this as the new limit. Save the starting point (current offset) | ||
// | ||
if ((Dictionary->Offset + Limit) > Dictionary->Size) | ||
{ | ||
return false; | ||
} | ||
Dictionary->Limit = Dictionary->Offset + Limit; | ||
Dictionary->Start = Dictionary->Offset; | ||
return true; | ||
} | ||
|
||
bool | ||
DtIsComplete ( | ||
uint32_t* BytesProcessed | ||
) | ||
{ | ||
// | ||
// Return bytes processed and if the dictionary has been fully written to | ||
// | ||
*BytesProcessed = Dictionary->Offset - Dictionary->Start; | ||
return (Dictionary->Offset == Dictionary->Limit); | ||
} | ||
|
||
bool | ||
DtCanWrite ( | ||
uint32_t* Position | ||
) | ||
{ | ||
// | ||
// Return our position and make sure it's not beyond the uncompressed size | ||
// | ||
*Position = Dictionary->Offset; | ||
return (Dictionary->Offset < Dictionary->Limit); | ||
} | ||
|
||
uint8_t | ||
DtGetSymbol ( | ||
uint32_t Distance | ||
) | ||
{ | ||
// | ||
// If the dictionary is still empty, just return 0, otherwise, return the | ||
// symbol that is Distance bytes backward | ||
// | ||
if (Distance > Dictionary->Offset) | ||
{ | ||
return 0; | ||
} | ||
return Dictionary->Buffer[Dictionary->Offset - Distance]; | ||
} | ||
|
||
void | ||
DtPutSymbol ( | ||
uint8_t Symbol | ||
) | ||
{ | ||
// | ||
// Write the symbol and advance our position | ||
// | ||
Dictionary->Buffer[Dictionary->Offset++] = Symbol; | ||
} | ||
|
||
bool | ||
DtRepeatSymbol ( | ||
uint32_t Length, | ||
uint32_t Distance | ||
) | ||
{ | ||
// | ||
// Make sure we never get asked to write past the end of the dictionary, | ||
// then rewrite the stream of symbols forward into the dictionary | ||
// | ||
if ((Length + Dictionary->Offset) > Dictionary->Limit) | ||
{ | ||
return false; | ||
} | ||
|
||
do | ||
{ | ||
DtPutSymbol(DtGetSymbol(Distance)); | ||
} while (--Length > 0); | ||
return true; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
/*++ | ||
Copyright (c) Alex Ionescu. All rights reserved. | ||
Module Name: | ||
inputbuf.c | ||
Abstract: | ||
This module implements helper functions for managing the input buffer that | ||
contains arithmetic-coded LZ77 match distance-length pairs and raw literals | ||
Both seeking (such that an external reader can refer to multiple bytes) and | ||
reading (capturing) an individual byte are supported. Support for aligning | ||
input data to 4 bytes (which is a requirement for XZ-encoded files) is also | ||
implemented. | ||
Author: | ||
Alex Ionescu (@aionescu) 15-Apr-2020 - Initial version | ||
Environment: | ||
Windows & Linux, user mode and kernel mode. | ||
--*/ | ||
|
||
#include "minlzlib.h" | ||
|
||
// | ||
// Input Buffer State | ||
// | ||
typedef struct _BUFFER_STATE | ||
{ | ||
// | ||
// Start of the buffer, current offset, and total input size | ||
// | ||
uint8_t* Buffer; | ||
uint32_t Offset; | ||
uint32_t Size; | ||
} BUFFER_STATE, * PBUFFER_STATE; | ||
BUFFER_STATE g_In; | ||
PBUFFER_STATE In = &g_In; | ||
|
||
bool | ||
BfAlign ( | ||
void | ||
) | ||
{ | ||
uint8_t padByte; | ||
// | ||
// Keep reading until we reach 32-bit alignment. All bytes must be zero. | ||
// | ||
while (In->Offset & 3) | ||
{ | ||
if (!BfRead(&padByte) || (padByte != 0)) | ||
{ | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
bool | ||
BfSeek ( | ||
uint32_t Length, | ||
uint8_t** Bytes | ||
) | ||
{ | ||
// | ||
// Make sure the input buffer has enough space to seek the desired size, if | ||
// it does, return the current position and then seek past the desired size | ||
// | ||
if ((In->Offset + Length) > In->Size) | ||
{ | ||
*Bytes = 0; | ||
return false; | ||
} | ||
*Bytes = &In->Buffer[In->Offset]; | ||
In->Offset += Length; | ||
return true; | ||
} | ||
|
||
bool | ||
BfRead ( | ||
uint8_t* Byte | ||
) | ||
{ | ||
uint8_t* pByte; | ||
// | ||
// Seek past the byte and read it | ||
// | ||
if (!BfSeek(sizeof(*Byte), &pByte)) | ||
{ | ||
*Byte = 0; | ||
return false; | ||
} | ||
*Byte = *pByte; | ||
return true; | ||
} | ||
|
||
void | ||
BfInitialize ( | ||
uint8_t* InputBuffer, | ||
uint32_t InputSize | ||
) | ||
{ | ||
// | ||
// Save all the data in the context buffer state | ||
// | ||
In->Buffer = InputBuffer; | ||
In->Size = InputSize; | ||
In->Offset = 0; | ||
} |
Oops, something went wrong.