diff options
Diffstat (limited to 'source/archived/network_compression.c')
| -rw-r--r-- | source/archived/network_compression.c | 154 | 
1 files changed, 154 insertions, 0 deletions
| diff --git a/source/archived/network_compression.c b/source/archived/network_compression.c new file mode 100644 index 0000000..eef9e3c --- /dev/null +++ b/source/archived/network_compression.c @@ -0,0 +1,154 @@ +#include <strings.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <wchar.h> +#include <fcntl.h> +#include <assert.h> +#include <stddef.h> +#include <stdint.h> + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; + +size_t +GetMaximumCompressedOutputSize(size_t FileSize) +{ +    // TODO: figure out equation +    return FileSize*2 + 256; +} + +u32 +RLECompress(size_t InSize, u8* In, size_t MaxOutSize, u8* OutBase) +{ +    u8* Out = OutBase; + +#define MAX_LITERAL_COUNT 255 +#define MAX_RUN_COUNT 255 +    u32 LiteralCount = 0; +    u8 Literals[MAX_LITERAL_COUNT] = {0}; + +    u8 *InEnd = In + InSize; +    while(In < InEnd) +    { +        u8 StartingValue = In[0]; +        size_t Run = 1; // first one is the character itself +        while((Run < (InEnd - In)) && +              (Run < MAX_RUN_COUNT) && +              (In[Run] == StartingValue)) +        { +            ++Run; +        } + +        if ((Run > 1) || +            (LiteralCount == MAX_LITERAL_COUNT)) // stop doing runs when there is no +                                                // space left in the buffer. +        { +            // Encode a literal/run pair +            u8 LiteralCount8 = (u8)LiteralCount; +            assert(LiteralCount8 == LiteralCount); +            *Out++ = LiteralCount8; + +            for(u32 LiteralIndex = 0; +                LiteralIndex < LiteralCount; +                ++LiteralIndex) +            { +                *Out++ = Literals[LiteralIndex]; +            } +            LiteralCount = 0; + +            u8 Run8 = (u8)Run; +            assert(Run8 == Run); +            *Out++ = Run8; + +            *Out++ = StartingValue; + +            In += Run; +        } +        else +        { +            // Buffer literals, you have to because we are encoding them in pairs +            Literals[LiteralCount++] = StartingValue; +            ++In; +        } + +    } +#undef MAX_LITERAL_COUNT +#undef MAX_RUN_COUNT + +    assert(In == InEnd); + +    size_t OutSize = Out - OutBase; +    assert(OutSize <= MaxOutSize); + +    return OutSize; +} + +void +RLEDecompress(size_t InSize, u8* In, size_t OutSize, u8* Out) +{ +    u8 *InEnd = In + InSize; +    while(In < InEnd) +    { +        // TODO: I think Casey made a mistake and this should be an u8 +        u8 LiteralCount = *In++; +        while(LiteralCount--) +        { +            *Out++ = *In++; +        } + +        // Alternate to Run +        u8 RepCount = *In++; +        u8 RepValue = *In++; +        while(RepCount--) +        { +            *Out++ = RepValue; +        } +    } + +    assert(In == InEnd); +} + +int main(int Argc, char* Argv[]) { + +    if (Argc < 2) +    { +        fprintf(stderr, "Usage: %s [compress|decompress]\n", Argv[0]); +        return 1; +    } + +    char* Command = Argv[1]; + +    if (!strcmp(Command, "compress")) +    { +        u32* Message = (u32*)L"abcabcbbbbbbb"; +        size_t MessageSize = wcslen((const wchar_t*)Message) * 4; +         +        size_t OutBufferSize = GetMaximumCompressedOutputSize(MessageSize); +        u8 OutBuffer[OutBufferSize + 8]; +        bzero(OutBuffer, OutBufferSize + 8); +        *(u32*)OutBuffer = MessageSize; + +        size_t CompressedSize = RLECompress(MessageSize, (u8*)Message, OutBufferSize, OutBuffer + 8); + +        s32 OutFile = open("test.compressed", O_WRONLY | O_CREAT, 0600); + +        write(OutFile, OutBuffer, CompressedSize); + +        fprintf(stdout, "%lu -> %lu bytes\n", MessageSize, CompressedSize); +    } +    else if (!strcmp(Command, "decompress")) +    { +        fprintf(stderr, "Not implemented yet.\n"); +    } +    else +        fprintf(stderr, "Unknown command: '%s'\n", Command); + +    return 0; +} | 
