Add startings of new kernel-side library
Lainlib is libk. It is separate from Helix, which will become the 3D engine common to the kernel and the userspace.
This commit is contained in:
parent
61dbcc0dec
commit
a915465fc1
327
chroma/inc/lainlib/compression/lzg.h
Normal file
327
chroma/inc/lainlib/compression/lzg.h
Normal file
|
@ -0,0 +1,327 @@
|
|||
/* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* This file is part of liblzg.
|
||||
*
|
||||
* Copyright (c) 2010-2018 Marcus Geelnard
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would
|
||||
* be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not
|
||||
* be misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
|
||||
#ifndef _LIBLZG_H_
|
||||
#define _LIBLZG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LZG_VERSION "1.0.10" /**< @brief LZG library version string */
|
||||
#define LZG_VERNUM 0x0100000a /**< @brief LZG library version number (strictly
|
||||
incremental) */
|
||||
#define LZG_VER_MAJOR 1 /**< @brief LZG library major version */
|
||||
#define LZG_VER_MINOR 0 /**< @brief LZG library minor version */
|
||||
#define LZG_VER_REVISION 10 /**< @brief LZG library revision */
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @mainpage
|
||||
*
|
||||
* @section intro_sec Introduction
|
||||
*
|
||||
* liblzg is a minimal implementation of an LZ77 class compression library. The
|
||||
* main characteristic of the library is that the decoding routine is very
|
||||
* simple, fast and requires no extra memory (except for the encoded and decoded
|
||||
* data buffers).
|
||||
*
|
||||
* @section funcs_sec Functions
|
||||
*
|
||||
* @li LZG_MaxEncodedSize() - Determine the maximum size of the encoded data for
|
||||
* a given uncompressed buffer (worst case).
|
||||
* @li LZG_InitEncoderConfig() - Set default encoder configuration.
|
||||
* @li LZG_Encode() - Encode uncompressed data as LZG coded data.
|
||||
* @li LZG_EncodeFull() - Same as LZG_Encode(), but using custom memory
|
||||
* allocation.
|
||||
* @li LZG_WorkMemSize() - Determine the amount of memory required for encoding
|
||||
* (useful for LZG_EncodeFull()).
|
||||
*
|
||||
* @li LZG_DecodedSize() - Determine the size of the decoded data for a given
|
||||
* LZG coded buffer.
|
||||
* @li LZG_Decode() - Decode LZG coded data.
|
||||
*
|
||||
* @li LZG_Version() - Get the version of the LZG library.
|
||||
* @li LZG_VersionString() - Get the version of the LZG library.
|
||||
*
|
||||
* @section compr_sec Compression
|
||||
* Here is a simple example of compressing an uncompressed data buffer (given
|
||||
* as buf/bufSize).
|
||||
*
|
||||
* @code
|
||||
* unsigned char *encBuf;
|
||||
* lzg_uint32_t encSize, maxEncSize;
|
||||
*
|
||||
* // Determine maximum size of compressed data
|
||||
* maxEncSize = LZG_MaxEncodedSize(bufSize);
|
||||
*
|
||||
* // Allocate memory for the compressed data
|
||||
* encBuf = (unsigned char*) malloc(maxEncSize);
|
||||
* if (encBuf)
|
||||
* {
|
||||
* // Compress
|
||||
* encSize = LZG_Encode(buf, bufSize, encBuf, maxEncSize, NULL);
|
||||
* if (encSize)
|
||||
* {
|
||||
* // Compressed data is now in encBuf, use it...
|
||||
* // ...
|
||||
* }
|
||||
* else
|
||||
* fprintf(stderr, "Compression failed!\n");
|
||||
*
|
||||
* // Free memory when we're done with the compressed data
|
||||
* free(encBuf);
|
||||
* }
|
||||
* else
|
||||
* fprintf(stderr, "Out of memory!\n");
|
||||
* @endcode
|
||||
*
|
||||
* @section decompr_sec Decompression
|
||||
* Here is a simple example of decompressing a compressed data buffer (given
|
||||
* as buf/bufSize).
|
||||
*
|
||||
* @code
|
||||
* unsigned char *decBuf;
|
||||
* lzg_uint32_t decSize;
|
||||
*
|
||||
* // Determine size of decompressed data
|
||||
* decSize = LZG_DecodedSize(buf, bufSize);
|
||||
* if (decSize)
|
||||
* {
|
||||
* // Allocate memory for the decompressed data
|
||||
* decBuf = (unsigned char*) malloc(decSize);
|
||||
* if (decBuf)
|
||||
* {
|
||||
* // Decompress
|
||||
* decSize = LZG_Decode(buf, bufSize, decBuf, decSize);
|
||||
* if (decSize)
|
||||
* {
|
||||
* // Uncompressed data is now in decBuf, use it...
|
||||
* // ...
|
||||
* }
|
||||
* else
|
||||
* printf("Decompression failed (bad data)!\n");
|
||||
*
|
||||
* // Free memory when we're done with the decompressed data
|
||||
* free(decBuf);
|
||||
* }
|
||||
* else
|
||||
* printf("Out of memory!\n");
|
||||
* }
|
||||
* else
|
||||
* printf("Bad input data!\n");
|
||||
* @endcode
|
||||
*/
|
||||
|
||||
/* Basic types */
|
||||
typedef int lzg_bool_t; /**< @brief Boolean (@ref LZG_TRUE/@ref LZG_FALSE) */
|
||||
typedef int lzg_int32_t; /**< @brief Signed 32-bit integer */
|
||||
typedef unsigned int lzg_uint32_t; /**< @brief Unsigned 32-bit integer */
|
||||
|
||||
#define LZG_FALSE 0 /**< @brief Boolean FALSE (see @ref lzg_bool_t) */
|
||||
#define LZG_TRUE 1 /**< @brief Boolean TRUE (see @ref lzg_bool_t) */
|
||||
|
||||
/* Compression levels */
|
||||
#define LZG_LEVEL_1 1 /**< @brief Lowest/fastest compression level */
|
||||
#define LZG_LEVEL_2 2 /**< @brief Compression level 2 */
|
||||
#define LZG_LEVEL_3 3 /**< @brief Compression level 3 */
|
||||
#define LZG_LEVEL_4 4 /**< @brief Compression level 4 */
|
||||
#define LZG_LEVEL_5 5 /**< @brief Medium compression level */
|
||||
#define LZG_LEVEL_6 6 /**< @brief Compression level 6 */
|
||||
#define LZG_LEVEL_7 7 /**< @brief Compression level 7 */
|
||||
#define LZG_LEVEL_8 8 /**< @brief Compression level 8 */
|
||||
#define LZG_LEVEL_9 9 /**< @brief Best/slowest compression level */
|
||||
|
||||
/** @brief Default compression level */
|
||||
#define LZG_LEVEL_DEFAULT LZG_LEVEL_5
|
||||
|
||||
/**
|
||||
* Progress callback function.
|
||||
* @param[in] progress The current progress (0-100).
|
||||
* @param[in] userdata User supplied data pointer.
|
||||
*/
|
||||
typedef void (*LZGPROGRESSFUN)(lzg_int32_t progress, void *userdata);
|
||||
|
||||
/** @brief LZG compression configuration parameters.
|
||||
*
|
||||
* This structure is used for passing configuration options to the LZG_Encode()
|
||||
* function. Initialize this structure to default values with
|
||||
* @ref LZG_InitEncoderConfig().
|
||||
*/
|
||||
typedef struct {
|
||||
/** @brief Compression level (1-9).
|
||||
|
||||
For convenience, you can use the predefined constants
|
||||
@ref LZG_LEVEL_1 (fast) to @ref LZG_LEVEL_9 (slow), or
|
||||
@ref LZG_LEVEL_DEFAULT.
|
||||
|
||||
Default value: LZG_LEVEL_DEFAULT */
|
||||
lzg_int32_t level;
|
||||
|
||||
/** @brief Use fast method (LZG_FALSE or LZG_TRUE).
|
||||
|
||||
Boolean flag that specifies whether or not to use a faster encoding
|
||||
acceleration data structure, which requires more memory. When using the
|
||||
fast method, the compression ratio is usually slightly improved.
|
||||
|
||||
Default value: LZG_TRUE */
|
||||
lzg_bool_t fast;
|
||||
|
||||
/** @brief Encoding progress callback function.
|
||||
|
||||
This function will be called during compression to report progress
|
||||
back to the caller (set this to NULL to disable progress
|
||||
callback).
|
||||
|
||||
Default value: NULL */
|
||||
LZGPROGRESSFUN progressfun;
|
||||
|
||||
/** @brief User data pointer for the progress callback function.
|
||||
|
||||
A user defined data pointer that can point to anything that the
|
||||
progress callback function may need, such as an object reference
|
||||
(this can set to NULL if the callback function does not need it).
|
||||
|
||||
Default value: NULL */
|
||||
void *userdata;
|
||||
} lzg_encoder_config_t;
|
||||
|
||||
|
||||
/**
|
||||
* Determine the maximum size of the encoded data for a given uncompressed
|
||||
* buffer.
|
||||
* @param[in] insize Size of the uncompressed buffer (number of bytes).
|
||||
* @return Worst case (maximum) size of the encoded data.
|
||||
*/
|
||||
lzg_uint32_t LZG_MaxEncodedSize(lzg_uint32_t insize);
|
||||
|
||||
/**
|
||||
* Initialize an encoder configuration object.
|
||||
* @param[out] config Configuration object.
|
||||
*/
|
||||
void LZG_InitEncoderConfig(lzg_encoder_config_t *config);
|
||||
|
||||
/**
|
||||
* Determine the amount of memory required for encoding.
|
||||
* @param[in] config Compression configuration (if set to NULL, default encoder
|
||||
* configuration parameters are used).
|
||||
* @retrun The size of the buffer required.
|
||||
*/
|
||||
lzg_uint32_t LZG_WorkMemSize(lzg_encoder_config_t *config);
|
||||
|
||||
/**
|
||||
* Encode uncompressed data using the LZG coder (i.e. compress the data).
|
||||
* @param[in] in Input (uncompressed) buffer.
|
||||
* @param[in] insize Size of the input buffer (number of bytes).
|
||||
* @param[out] out Output (compressed) buffer.
|
||||
* @param[in] outsize Size of the output buffer (number of bytes).
|
||||
* @param[in] config Compression configuration (if set to NULL, default encoder
|
||||
* configuration parameters are used).
|
||||
* @return The size of the encoded data, or zero if the function failed
|
||||
* (e.g. if the end of the output buffer was reached before the
|
||||
* entire input buffer was encoded).
|
||||
* @note For the slow method (config->fast = 0), the memory requirement during
|
||||
* compression is 136 KB (LZG_LEVEL_1) to 2 MB (LZG_LEVEL_9). For the fast
|
||||
* method (config->fast = 1), the memory requirement is 64 MB (LZG_LEVEL_1) to
|
||||
* 66 MB (LZG_LEVEL_9). Also note that these figures are doubled on 64-bit
|
||||
* systems.
|
||||
*/
|
||||
lzg_uint32_t LZG_Encode(const unsigned char *in, lzg_uint32_t insize,
|
||||
unsigned char *out, lzg_uint32_t outsize,
|
||||
lzg_encoder_config_t *config);
|
||||
|
||||
/**
|
||||
* Encode uncompressed data using the LZG coder (i.e. compress the data).
|
||||
* @param[in] in Input (uncompressed) buffer.
|
||||
* @param[in] insize Size of the input buffer (number of bytes).
|
||||
* @param[out] out Output (compressed) buffer.
|
||||
* @param[in] outsize Size of the output buffer (number of bytes).
|
||||
* @param[in] config Compression configuration (if set to NULL, default encoder
|
||||
* configuration parameters are used).
|
||||
* @param[in] workmem Buffer to be used for compression, or NULL. See
|
||||
* @ref LZG_WorkMemSize.
|
||||
* @return The size of the encoded data, or zero if the function failed
|
||||
* (e.g. if the end of the output buffer was reached before the
|
||||
* entire input buffer was encoded).
|
||||
* @note For the slow method (config->fast = 0), the memory requirement during
|
||||
* compression is 136 KB (LZG_LEVEL_1) to 2 MB (LZG_LEVEL_9). For the fast
|
||||
* method (config->fast = 1), the memory requirement is 64 MB (LZG_LEVEL_1) to
|
||||
* 66 MB (LZG_LEVEL_9). Also note that these figures are doubled on 64-bit
|
||||
* systems.
|
||||
*/
|
||||
lzg_uint32_t LZG_EncodeFull(const unsigned char *in, lzg_uint32_t insize,
|
||||
unsigned char *out, lzg_uint32_t outsize,
|
||||
lzg_encoder_config_t *config,
|
||||
void *workmem);
|
||||
|
||||
/**
|
||||
* Determine the size of the decoded data for a given LZG coded buffer.
|
||||
* @param[in] in Input (compressed) buffer.
|
||||
* @param[in] insize Size of the input buffer (number of bytes). This does
|
||||
* not have to be the size of the entire compressed data, but
|
||||
* it has to be at least 7 bytes (the first few bytes of the
|
||||
* header, including the decompression size).
|
||||
* @return The size of the decoded data, or zero if the function failed
|
||||
* (e.g. if the magic header ID could not be found).
|
||||
*/
|
||||
lzg_uint32_t LZG_DecodedSize(const unsigned char *in, lzg_uint32_t insize);
|
||||
|
||||
|
||||
/**
|
||||
* Decode LZG coded data.
|
||||
* @param[in] in Input (compressed) buffer.
|
||||
* @param[in] insize Size of the input buffer (number of bytes).
|
||||
* @param[out] out Output (uncompressed) buffer.
|
||||
* @param[in] outsize Size of the output buffer (number of bytes).
|
||||
* @return The size of the decoded data, or zero if the function failed
|
||||
* (e.g. if the end of the output buffer was reached before the
|
||||
* entire input buffer was decoded).
|
||||
*/
|
||||
lzg_uint32_t LZG_Decode(const unsigned char *in, lzg_uint32_t insize,
|
||||
unsigned char *out, lzg_uint32_t outsize);
|
||||
|
||||
|
||||
/**
|
||||
* Get the version of the LZG library.
|
||||
* @return The version of the LZG library, on the same format as
|
||||
* @ref LZG_VERNUM.
|
||||
*/
|
||||
lzg_uint32_t LZG_Version(void);
|
||||
|
||||
|
||||
/**
|
||||
* Get the version string of the LZG library.
|
||||
* @return The version of the LZG library, on the same format as
|
||||
* @ref LZG_VERSION.
|
||||
*/
|
||||
const char* LZG_VersionString(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _LIBLZG_H_
|
25
chroma/inc/lainlib/lainlib.h
Normal file
25
chroma/inc/lainlib/lainlib.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
/************************
|
||||
*** Team Kitty, 2020 ***
|
||||
*** Chroma ***
|
||||
***********************/
|
||||
|
||||
|
||||
/* Defines all of the temporary library functions.
|
||||
* All of this must be moved into the Chroma stdlib.
|
||||
* They exist here as guidance, and as utility for the kernel itself.
|
||||
* If need be, they can also be moved into a trimmed-down "kernel libc" or "libk".
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <lainlib/vector/vector.h>
|
||||
|
||||
#include <lainlib/list/list.h>
|
||||
|
||||
#include <lainlib/mutex/spinlock.h>
|
||||
#include <lainlib/mutex/ticketlock.h>
|
||||
|
||||
#include <lainlib/compression/lzg.h>
|
34
chroma/inc/lainlib/list/list.h
Normal file
34
chroma/inc/lainlib/list/list.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
typedef struct list_entry {
|
||||
struct list_entry* Previous;
|
||||
struct list_entry* Next;
|
||||
} list_entry_t;
|
||||
|
||||
#define UNSAFE_CAST(ptr, type, member) \
|
||||
((type*)((char*)(ptr) - (char*)offsetof(type, member)))
|
||||
|
||||
#define LISTNEW(var) \
|
||||
((list_entry_t){ 0, 0 })
|
||||
|
||||
void ListAdd(list_entry_t* Head, list_entry_t* New);
|
||||
|
||||
void ListEmplaceBack(list_entry_t* Head, list_entry_t* Tail);
|
||||
|
||||
void ListRemove(list_entry_t* List);
|
||||
|
||||
bool ListIsEmpty(list_entry_t* Head);
|
||||
|
||||
#define LISTNEXT(current, member) \
|
||||
UNSAFE_CAST((current)->member.next, typeof(*(current)), member);
|
||||
|
||||
#define LISTPREV(current, member) \
|
||||
UNSAFE_CAST((current)->member.prev, typeof(*(curent)), member)
|
||||
|
||||
#define LISTFOREACH(pos, head) \
|
||||
for (pos = (head)->next; pos != (head); pos = pos->next)
|
||||
|
||||
#define LISTFOREACHENTRY(pos, head, member) \
|
||||
for(pos = UNSAFE_CAST((head)->next, typeof(*(pos)), member); &pos->member != (head); pos = LISTNEXT(pos, member))
|
||||
|
||||
#define LASTENTRY 0
|
22
chroma/inc/lainlib/mutex/spinlock.h
Normal file
22
chroma/inc/lainlib/mutex/spinlock.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
/************************
|
||||
*** Team Kitty, 2020 ***
|
||||
*** Chroma ***
|
||||
***********************/
|
||||
|
||||
|
||||
typedef volatile int spinlock_t;
|
||||
|
||||
/* A set of macros that acquire and release a mutex spinlock. */
|
||||
//TODO: this *needs* to be moved to a kernel header.
|
||||
|
||||
#define SPINLOCK(name) \
|
||||
while( !__sync_bool_compare_and_swap(name, 0, 1)); \
|
||||
__sync_synchronize();
|
||||
|
||||
|
||||
#define SPUNLOCK(name) \
|
||||
__sync_synchronize(); \
|
||||
name = 0;
|
||||
|
32
chroma/inc/lainlib/mutex/ticketlock.h
Normal file
32
chroma/inc/lainlib/mutex/ticketlock.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
#include <stdbool.h>
|
||||
#include <stdatomic.h>
|
||||
|
||||
/************************
|
||||
*** Team Kitty, 2020 ***
|
||||
*** Chroma ***
|
||||
***********************/
|
||||
|
||||
/* This file provides a simple implementation of a ticket-based locking system.
|
||||
* You should probably prefer Spinlock over Ticketlock.
|
||||
*
|
||||
* Create a new lock with NEW_TICKETLOCK(),
|
||||
* lock a resource with TicketLock().
|
||||
*
|
||||
* Use TicketUnlock() to free the resource after you are done.
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
atomic_size_t NowServing;
|
||||
atomic_size_t NextTicket;
|
||||
} ticketlock_t;
|
||||
|
||||
#define NEW_TICKETLOCK() (ticketlock_t{0})
|
||||
|
||||
void TicketLock(ticketlock_t* Lock);
|
||||
|
||||
bool TicketAttemptLock(ticketlock_t* Lock);
|
||||
|
||||
void TicketUnlock(ticketlock_t* Lock);
|
||||
|
30
chroma/inc/lainlib/vector/vector.h
Normal file
30
chroma/inc/lainlib/vector/vector.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/************************
|
||||
*** Team Kitty, 2020 ***
|
||||
*** Chroma ***
|
||||
***********************/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include<stddef.h>
|
||||
#include<stdint.h>
|
||||
#include <lainlib/mutex/spinlock.h>
|
||||
|
||||
struct vector_t {
|
||||
void** items;
|
||||
size_t n;
|
||||
|
||||
spinlock_t vector_lock;
|
||||
};
|
||||
|
||||
int VectorRemoveItem(struct vector_t* vec, void* item);
|
||||
|
||||
int VectorRemove(struct vector_t* vec, size_t index);
|
||||
|
||||
void* VectorGet(struct vector_t* vec, size_t index);
|
||||
|
||||
int VectorInsert(struct vector_t* vec, void* item, size_t index);
|
||||
|
||||
int VectorAppend(struct vector_t* vec, void* item);
|
||||
|
||||
int VectorDestroy(struct vector_t* vec);
|
190
chroma/lainlib/compression/lzgmini.c
Normal file
190
chroma/lainlib/compression/lzgmini.c
Normal file
|
@ -0,0 +1,190 @@
|
|||
/* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* This file is part of liblzg.
|
||||
*
|
||||
* Copyright (c) 2010 Marcus Geelnard
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would
|
||||
* be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not
|
||||
* be misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
|
||||
#include <lainlib/lainlib.h>
|
||||
|
||||
/*-- PRIVATE -----------------------------------------------------------------*/
|
||||
|
||||
/* Internal definitions */
|
||||
#define LZG_HEADER_SIZE 16
|
||||
#define LZG_METHOD_COPY 0
|
||||
#define LZG_METHOD_LZG1 1
|
||||
|
||||
/* Endian and alignment independent reader for 32-bit integers */
|
||||
#define _LZG_GetUINT32(in, offs) \
|
||||
((((lzg_uint32_t)in[offs]) << 24) | \
|
||||
(((lzg_uint32_t)in[offs+1]) << 16) | \
|
||||
(((lzg_uint32_t)in[offs+2]) << 8) | \
|
||||
((lzg_uint32_t)in[offs+3]))
|
||||
|
||||
/* Calculate the checksum */
|
||||
static lzg_uint32_t _LZG_CalcChecksum(const unsigned char *data, lzg_uint32_t size)
|
||||
{
|
||||
unsigned short a = 1, b = 0;
|
||||
unsigned char *end = (unsigned char *)data + size;
|
||||
while (data != end)
|
||||
{
|
||||
a += *data++;
|
||||
b += a;
|
||||
}
|
||||
return (((lzg_uint32_t)b) << 16) | a;
|
||||
}
|
||||
|
||||
/* LUT for decoding the copy length parameter */
|
||||
static const unsigned char _LZG_LENGTH_DECODE_LUT[32] = {
|
||||
2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,
|
||||
18,19,20,21,22,23,24,25,26,27,28,29,35,48,72,128
|
||||
};
|
||||
|
||||
|
||||
/*-- PUBLIC ------------------------------------------------------------------*/
|
||||
|
||||
lzg_uint32_t LZG_DecodedSize(const unsigned char *in, lzg_uint32_t insize)
|
||||
{
|
||||
/* Check header */
|
||||
if ((insize < 7) || (in[0] != 'L') || (in[1] != 'Z') || (in[2] != 'G'))
|
||||
return 0;
|
||||
|
||||
/* Get output buffer size */
|
||||
return _LZG_GetUINT32(in, 3);
|
||||
}
|
||||
|
||||
lzg_uint32_t LZG_Decode(const unsigned char *in, lzg_uint32_t insize,
|
||||
unsigned char *out, lzg_uint32_t outsize)
|
||||
{
|
||||
unsigned char *src, *inEnd, *dst, *outEnd, *copy, symbol, b, b2;
|
||||
unsigned char m1, m2, m3, m4, method;
|
||||
lzg_uint32_t i, length, offset, encodedSize, decodedSize, checksum;
|
||||
|
||||
/* Check magic ID */
|
||||
if ((insize < LZG_HEADER_SIZE) || (in[0] != 'L') || (in[1] != 'Z') || (in[2] != 'G'))
|
||||
return 0;
|
||||
|
||||
/* Get header data */
|
||||
decodedSize = _LZG_GetUINT32(in, 3);
|
||||
encodedSize = _LZG_GetUINT32(in, 7);
|
||||
checksum = _LZG_GetUINT32(in, 11);
|
||||
|
||||
/* Check sizes */
|
||||
if ((outsize < decodedSize) || (encodedSize != (insize - LZG_HEADER_SIZE)))
|
||||
return 0;
|
||||
|
||||
/* Check checksum */
|
||||
if (_LZG_CalcChecksum(&in[LZG_HEADER_SIZE], encodedSize) != checksum)
|
||||
return 0;
|
||||
|
||||
/* Initialize the byte streams */
|
||||
src = (unsigned char *)in + LZG_HEADER_SIZE;;
|
||||
inEnd = ((unsigned char *)in) + insize;
|
||||
dst = out;
|
||||
outEnd = out + outsize;
|
||||
|
||||
/* Check which method to use */
|
||||
method = in[15];
|
||||
if (method == LZG_METHOD_LZG1)
|
||||
{
|
||||
if (!((src + 4) <= inEnd)) return 0;
|
||||
m1 = *src++; m2 = *src++; m3 = *src++; m4 = *src++;
|
||||
|
||||
/* Main decompression loop */
|
||||
while (src < inEnd)
|
||||
{
|
||||
symbol = *src++;
|
||||
|
||||
if ((symbol != m1) && (symbol != m2) && (symbol != m3) && (symbol != m4))
|
||||
{
|
||||
/* Literal copy */
|
||||
if (!(dst < outEnd)) return 0;
|
||||
*dst++ = symbol;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Decode offset / length parameters */
|
||||
if (!(src < inEnd)) return 0;
|
||||
if ((b = *src++))
|
||||
{
|
||||
if (symbol == m1)
|
||||
{
|
||||
/* Distant copy */
|
||||
if (!((src + 2) <= inEnd)) return 0;
|
||||
length = _LZG_LENGTH_DECODE_LUT[b & 0x1f];
|
||||
b2 = *src++;
|
||||
offset = (((unsigned int)(b & 0xe0)) << 11) |
|
||||
(((unsigned int)b2) << 8) |
|
||||
(*src++);
|
||||
offset += 2056;
|
||||
}
|
||||
else if (symbol == m2)
|
||||
{
|
||||
/* Medium copy */
|
||||
if (!(src < inEnd)) return 0;
|
||||
length = _LZG_LENGTH_DECODE_LUT[b & 0x1f];
|
||||
b2 = *src++;
|
||||
offset = (((unsigned int)(b & 0xe0)) << 3) | b2;
|
||||
offset += 8;
|
||||
}
|
||||
else if (symbol == m3)
|
||||
{
|
||||
/* Short copy */
|
||||
length = (b >> 6) + 3;
|
||||
offset = (b & 0x3f) + 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Near copy (including RLE) */
|
||||
length = _LZG_LENGTH_DECODE_LUT[b & 0x1f];
|
||||
offset = (b >> 5) + 1;
|
||||
}
|
||||
|
||||
/* Copy the corresponding data from the history window */
|
||||
copy = dst - offset;
|
||||
if (!((copy >= out) && ((dst + length) <= outEnd))) return 0;
|
||||
for (i = 0; i < length; ++i)
|
||||
*dst++ = *copy++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Literal copy (single occurance of a marker symbol) */
|
||||
if (!(dst < outEnd)) return 0;
|
||||
*dst++ = symbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (method == LZG_METHOD_COPY)
|
||||
{
|
||||
/* Plain copy */
|
||||
while ((src < inEnd) && (dst < outEnd))
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
/* All OK? */
|
||||
if ((unsigned int)(dst - out) != decodedSize)
|
||||
return 0;
|
||||
else
|
||||
return decodedSize;
|
||||
}
|
27
chroma/lainlib/list/basic_list.c
Normal file
27
chroma/lainlib/list/basic_list.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
#include <lainlib/list/list.h>
|
||||
|
||||
void ListAdd(list_entry_t* Head, list_entry_t* New) {
|
||||
New->Next = Head->Next;
|
||||
New->Previous = Head;
|
||||
New->Next->Previous = New;
|
||||
Head->Next = New;
|
||||
}
|
||||
|
||||
void ListEmplaceBack(list_entry_t* Head, list_entry_t* New) {
|
||||
New->Next = Head;
|
||||
New->Previous = Head->Previous;
|
||||
New->Previous->Next = New;
|
||||
Head->Previous = New;
|
||||
}
|
||||
|
||||
void ListRemove(list_entry_t* Entry) {
|
||||
Entry->Next->Previous = Entry->Previous;
|
||||
Entry->Previous->Next = Entry->Next;
|
||||
|
||||
Entry->Previous = (void*)0xDEADull;
|
||||
Entry->Next = (void*)0xBEEFull;
|
||||
}
|
||||
|
||||
bool ListIsEmpty(list_entry_t* Head) {
|
||||
return Head->Next == Head;
|
||||
}
|
21
chroma/lainlib/mutex/ticketlock.c
Normal file
21
chroma/lainlib/mutex/ticketlock.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include <kernel/chroma.h>
|
||||
#include <lainlib/lainlib.h>
|
||||
|
||||
void TicketLock(ticketlock_t* Lock) {
|
||||
size_t Ticket = atomic_fetch_add_explicit(&Lock->NextTicket, 1, memory_order_relaxed);
|
||||
|
||||
while(atomic_load_explicit(&Lock->NowServing, memory_order_acquire) != Ticket) {
|
||||
PAUSE;
|
||||
}
|
||||
}
|
||||
|
||||
bool TicketAttemptLock(ticketlock_t* Lock) {
|
||||
size_t Ticket = atomic_load_explicit(&Lock->NowServing, memory_order_relaxed);
|
||||
|
||||
return atomic_compare_exchange_strong_explicit(&Lock->NowServing, &Ticket, Ticket + 1, memory_order_acquire, memory_order_relaxed);
|
||||
}
|
||||
|
||||
void TicketUnlock(ticketlock_t* Lock) {
|
||||
size_t NextTicket = atomic_load_explicit(&Lock->NowServing, memory_order_relaxed) + 1;
|
||||
atomic_store_explicit(&Lock->NowServing, NextTicket, memory_order_release);
|
||||
}
|
68
chroma/lainlib/vector.c
Normal file
68
chroma/lainlib/vector.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
#include <templib/templib.h>
|
||||
|
||||
/************************
|
||||
*** Team Kitty, 2020 ***
|
||||
*** Chroma ***
|
||||
***********************/
|
||||
|
||||
/* This file provides a Chroma implementation of std::vector, a C++ standard library class.
|
||||
* It has a lot of work left to be done, but it's usable for its intended function (Graphics)
|
||||
*/
|
||||
|
||||
int VectorRemoveItem(struct vector_t* vec, void* item) {
|
||||
//TODO
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
int VectorRemove(struct vector_t* vec, size_t index) {
|
||||
|
||||
if (!vec) return 0;
|
||||
|
||||
//TODO: Vector spinlock
|
||||
// AcqSpinlock(&vec->lock);
|
||||
|
||||
if((index + 1) > vec->n) return 0;
|
||||
|
||||
vec->items[index] = NULL;
|
||||
|
||||
for (int i = 0; i < vec->n; i++) {
|
||||
vec->items[i] = vec->items[i + 1];
|
||||
}
|
||||
|
||||
//TODO: vector reallocate
|
||||
// realloc(vec->items, vec->n - 1);
|
||||
|
||||
vec->n--;
|
||||
|
||||
// ReleaseSpinlock(&vec->lock);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
void* VectorGet(struct vector_t* vec, size_t index) {
|
||||
|
||||
if(!vec) return 0;
|
||||
|
||||
//TODO: Vector spinlock
|
||||
// AcqSpinlock(&vec->lock);
|
||||
|
||||
if((index + 1) > vec->n) return NULL;
|
||||
|
||||
// ReleaseSpinlock(&vec->lock);
|
||||
return vec->items[index];
|
||||
|
||||
}
|
||||
|
||||
int VectorInsert(struct vector_t* vec, void* item, size_t index) {
|
||||
|
||||
}
|
||||
|
||||
int VectorAppend(struct vector_t* vec, void* item) {
|
||||
|
||||
}
|
||||
|
||||
int VectorDestroy(struct vector_t* vec) {
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user