Skip to content

Commit

Permalink
Updated s2p2bin
Browse files Browse the repository at this point in the history
  • Loading branch information
Clownacy committed May 19, 2019
1 parent 09b6e87 commit 7453d55
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 94 deletions.
4 changes: 2 additions & 2 deletions extra/Build tools/build_source/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
CFLAGS := -O3 -s -std=c99
CFLAGS := -std=c99 -O2 -s -fno-ident -flto

s2p2bin: s2p2bin.c clownlzss/clownlzss.c clownlzss/kosinski.c clownlzss/memory_stream.c
s2p2bin: s2p2bin.c clownlzss/common.c clownlzss/kosinski.c clownlzss/memory_stream.c
$(CC) $(CFLAGS) -o $@ $^
32 changes: 13 additions & 19 deletions extra/Build tools/build_source/clownlzss/clownlzss.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@

#include <limits.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>

#include "memory_stream.h"

#define CLOWNLZSS_MIN(a, b) (a) < (b) ? (a) : (b)
#define CLOWNLZSS_MAX(a, b) (a) > (b) ? (a) : (b)

Expand All @@ -16,7 +13,7 @@ typedef struct ClownLZSS_GraphEdge
{
unsigned int cost;
size_t next_node_index;
};
} u;
size_t previous_node_index;
size_t match_length;
size_t match_offset;
Expand All @@ -27,9 +24,9 @@ void NAME(TYPE *data, size_t data_size, void *user)\
{\
ClownLZSS_GraphEdge *node_meta_array = (ClownLZSS_GraphEdge*)malloc((data_size + 1) * sizeof(ClownLZSS_GraphEdge)); /* +1 for the end-node */\
\
node_meta_array[0].cost = 0;\
node_meta_array[0].u.cost = 0;\
for (size_t i = 1; i < data_size + 1; ++i)\
node_meta_array[i].cost = UINT_MAX;\
node_meta_array[i].u.cost = UINT_MAX;\
\
for (size_t i = 0; i < data_size; ++i)\
{\
Expand All @@ -46,9 +43,9 @@ void NAME(TYPE *data, size_t data_size, void *user)\
{\
const unsigned int cost = MATCH_COST_CALLBACK(i - j, k + 1, user);\
\
if (cost && node_meta_array[i + k + 1].cost > node_meta_array[i].cost + cost)\
if (cost && node_meta_array[i + k + 1].u.cost > node_meta_array[i].u.cost + cost)\
{\
node_meta_array[i + k + 1].cost = node_meta_array[i].cost + cost;\
node_meta_array[i + k + 1].u.cost = node_meta_array[i].u.cost + cost;\
node_meta_array[i + k + 1].previous_node_index = i;\
node_meta_array[i + k + 1].match_length = k + 1;\
node_meta_array[i + k + 1].match_offset = j;\
Expand All @@ -59,22 +56,22 @@ void NAME(TYPE *data, size_t data_size, void *user)\
}\
}\
\
if (node_meta_array[i + 1].cost >= node_meta_array[i].cost + LITERAL_COST)\
if (node_meta_array[i + 1].u.cost >= node_meta_array[i].u.cost + LITERAL_COST)\
{\
node_meta_array[i + 1].cost = node_meta_array[i].cost + LITERAL_COST;\
node_meta_array[i + 1].u.cost = node_meta_array[i].u.cost + LITERAL_COST;\
node_meta_array[i + 1].previous_node_index = i;\
node_meta_array[i + 1].match_length = 0;\
}\
}\
\
node_meta_array[0].previous_node_index = SIZE_MAX;\
node_meta_array[data_size].next_node_index = SIZE_MAX;\
for (size_t node_index = data_size; node_meta_array[node_index].previous_node_index != SIZE_MAX; node_index = node_meta_array[node_index].previous_node_index)\
node_meta_array[node_meta_array[node_index].previous_node_index].next_node_index = node_index;\
node_meta_array[0].previous_node_index = (size_t)-1;\
node_meta_array[data_size].u.next_node_index = (size_t)-1;\
for (size_t node_index = data_size; node_meta_array[node_index].previous_node_index != (size_t)-1; node_index = node_meta_array[node_index].previous_node_index)\
node_meta_array[node_meta_array[node_index].previous_node_index].u.next_node_index = node_index;\
\
for (size_t node_index = 0; node_meta_array[node_index].next_node_index != SIZE_MAX; node_index = node_meta_array[node_index].next_node_index)\
for (size_t node_index = 0; node_meta_array[node_index].u.next_node_index != (size_t)-1; node_index = node_meta_array[node_index].u.next_node_index)\
{\
const size_t next_index = node_meta_array[node_index].next_node_index;\
const size_t next_index = node_meta_array[node_index].u.next_node_index;\
const size_t length = node_meta_array[next_index].match_length;\
const size_t offset = node_meta_array[next_index].match_offset;\
\
Expand All @@ -86,6 +83,3 @@ void NAME(TYPE *data, size_t data_size, void *user)\
\
free(node_meta_array);\
}

unsigned char* ClownLZSS_RegularWrapper(unsigned char *data, size_t data_size, size_t *compressed_size, void (*function)(unsigned char *data, size_t data_size, MemoryStream *output_stream));
unsigned char* ClownLZSS_ModuledCompressionWrapper(unsigned char *data, size_t data_size, size_t *compressed_size, void (*function)(unsigned char *data, size_t data_size, MemoryStream *output_stream), size_t module_size, size_t module_alignment);
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
#include "clownlzss.h"
#include "common.h"

#include <stddef.h>
#include <stdlib.h>

#include "memory_stream.h"

unsigned char* ClownLZSS_RegularWrapper(unsigned char *data, size_t data_size, size_t *compressed_size, void (*function)(unsigned char *data, size_t data_size, MemoryStream *output_stream))
unsigned char* RegularWrapper(unsigned char *data, size_t data_size, size_t *compressed_size, void *user_data, void (*function)(unsigned char *data, size_t data_size, MemoryStream *output_stream, void *user_data))
{
MemoryStream *output_stream = MemoryStream_Create(0x1000, false);

function(data, data_size, output_stream);
function(data, data_size, output_stream, user_data);

unsigned char *out_buffer = MemoryStream_GetBuffer(output_stream);

Expand All @@ -21,11 +21,11 @@ unsigned char* ClownLZSS_RegularWrapper(unsigned char *data, size_t data_size, s
return out_buffer;
}

unsigned char* ClownLZSS_ModuledCompressionWrapper(unsigned char *data, size_t data_size, size_t *out_compressed_size, void (*function)(unsigned char *data, size_t data_size, MemoryStream *output_stream), size_t module_size, size_t module_alignment)
unsigned char* ModuledCompressionWrapper(unsigned char *data, size_t data_size, size_t *out_compressed_size, void *user_data, void (*function)(unsigned char *data, size_t data_size, MemoryStream *output_stream, void *user_data), size_t module_size, size_t module_alignment)
{
MemoryStream *output_stream = MemoryStream_Create(0x1000, false);

const unsigned short header = (data_size % module_size) | ((data_size / module_size) << 12);
const unsigned short header = (unsigned short)((data_size % module_size) | ((data_size / module_size) << 12));

MemoryStream_WriteByte(output_stream, header >> 8);
MemoryStream_WriteByte(output_stream, header & 0xFF);
Expand All @@ -37,7 +37,7 @@ unsigned char* ClownLZSS_ModuledCompressionWrapper(unsigned char *data, size_t d
MemoryStream_WriteByte(output_stream, 0);

const size_t start = MemoryStream_GetPosition(output_stream);
function(data + i, module_size < data_size - i ? module_size : data_size - i, output_stream);
function(data + i, module_size < data_size - i ? module_size : data_size - i, output_stream, user_data);
compressed_size = MemoryStream_GetPosition(output_stream) - start;
}

Expand Down
8 changes: 8 additions & 0 deletions extra/Build tools/build_source/clownlzss/common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once

#include <stddef.h>

#include "memory_stream.h"

unsigned char* RegularWrapper(unsigned char *data, size_t data_size, size_t *compressed_size, void *user_data, void (*function)(unsigned char *data, size_t data_size, MemoryStream *output_stream, void *user_data));
unsigned char* ModuledCompressionWrapper(unsigned char *data, size_t data_size, size_t *compressed_size, void *user_data, void (*function)(unsigned char *data, size_t data_size, MemoryStream *output_stream, void *user_data), size_t module_size, size_t module_alignment);
115 changes: 62 additions & 53 deletions extra/Build tools/build_source/clownlzss/kosinski.c
Original file line number Diff line number Diff line change
@@ -1,88 +1,95 @@
#include "kosinski.h"

#ifndef __cplusplus
#include <stdbool.h>
#endif
#include <stddef.h>

#include "clownlzss.h"
#include "common.h"
#include "memory_stream.h"

#define TOTAL_DESCRIPTOR_BITS 16

static MemoryStream *output_stream;
static MemoryStream *match_stream;
typedef struct KosinskiInstance
{
MemoryStream *output_stream;
MemoryStream *match_stream;

static unsigned short descriptor;
static unsigned int descriptor_bits_remaining;
unsigned short descriptor;
unsigned int descriptor_bits_remaining;
} KosinskiInstance;

static void FlushData(void)
static void FlushData(KosinskiInstance *instance)
{
MemoryStream_WriteByte(output_stream, descriptor & 0xFF);
MemoryStream_WriteByte(output_stream, descriptor >> 8);
MemoryStream_WriteByte(instance->output_stream, instance->descriptor & 0xFF);
MemoryStream_WriteByte(instance->output_stream, instance->descriptor >> 8);

const size_t match_buffer_size = MemoryStream_GetPosition(match_stream);
unsigned char *match_buffer = MemoryStream_GetBuffer(match_stream);
const size_t match_buffer_size = MemoryStream_GetPosition(instance->match_stream);
unsigned char *match_buffer = MemoryStream_GetBuffer(instance->match_stream);

MemoryStream_WriteBytes(output_stream, match_buffer, match_buffer_size);
MemoryStream_WriteBytes(instance->output_stream, match_buffer, match_buffer_size);
}

static void PutMatchByte(unsigned char byte)
static void PutMatchByte(KosinskiInstance *instance, unsigned char byte)
{
MemoryStream_WriteByte(match_stream, byte);
MemoryStream_WriteByte(instance->match_stream, byte);
}

static void PutDescriptorBit(bool bit)
static void PutDescriptorBit(KosinskiInstance *instance, bool bit)
{
--descriptor_bits_remaining;
--instance->descriptor_bits_remaining;

descriptor >>= 1;
instance->descriptor >>= 1;

if (bit)
descriptor |= 1 << (TOTAL_DESCRIPTOR_BITS - 1);
instance->descriptor |= 1 << (TOTAL_DESCRIPTOR_BITS - 1);

if (descriptor_bits_remaining == 0)
if (instance->descriptor_bits_remaining == 0)
{
FlushData();
FlushData(instance);

descriptor_bits_remaining = TOTAL_DESCRIPTOR_BITS;
MemoryStream_Rewind(match_stream);
instance->descriptor_bits_remaining = TOTAL_DESCRIPTOR_BITS;
MemoryStream_Rewind(instance->match_stream);
}
}

static void DoLiteral(unsigned char value, void *user)
{
(void)user;
KosinskiInstance *instance = (KosinskiInstance*)user;

PutDescriptorBit(1);
PutMatchByte(value);
PutDescriptorBit(instance, 1);
PutMatchByte(instance, value);
}

static void DoMatch(size_t distance, size_t length, size_t offset, void *user)
{
(void)offset;
(void)user;

KosinskiInstance *instance = (KosinskiInstance*)user;

if (length >= 2 && length <= 5 && distance <= 256)
{
PutDescriptorBit(0);
PutDescriptorBit(0);
PutDescriptorBit((length - 2) & 2);
PutDescriptorBit((length - 2) & 1);
PutMatchByte(-distance);
PutDescriptorBit(instance, 0);
PutDescriptorBit(instance, 0);
PutDescriptorBit(instance, (length - 2) & 2);
PutDescriptorBit(instance, (length - 2) & 1);
PutMatchByte(instance, (unsigned char)-distance);
}
else if (length >= 3 && length <= 9)
{
PutDescriptorBit(0);
PutDescriptorBit(1);
PutMatchByte(-distance & 0xFF);
PutMatchByte(((-distance >> (8 - 3)) & 0xF8) | ((length - 2) & 7));
PutDescriptorBit(instance, 0);
PutDescriptorBit(instance, 1);
PutMatchByte(instance, -distance & 0xFF);
PutMatchByte(instance, ((-distance >> (8 - 3)) & 0xF8) | ((length - 2) & 7));
}
else //if (length >= 3)
{
PutDescriptorBit(0);
PutDescriptorBit(1);
PutMatchByte(-distance & 0xFF);
PutMatchByte((-distance >> (8 - 3)) & 0xF8);
PutMatchByte(length - 1);
PutDescriptorBit(instance, 0);
PutDescriptorBit(instance, 1);
PutMatchByte(instance, -distance & 0xFF);
PutMatchByte(instance, (-distance >> (8 - 3)) & 0xF8);
PutMatchByte(instance, (unsigned char)(length - 1));
}
}

Expand Down Expand Up @@ -111,34 +118,36 @@ static void FindExtraMatches(unsigned char *data, size_t data_size, size_t offse

static CLOWNLZSS_MAKE_COMPRESSION_FUNCTION(CompressData, unsigned char, 0x100, 0x2000, FindExtraMatches, 1 + 8, DoLiteral, GetMatchCost, DoMatch)

static void KosinskiCompressStream(unsigned char *data, size_t data_size, MemoryStream *p_output_stream)
static void KosinskiCompressStream(unsigned char *data, size_t data_size, MemoryStream *output_stream, void *user)
{
output_stream = p_output_stream;
(void)user;

match_stream = MemoryStream_Create(0x10, true);
descriptor_bits_remaining = TOTAL_DESCRIPTOR_BITS;
KosinskiInstance instance;
instance.output_stream = output_stream;
instance.match_stream = MemoryStream_Create(0x10, true);
instance.descriptor_bits_remaining = TOTAL_DESCRIPTOR_BITS;

CompressData(data, data_size, NULL);
CompressData(data, data_size, &instance);

// Terminator match
PutDescriptorBit(0);
PutDescriptorBit(1);
PutMatchByte(0x00);
PutMatchByte(0xF0);
PutMatchByte(0x00);
PutDescriptorBit(&instance, 0);
PutDescriptorBit(&instance, 1);
PutMatchByte(&instance, 0x00);
PutMatchByte(&instance, 0xF0);
PutMatchByte(&instance, 0x00);

descriptor >>= descriptor_bits_remaining;
FlushData();
instance.descriptor >>= instance.descriptor_bits_remaining;
FlushData(&instance);

MemoryStream_Destroy(match_stream);
MemoryStream_Destroy(instance.match_stream);
}

unsigned char* KosinskiCompress(unsigned char *data, size_t data_size, size_t *compressed_size)
{
return ClownLZSS_RegularWrapper(data, data_size, compressed_size, KosinskiCompressStream);
return RegularWrapper(data, data_size, compressed_size, NULL, KosinskiCompressStream);
}

unsigned char* ModuledKosinskiCompress(unsigned char *data, size_t data_size, size_t *compressed_size, size_t module_size)
{
return ClownLZSS_ModuledCompressionWrapper(data, data_size, compressed_size, KosinskiCompressStream, module_size, 0x10);
return ModuledCompressionWrapper(data, data_size, compressed_size, NULL, KosinskiCompressStream, module_size, 0x10);
}
15 changes: 8 additions & 7 deletions extra/Build tools/build_source/clownlzss/memory_stream.c
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
#include "memory_stream.h"

#ifndef __cplusplus
#include <stdbool.h>
#endif
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

typedef struct MemoryStream
struct MemoryStream
{
unsigned char *buffer;
size_t position;
size_t end;
size_t size;
size_t growth;
bool free_buffer_when_destroyed;
} MemoryStream;
};

static void ResizeIfNeeded(MemoryStream *memory_stream, size_t minimum_needed_size)
{
Expand Down Expand Up @@ -75,18 +76,18 @@ size_t MemoryStream_GetPosition(MemoryStream *memory_stream)
return memory_stream->position;
}

void MemoryStream_SetPosition(MemoryStream *memory_stream, intmax_t offset, enum MemoryStream_Origin origin)
void MemoryStream_SetPosition(MemoryStream *memory_stream, ptrdiff_t offset, enum MemoryStream_Origin origin)
{
switch (origin)
{
case MEMORYSTREAM_START:
memory_stream->position = offset;
memory_stream->position = (size_t)offset;
break;
case MEMORYSTREAM_CURRENT:
memory_stream->position += offset;
memory_stream->position = (size_t)(memory_stream->position + offset);
break;
case MEMORYSTREAM_END:
memory_stream->position = memory_stream->end + offset;
memory_stream->position = (size_t)(memory_stream->end + offset);
break;
}
}
Expand Down
5 changes: 3 additions & 2 deletions extra/Build tools/build_source/clownlzss/memory_stream.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#pragma once

#ifndef __cplusplus
#include <stdbool.h>
#endif
#include <stddef.h>
#include <stdint.h>

typedef struct MemoryStream MemoryStream;

Expand All @@ -19,5 +20,5 @@ void MemoryStream_WriteByte(MemoryStream *memory_stream, unsigned char byte);
void MemoryStream_WriteBytes(MemoryStream *memory_stream, unsigned char *bytes, size_t byte_count);
unsigned char* MemoryStream_GetBuffer(MemoryStream *memory_stream);
size_t MemoryStream_GetPosition(MemoryStream *memory_stream);
void MemoryStream_SetPosition(MemoryStream *memory_stream, intmax_t offset, enum MemoryStream_Origin origin);
void MemoryStream_SetPosition(MemoryStream *memory_stream, ptrdiff_t offset, enum MemoryStream_Origin origin);
void MemoryStream_Rewind(MemoryStream *memory_stream);
Loading

0 comments on commit 7453d55

Please sign in to comment.