- Added libraries from formats and libvitaboy
This commit is contained in:
Tony Bark 2024-04-28 05:33:13 -04:00
parent 66ce473514
commit 5efdb29315
101 changed files with 11711 additions and 10889 deletions

View file

@ -0,0 +1,22 @@
cmake_minimum_required(VERSION 2.6)
project(far)
set(FAR_SOURCES
far.c
refpack_dec.c
)
add_library(far_static STATIC ${FAR_SOURCES})
set_target_properties(far_static PROPERTIES
OUTPUT_NAME "far"
CLEAN_DIRECT_OUTPUT 1)
#### Shared library (uncomment to build)
#add_library(far_shared SHARED ${FAR_SOURCES})
#set_target_properties(far_shared PROPERTIES
# OUTPUT_NAME "far"
# PREFIX ""
# CLEAN_DIRECT_OUTPUT 1)
add_executable(farextract farextract.c)
target_link_libraries(farextract far_static)

View file

@ -0,0 +1,24 @@
/* config.h - far build configuration */
/* Define if you have the <stdint.h> header file. */
#define HAVE_STDINT_H
/* compile-in support */
#define FAR_ARCHIVEREAD
#define FAR_ARCHIVEWRITE
#define FAR_REFPACK_DECOMPRESS
#define FAR_REFPACK_COMPRESS
#define FAR_SUPPORT_FAR
#define FAR_SUPPORT_DBPF
#define FAR_SUPPORT_PERSIST
#define FAR_DEBUGSUPPORT
#define FAR_FILEIO
#define FAR_EMBEDDEDFUNCTIONS
/* end of compile-in support */
/* preferences -- on non-numerical definitions, define to 1 for "yes", 0 for "no" */
#define FAR_DEFAULT_1A 0
#define FAR_DEFAULT_DBPF_COMPRESSED 0
#define FAR_DEFAULT_MAX_FILE_NAME_LENGTH 255
#define FAR_DEFAULT_REFPACK_HNSV 0xFB
/* end of default preferences */

446
library/formats/far/far.c Normal file
View file

@ -0,0 +1,446 @@
/*
FileHandler - General-purpose file handling library for Niotso
far.c - Copyright (c) 2011-2012 Niotso Project <http://niotso.org/>
Author(s): Fatbag <X-Fi6@phppoll.org>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "far.h"
#if defined(FAR_SUPPORT_PERSIST)
#define FAR_MINSIZE_ANY MINSIZE_PERSIST
#elif defined(FAR_SUPPORT_FAR)
#define FAR_MINSIZE_ANY MINSIZE_FAR
#else
#define FAR_MINSIZE_ANY MINSIZE_DBPF
#endif
#ifndef read_int32
#define read_int32(x) (int)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*2)) | ((x)[3]<<(8*3)))
#define read_int24(x) (int)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*2)))
#define read_int16(x) (int)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)))
#define read_int8(x) (int)(((x)[0]<<(8*0)))
#define read_uint32(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*2)) | ((x)[3]<<(8*3)))
#define read_uint24(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*2)))
#define read_uint16(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)))
#define read_uint8(x) (unsigned)(((x)[0]<<(8*0)))
#endif
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
/* These options can be changed during runtime */
static int libfarOptions[] = {
FAR_DEFAULT_1A,
FAR_DEFAULT_DBPF_COMPRESSED,
FAR_DEFAULT_MAX_FILE_NAME_LENGTH,
FAR_DEFAULT_REFPACK_HNSV
};
void libfar_set_option(int Option, int Value){
libfarOptions[Option] = Value;
}
int libfar_get_option(int Option){
return libfarOptions[Option];
}
int far_identify(const uint8_t * Buffer, unsigned FileSize)
{
if(!FileSize) FileSize = ~0;
else if(FileSize < FAR_MINSIZE_ANY)
return FAR_TYPE_INVALID;
#ifdef FAR_SUPPORT_FAR
if(FileSize >= MINSIZE_FAR && !memcmp(Buffer, Header_FAR, 8))
return FAR_TYPE_FAR;
#endif
#ifdef FAR_SUPPORT_DBPF
if(FileSize >= MINSIZE_DBPF && !memcmp(Buffer, Header_DBPF, 4))
return FAR_TYPE_DBPF;
#endif
#ifdef FAR_SUPPORT_PERSIST
if(FileSize >= MINSIZE_PERSIST && Buffer[0] == 0x01)
return FAR_TYPE_PERSIST;
#endif
return FAR_TYPE_INVALID;
}
FARFile * far_create_archive(int Type)
{
FARFile *ptr = calloc(1, sizeof(FARFile));
if(ptr == NULL) return NULL;
ptr->Type = Type;
return ptr;
}
PersistFile * far_create_persist()
{
return calloc(1, sizeof(PersistFile));
}
FAREntryNode * far_add_entry(FARFile * FARFileInfo, int Position)
{
FAREntryNode *ptr = calloc(1, sizeof(FAREntryNode)), *node;
if(ptr == NULL) return NULL;
if(FARFileInfo == NULL) return ptr;
if(Position >= 0){
node = FARFileInfo->FirstEntry;
if(node == NULL){
FARFileInfo->FirstEntry = ptr;
FARFileInfo->LastEntry = ptr;
}else{
/* Find the node we will take the place of */
while(Position-- && node->NextEntry != NULL)
node = node->NextEntry;
if(node->PrevEntry == NULL)
FARFileInfo->FirstEntry = ptr;
/* Shift this node and all nodes after it above us */
ptr->PrevEntry = node->PrevEntry;
ptr->NextEntry = node;
node->PrevEntry = ptr;
}
}else{
node = FARFileInfo->LastEntry;
if(node == NULL){
FARFileInfo->FirstEntry = ptr;
FARFileInfo->LastEntry = ptr;
}else{
/* Find the node we will take the place of */
while(++Position && node->PrevEntry != NULL)
node = node->PrevEntry;
if(node->NextEntry == NULL)
FARFileInfo->LastEntry = ptr;
/* Shift this node and all nodes before it below us */
ptr->PrevEntry = node;
ptr->NextEntry = node->NextEntry;
node->NextEntry = ptr;
}
}
FARFileInfo->Files++;
return ptr;
}
int far_read_header(FARFile * FARFileInfo, const uint8_t * Buffer, unsigned FileSize)
{
if(!FileSize) FileSize = ~0;
else if(FileSize < FAR_MINSIZE_ANY)
return 0;
#ifdef FAR_SUPPORT_FAR
if(FARFileInfo->Type == FAR_TYPE_FAR){
FARFileInfo->MajorVersion = read_uint32(Buffer+8);
FARFileInfo->IndexOffset = read_uint32(Buffer+12);
if(FARFileInfo->MajorVersion != 1 && FARFileInfo->MajorVersion != 3)
return 0;
if(FARFileInfo->MajorVersion == 1)
FARFileInfo->Revision = !libfarOptions[FAR_CONFIG_DEFAULT_TO_1A];
if(FARFileInfo->IndexOffset > FileSize-4)
return 0;
FARFileInfo->Files = read_uint32(Buffer + FARFileInfo->IndexOffset);
if(FARFileInfo->Files > (FileSize-FARFileInfo->IndexOffset) / (
(FARFileInfo->MajorVersion == 1) ? (
(FARFileInfo->Revision == 0) ? MINSIZE_ENTRY_FAR_1A : MINSIZE_ENTRY_FAR_1B
) : MINSIZE_ENTRY_FAR_3)
) return 0;
return 1;
}
#endif
#ifdef FAR_SUPPORT_DBPF
if(FARFileInfo->Type == FAR_TYPE_DBPF){
int i;
FARFileInfo->MajorVersion = read_uint32(Buffer+4);
FARFileInfo->MinorVersion = read_uint32(Buffer+8);
FARFileInfo->DateCreated = read_uint32(Buffer+24);
FARFileInfo->DateModified = read_uint32(Buffer+28);
FARFileInfo->IndexMajorVersion = read_uint32(Buffer+32);
FARFileInfo->Files = read_uint32(Buffer+36);
FARFileInfo->IndexOffset = read_uint32(Buffer+40);
FARFileInfo->IndexSize = read_uint32(Buffer+44);
FARFileInfo->TrashCount = read_uint32(Buffer+48);
FARFileInfo->TrashOffset = read_uint32(Buffer+52);
FARFileInfo->TrashSize = read_uint32(Buffer+56);
FARFileInfo->IndexMinorVersion = read_uint32(Buffer+60);
if(FARFileInfo->MajorVersion != 1) return 0;
if(FARFileInfo->MinorVersion != 0) return 0;
if(FARFileInfo->IndexMajorVersion != 7) return 0;
if(FARFileInfo->IndexMinorVersion != 0) return 0;
for(i=12; i<24; i++)
if(Buffer[i] != 0x00) return 0;
if(FARFileInfo->Files){
if(FARFileInfo->Files > MAX_ENTRIES_DBPF) return 0;
if(FARFileInfo->IndexSize != FARFileInfo->Files*SIZEOF_ENTRY_DBPF) return 0;
if(FARFileInfo->IndexOffset > FileSize) return 0;
if(FARFileInfo->IndexSize > FileSize - FARFileInfo->IndexOffset) return 0;
}
if(FARFileInfo->TrashCount){
if(FARFileInfo->TrashCount > MAX_ENTRIES_DBPF) return 0;
if(FARFileInfo->TrashSize != FARFileInfo->TrashCount*SIZEOF_ENTRY_DBPF) return 0;
if(FARFileInfo->TrashOffset > FileSize) return 0;
if(FARFileInfo->TrashSize > FileSize - FARFileInfo->TrashOffset) return 0;
}
return 1;
}
#endif
return 0;
}
int far_read_entry(const FARFile * FARFileInfo, FAREntry * FAREntryInfo,
const uint8_t * Buffer, unsigned MaxEntrySize, unsigned ArchiveSize)
{
int MajorVersion = FARFileInfo->MajorVersion, Revision = FARFileInfo->Revision;
if(MaxEntrySize == 0) MaxEntrySize = ~0;
if(ArchiveSize == 0) ArchiveSize = ~0;
#ifdef FAR_SUPPORT_FAR
if(FARFileInfo->Type == FAR_TYPE_FAR){
unsigned MinEntrySize =
(MajorVersion == 1) ? (
(Revision == 0) ? MINSIZE_ENTRY_FAR_1A : MINSIZE_ENTRY_FAR_1B
) : MINSIZE_ENTRY_FAR_3;
if(MaxEntrySize < MinEntrySize)
return 0;
if(MajorVersion == 1){
FAREntryInfo->DecompressedSize = read_uint32(Buffer+0);
FAREntryInfo->CompressedSize = read_uint32(Buffer+4);
FAREntryInfo->DataOffset = read_uint32(Buffer+8);
if(Revision == 0)
FAREntryInfo->FilenameLength = read_uint32(Buffer+12);
else
FAREntryInfo->FilenameLength = read_uint16(Buffer+12);
}else if(MajorVersion == 3){
FAREntryInfo->DecompressedSize = read_uint32(Buffer+0);
FAREntryInfo->CompressedSize = read_uint24(Buffer+4);
FAREntryInfo->DataType = read_uint8(Buffer+7);
FAREntryInfo->DataOffset = read_uint32(Buffer+8);
FAREntryInfo->HasFilename = read_uint16(Buffer+12);
FAREntryInfo->FilenameLength = read_uint16(Buffer+14);
FAREntryInfo->TypeID = read_uint32(Buffer+16);
FAREntryInfo->FileID = read_uint32(Buffer+20);
}
if(FAREntryInfo->FilenameLength > MaxEntrySize - MinEntrySize) return 0;
if(FAREntryInfo->FilenameLength > (unsigned)libfarOptions[FAR_CONFIG_MAX_FILE_NAME_LENGTH]) return 0;
if(FAREntryInfo->CompressedSize > FAREntryInfo->DecompressedSize) return 0;
if(FAREntryInfo->DecompressedSize != 0){
if(FAREntryInfo->DataOffset > ArchiveSize) return 0;
if(FAREntryInfo->CompressedSize > ArchiveSize - FAREntryInfo->DataOffset) return 0;
}else if(MajorVersion == 3 && FAREntryInfo->DataType != 0) return 0;
FAREntryInfo->Filename = malloc(FAREntryInfo->FilenameLength + 1);
if(FAREntryInfo->Filename == NULL) return 0;
if(FAREntryInfo->FilenameLength != 0)
memcpy(FAREntryInfo->Filename, Buffer+MinEntrySize, FAREntryInfo->FilenameLength);
FAREntryInfo->Filename[FAREntryInfo->FilenameLength] = '\0';
return 1;
}
#endif
#ifdef FAR_SUPPORT_DBPF
if(FARFileInfo->Type == FAR_TYPE_DBPF){
if(MaxEntrySize < SIZEOF_ENTRY_DBPF) return 0;
FAREntryInfo->TypeID = read_uint32(Buffer+0);
FAREntryInfo->GroupID = read_uint32(Buffer+4);
FAREntryInfo->FileID = read_uint32(Buffer+8);
FAREntryInfo->DataOffset = read_uint32(Buffer+12);
FAREntryInfo->CompressedSize = read_uint32(Buffer+16);
FAREntryInfo->DecompressedSize = FAREntryInfo->CompressedSize;
if(FAREntryInfo->CompressedSize != 0){
if(FAREntryInfo->CompressedSize > ArchiveSize - FAREntryInfo->DataOffset) return 0;
if(FAREntryInfo->DataOffset > ArchiveSize) return 0;
if(FAREntryInfo->CompressedSize > ArchiveSize - FAREntryInfo->DataOffset) return 0;
}
return 1;
}
#endif
return 0;
}
int far_read_persist_header(PersistFile * PersistData, const uint8_t * Buffer, unsigned FileSize)
{
RefPackParameters * Parameters;
PersistData->BodyType = read_uint8(Buffer);
PersistData->DecompressedSize = read_uint32(Buffer+1);
PersistData->CompressedSize = read_uint32(Buffer+5);
PersistData->StreamBodySize = read_uint32(Buffer+9);
PersistData->Compressor = read_uint8(Buffer+13);
if(PersistData->BodyType != 1)
return 0;
if(PersistData->CompressedSize < FileSize-9)
return 0;
if(PersistData->CompressedSize != PersistData->StreamBodySize)
return 0;
PersistData->Parameters = malloc(sizeof(RefPackParameters));
if(PersistData->Parameters == NULL)
return 0;
Parameters = (RefPackParameters *) PersistData->Parameters;
Parameters->hnsv = read_uint8(Buffer+14);
Parameters->DecompressedSize = (Buffer[15]<<16) | (Buffer[16]<<8) | Buffer[17]; /* Big endian */
if((PersistData->DecompressedSize&0x00FFFFFF) != Parameters->DecompressedSize){
free(PersistData->Parameters); return 0;
}
return 1;
}
int far_read_entry_data(const FARFile * FARFileInfo, FAREntry * FAREntryInfo, uint8_t * Buffer)
{
int Compressed = (FARFileInfo->Type == FAR_TYPE_FAR) ? (
(FARFileInfo->MajorVersion == 1) ? (
FAREntryInfo->DecompressedSize != FAREntryInfo->CompressedSize
) : FAREntryInfo->DataType == 0x80) : libfarOptions[FAR_CONFIG_DBPF_COMPRESSED];
FAREntryInfo->CompressedData = Buffer+FAREntryInfo->DataOffset;
if(!Compressed)
FAREntryInfo->DecompressedData = FAREntryInfo->CompressedData;
else{
PersistFile * PersistInfo = &(FAREntryInfo->PersistData);
if(far_identify(FAREntryInfo->CompressedData, FAREntryInfo->CompressedSize) != FAR_TYPE_PERSIST)
return 0;
if(!far_read_persist_header(PersistInfo, FAREntryInfo->CompressedData, FAREntryInfo->CompressedSize))
return 0;
/* Verify that the Persist data agrees with the entry data */
if(PersistInfo->DecompressedSize != FAREntryInfo->DecompressedSize){
free(PersistInfo->Parameters); return 0;
}if(PersistInfo->CompressedSize != FAREntryInfo->CompressedSize - 9){
free(PersistInfo->Parameters); return 0;
}if(PersistInfo->Compressor != 0x10){
free(PersistInfo->Parameters); return 0;
}
PersistInfo->DecompressedData = FAREntryInfo->DecompressedData;
if(!far_read_persist_data(PersistInfo, FAREntryInfo->CompressedData+18)){
free(PersistInfo->Parameters); return 0;
}
FAREntryInfo->DecompressedData = PersistInfo->DecompressedData;
}
return 1;
}
int far_read_persist_data(PersistFile * PersistData, uint8_t * CompressedData)
{
if(CompressedData != NULL) PersistData->CompressedData = CompressedData;
PersistData->DecompressedData = malloc(PersistData->DecompressedSize);
if(PersistData->DecompressedData == NULL)
return 0;
if(!RefPackDecompress(PersistData->CompressedData, PersistData->CompressedSize-9,
PersistData->DecompressedData, PersistData->DecompressedSize,
libfarOptions[FAR_CONFIG_REFPACK_HNSV])){
free(PersistData->DecompressedData);
return 0;
}
return 1;
}
int far_enumerate_entries(FARFile * FARFileInfo, const uint8_t * Index, unsigned IndexSize, unsigned ArchiveSize)
{
unsigned Files = FARFileInfo->Files;
int ArchiveType = FARFileInfo->Type;
unsigned MinEntrySize = (ArchiveType == FAR_TYPE_FAR) ? (
(FARFileInfo->MajorVersion == 1) ? (
(FARFileInfo->Revision == 0) ? MINSIZE_ENTRY_FAR_1A : MINSIZE_ENTRY_FAR_1B
) : MINSIZE_ENTRY_FAR_3) : SIZEOF_ENTRY_DBPF;
unsigned EntriesAdded = 0;
FARFileInfo->Files = 0;
if(FARFileInfo->Type == FAR_TYPE_FAR)
Index += 4;
while(EntriesAdded < Files){
FAREntryNode * node = far_add_entry(FARFileInfo, -1);
if(node == NULL)
return 0;
if(!far_read_entry(FARFileInfo, &(node->Entry), Index, IndexSize, ArchiveSize)){
free(node);
return 0;
}
EntriesAdded++;
Index += MinEntrySize;
IndexSize -= MinEntrySize;
if(ArchiveType != FAR_TYPE_DBPF){
Index += node->Entry.FilenameLength;
IndexSize -= node->Entry.FilenameLength;
}
}
return (EntriesAdded == FARFileInfo->Files);
}
int far_enumerate_entry_data(const FARFile * FARFileInfo, uint8_t * Buffer)
{
FAREntryNode * node = FARFileInfo->FirstEntry;
while(node){
if(!far_read_entry_data(FARFileInfo, &(node->Entry), Buffer))
return 0;
node = node->NextEntry;
}
return 1;
}
void libfar_free(void * ptr)
{
free(ptr);
}

176
library/formats/far/far.h Normal file
View file

@ -0,0 +1,176 @@
/*
FileHandler - General-purpose file handling library for Niotso
far.h - Copyright (c) 2011 Niotso Project <http://niotso.org/>
Author(s): Fatbag <X-Fi6@phppoll.org>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/****
** Constants
*/
/* libfarOptions array members */
#define FAR_CONFIG_DEFAULT_TO_1A 0
#define FAR_CONFIG_DBPF_COMPRESSED 1
#define FAR_CONFIG_MAX_FILE_NAME_LENGTH 2
#define FAR_CONFIG_REFPACK_HNSV 3
/* Archive types */
#define FAR_TYPE_INVALID 0
#define FAR_TYPE_FAR 1
#define FAR_TYPE_DBPF 2
#define FAR_TYPE_PERSIST 3
/* Numerical constants */
#define FAR_ARCHIVE_MINIMUM_SIZE 14
#define MINSIZE_FAR 20
#define MINSIZE_DBPF 64
#define MINSIZE_ENTRY_FAR_1A 16
#define MINSIZE_ENTRY_FAR_1B 14
#define MINSIZE_ENTRY_FAR_3 24
#define SIZEOF_ENTRY_DBPF 20
#define MAX_ENTRIES_FAR_1A 268435455
#define MAX_ENTRIES_FAR_1B 306783377
#define MAX_ENTRIES_FAR_3 178956970
#define MAX_ENTRIES_DBPF 214748364
#define MINSIZE_PERSIST 18
#define MAXSIZE_REFPACK_UNCOMPRESSED 16777215
#define MAXSIZE_REFPACK_COMPRESSED 16777215
/* Header bytes */
static const uint8_t Header_FAR[] = {'F','A','R','!','b','y','A','Z'};
static const uint8_t Header_DBPF[] = {'D','B','P','F'};
/****
** Data structures
*/
typedef struct PersistFile_s
{
uint8_t BodyType;
uint32_t DecompressedSize;
uint32_t CompressedSize;
uint32_t StreamBodySize;
uint8_t Compressor;
uint8_t * Parameters;
uint8_t * CompressedData;
uint8_t * DecompressedData;
} PersistFile;
typedef struct RefPackParameters_s
{
uint8_t hnsv;
uint32_t DecompressedSize;
} RefPackParameters;
typedef struct FAREntry_s
{
uint32_t DecompressedSize;
uint32_t CompressedSize;
uint8_t DataType;
uint32_t DataOffset;
uint16_t HasFilename;
uint32_t FilenameLength;
uint32_t TypeID;
uint32_t GroupID;
uint32_t FileID;
char * Filename;
PersistFile PersistData;
uint8_t * CompressedData;
uint8_t * DecompressedData;
} FAREntry;
typedef struct FAREntryNode_s
{
FAREntry Entry;
struct FAREntryNode_s * PrevEntry;
struct FAREntryNode_s * NextEntry;
} FAREntryNode;
typedef struct FARFile_s
{
int32_t Type;
/* Header */
uint32_t MajorVersion;
uint32_t MinorVersion;
uint32_t Revision;
uint32_t IndexOffset;
/* DBPF */
uint32_t DateCreated;
uint32_t DateModified;
uint32_t IndexMajorVersion;
uint32_t IndexSize;
uint32_t TrashCount;
uint32_t TrashOffset;
uint32_t TrashSize;
uint32_t IndexMinorVersion;
/* Regular index */
uint32_t Files;
FAREntryNode * FirstEntry;
FAREntryNode * LastEntry;
struct { /* DIR index for DBPF */
FAREntryNode * FirstEntry;
FAREntryNode * LastEntry;
} Dir;
struct { /* Trash index for DBPF */
FAREntryNode * FirstEntry;
FAREntryNode * LastEntry;
} Trash;
} FARFile;
/****
** Exported functions
*/
#ifdef __cplusplus
extern "C" {
#endif
void libfar_set_option(int Option, int Value);
int libfar_get_option(int Option);
int far_identify(const uint8_t * Buffer, unsigned FileSize);
FARFile * far_create_archive(int Type);
PersistFile * far_create_persist();
FAREntryNode * far_add_entry(FARFile * FARFileInfo, int Position);
int far_read_header(FARFile * FARFileInfo, const uint8_t * Buffer, unsigned FileSize);
int far_read_entry(const FARFile * FARFileInfo, FAREntry * FAREntryInfo,
const uint8_t * Buffer, unsigned MaxEntrySize, unsigned ArchiveSize);
int far_read_persist_header(PersistFile * PersistData, const uint8_t * Buffer, unsigned FileSize);
int far_read_entry_data(const FARFile * FARFileInfo, FAREntry * FAREntryInfo, uint8_t * Buffer);
int far_read_persist_data(PersistFile * PersistData, uint8_t * CompressedData);
int far_enumerate_entries(FARFile * FARFileInfo, const uint8_t * Index, unsigned IndexSize, unsigned ArchiveSize);
int far_enumerate_entry_data(const FARFile * FARFileInfo, uint8_t * Buffer);
FAREntryNode * far_search_id();
FAREntryNode * far_search_name();
FAREntryNode * far_search_multi();
void far_delete_entry(FARFile * FARFileInfo, int Position);
void far_delete_archive(FARFile * FARFileInfo);
void far_delete_persist(FARFile * FARFileInfo);
void libfar_free(void * ptr);
int RefPackDecompress(const uint8_t * CompressedData, size_t CompressedSize,
uint8_t * DecompressedData, size_t DecompressedSize, unsigned HNSV);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,430 @@
/*
FileHandler - General-purpose file handling library for Niotso
farextract.c - Copyright (c) 2011 Niotso Project <http://niotso.org/>
Author(s): Fatbag <X-Fi6@phppoll.org>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <time.h>
#include <sys/stat.h>
#include <errno.h>
#include "far.h"
#ifndef read_uint32
#define read_uint32(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*2)) | ((x)[3]<<(8*3)))
#endif
#ifdef _WIN32
#define mkdir(path, x) mkdir(path)
#endif
static int mkpath(char * path){
char * p;
for(p = strpbrk(path+1, "/\\"); p; p = strpbrk(p+1, "/\\")){
char c = *p;
int value;
*p = '\0'; value = mkdir(path, 0644); *p = c;
if(value != 0 && errno != EEXIST)
return -1;
}
return 0;
}
enum {
profile_ts1 = 1,
profile_tso,
profile_sc4,
profile_ts2,
profile_spore,
profile_ts3
};
typedef struct {
uint32_t GroupID;
const char * Directory;
} GroupMap_t;
typedef struct {
uint32_t TypeID;
const char * Extension;
} TypeMap_t;
typedef struct {
uint8_t Size;
const char * Header;
const char * Extension;
} HeaderMap_t;
static const GroupMap_t GroupMap[] = {
{0x0A3C55C7, "Music/Stations/Horror/"},
{0x0A3C55CE, "Music/Stations/OldWorld/"},
{0x0A3C55D3, "Music/Stations/SciFi/"},
{0x1D6962CF, "SoundData/HitLabUI/"},
{0x1D8A8B4F, "SoundData/HitLabTestSamples/"},
{0x29D9359D, "SoundData/CustomTrks/"},
{0x29DAA4A6, "SoundData/Custom/"},
{0x29DD0888, "SoundData/Multiplayer/"},
{0x69C6C943, "SoundData/tsov2/"},
{0x8A6FCC30, "SoundData/EP5Samps/"},
{0x9DBDBF74, "SoundData/HitLists/"},
{0x9DBDBF89, "SoundData/Samples/"},
{0x9DF26DAD, "Music/Stations/Country/"},
{0x9DF26DAE, "Music/Stations/CountryD/"},
{0x9DF26DB1, "Music/Stations/Latin/"},
{0x9DF26DB3, "Music/Stations/Rap/"},
{0x9DF26DB6, "Music/Stations/Rock/"},
{0xA9C6C89A, "SoundData/Tracks/"},
{0xBD6E5937, "SoundData/HitLabTest/"},
{0xBDF26DB0, "Music/Stations/Disco/"},
{0xC9C6C9B3, "SoundData/HitListsTemp/"},
{0xDDBDBF8C, "SoundData/Stings/"},
{0xDDE8F5C6, "SoundData/EP2/"},
{0xDDF26DA9, "Music/Stations/Beach/"},
{0xDDF26DB4, "Music/Stations/Rave/"},
{0xFDBDBF87, "SoundData/TrackDefs/"},
{0xFDF26DAB, "Music/Stations/Classica/"}
};
static const TypeMap_t TypeMap[] = {
{0, ".dat"},
{1, ".bmp"},
{2, ".tga"},
{5, ".skel"},
{7, ".anim"},
{9, ".mesh"},
{11, ".bnd"},
{12, ".apr"},
{13, ".oft"},
{14, ".png"},
{15, ".po"},
{16, ".col"},
{18, ".hag"},
{20, ".jpg"},
{24, ".png"},
{0x0A8B0E70, ".mad"},
{0x1B6B9806, ".utk"},
{0x1D07EB4B, ".xa"},
{0x1D968538, ".xa"},
{0x2026960B, ".dat"},
{0x3CEC2B47, ".mp3"},
{0x3D968536, ".mp3"},
{0x5D73A611, ".trk"},
{0x7B1ACFCD, ".hls"},
{0x856DDBAC, ".bmp"},
{0x9D796DB4, ".tlo"},
{0x9D96853A, ".wav"},
{0xA3CD96CF, ".tkd"},
{0xBB7051F5, ".wav"}
};
static const HeaderMap_t AudioHeaders[] = {
{2, "XA", ".xa"},
{4, "RIFF", ".wav"},
{4, "UTM0", ".utk"},
{4, "\xFF\xFB\x90\x40", ".mp3"},
{24, "# Generated by UI editor", ".scr"}
};
static const char * groupid_to_dir(uint32_t GroupID){
size_t i;
for(i=0; i<sizeof(GroupMap)/sizeof(GroupMap_t); i++){
if(GroupMap[i].GroupID == GroupID)
return GroupMap[i].Directory;
}
fprintf(stderr, "%sUnrecognized Group ID 0x%08X.\n", "farextract: warning: ", GroupID);
return "./";
}
static const char * typeid_to_ext(uint32_t TypeID){
size_t i;
for(i=0; i<sizeof(TypeMap)/sizeof(TypeMap_t); i++){
if(TypeMap[i].TypeID == TypeID)
return TypeMap[i].Extension;
}
fprintf(stderr, "%sUnrecognized Type ID 0x%08X.\n", "farextract: warning: ", TypeID);
return ".dat";
}
static const char * header_to_ext(const uint8_t * Buffer, size_t Size){
size_t i;
for(i=0; i<sizeof(AudioHeaders)/sizeof(HeaderMap_t); i++){
if(Size >= AudioHeaders[i].Size && !memcmp(Buffer, AudioHeaders[i].Header, AudioHeaders[i].Size))
return AudioHeaders[i].Extension;
}
return ".str";
}
int main(int argc, char *argv[]){
int profile = 0, overwrite = 0;
const char * InFile = "", * OutDirectory;
FILE * hFile;
size_t ArchiveSize;
uint8_t * ArchiveData;
int ArchiveType;
clock_t BeginningTime, EndingTime;
unsigned extracted = 0;
int i;
/****
** Check the arguments
*/
if(argc == 1 || (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")))){
printf("Usage: farextract [OPTIONS] [FILE] [OUTDIRECTORY]\n"
"Extract the contents of a FAR, DBPF, or Persist file.\n"
"With no FILE, or when FILE is -, read from standard input.\n"
"\n"
"Profile options:\n"
" -ts1, -tso, -sc4, Select presets suitable for The Sims 1,\n"
" -ts2, -spore, -ts3 The Sims Online, SimCity 4, Spore, or The Sims 3\n"
"\n");
printf("Miscellaneous options:\n"
" -f, --force Force overwriting of files without confirmation\n"
" -h, --help Show this help and exit\n"
"\n"
"Report bugs to <X-Fi6@phppoll.org>.\n"
"farextract and libfar are maintained by the Niotso project.\n"
"Home page: <http://www.niotso.org/>\n");
return 0;
}
for(i=1; !InFile[0] && i != argc-1; i++){
/* Match for options */
if(!profile){
if(!strcmp(argv[i], "-ts1")){ profile = profile_ts1; continue; }
if(!strcmp(argv[i], "-tso")){ profile = profile_tso; continue; }
if(!strcmp(argv[i], "-sc4")){ profile = profile_sc4; continue; }
if(!strcmp(argv[i], "-ts2")){ profile = profile_ts2; continue; }
if(!strcmp(argv[i], "-spore")){ profile = profile_spore; continue; }
if(!strcmp(argv[i], "-ts3")){ profile = profile_ts3; continue; }
}
if(!overwrite && (!strcmp(argv[i], "-f") || !strcmp(argv[i], "--force"))){
overwrite = 1;
continue;
}
/* Not an option */
if(!strcmp(argv[i], "-")){
fprintf(stderr, "%sReading from standard input is not yet implemented.", "farextract: error: ");
return -1;
}
InFile = argv[i];
continue;
}
/* We're left with the out directory */
if(!InFile[0]){
fprintf(stderr, "%sReading from standard input is not yet implemented.", "farextract: error: ");
return -1;
}
OutDirectory = argv[i];
/****
** Handle profile settings
*/
if(!profile) profile = profile_tso;
libfar_set_option(FAR_CONFIG_DEFAULT_TO_1A, (profile == profile_ts1));
libfar_set_option(FAR_CONFIG_DBPF_COMPRESSED, (profile >= profile_sc4));
libfar_set_option(FAR_CONFIG_REFPACK_HNSV, 0xFB);
/****
** Open the file and read in the entire contents to memory
*/
hFile = fopen(InFile, "rb");
if(hFile == NULL){
fprintf(stderr, "%sThe specified input file does not exist or could not be opened for reading.", "farextract: error: ");
return -1;
}
fseek(hFile, 0, SEEK_END);
ArchiveSize = ftell(hFile);
if(ArchiveSize < 24){
fprintf(stderr, "%sNot a valid archive.", "farextract: error: ");
return -1;
}
fseek(hFile, 0, SEEK_SET);
ArchiveData = malloc(ArchiveSize);
if(ArchiveData == NULL){
fprintf(stderr, "%sMemory for this archive could not be allocated.", "farextract: error: ");
return -1;
}
if(fread(ArchiveData, 1, ArchiveSize, hFile) != ArchiveSize){
fprintf(stderr, "%sThe input file could not be read.", "farextract: error: ");
return -1;
}
fclose(hFile);
/****
** Identify the type of archive
*/
ArchiveType = far_identify(ArchiveData, ArchiveSize);
if(ArchiveType == FAR_TYPE_INVALID){
fprintf(stderr, "%sNot a valid archive.", "farextract: error: ");
return -1;
}
if(chdir(OutDirectory) != 0){
fprintf(stderr, "%sOutput directory '%s' does not exist.", "farextract: error: ", OutDirectory);
return -1;
}
if(ArchiveType != FAR_TYPE_PERSIST){
FAREntryNode * EntryNode;
unsigned file = 0, filescount;
/****
** Load header information
*/
FARFile * FARFileInfo = far_create_archive(ArchiveType);
if(FARFileInfo == NULL){
fprintf(stderr, "%sMemory for this archive could not be allocated.", "farextract: error: ");
return -1;
}
if(!far_read_header(FARFileInfo, ArchiveData, ArchiveSize)){
fprintf(stderr, "%sNot a valid archive.", "farextract: error: ");
return -1;
}
filescount = FARFileInfo->Files;
printf("This archive contains %u files.\n\nExtracting\n", filescount);
BeginningTime = clock();
/****
** Load entry information
*/
if(!far_enumerate_entries(FARFileInfo, ArchiveData+FARFileInfo->IndexOffset,
ArchiveSize-FARFileInfo->IndexOffset, ArchiveSize)){
fprintf(stderr, "%sEntry data is corrupt.", "farextract: error: ");
return -1;
}
/****
** Extract each entry
*/
for(EntryNode = FARFileInfo->FirstEntry; EntryNode; EntryNode = EntryNode->NextEntry){
char destbuffer[256], * destination = destbuffer;
file++;
if(EntryNode->Entry.Filename)
destination = EntryNode->Entry.Filename;
else
sprintf(destbuffer, "%s%08x%s", groupid_to_dir(EntryNode->Entry.GroupID),
EntryNode->Entry.FileID, typeid_to_ext(EntryNode->Entry.TypeID));
if(far_read_entry_data(FARFileInfo, &(EntryNode->Entry), ArchiveData)){
/* Decompression, if any, was successful */
if(!EntryNode->Entry.Filename && EntryNode->Entry.TypeID == 0x2026960B)
sprintf(destbuffer, "%s%08x%s", groupid_to_dir(EntryNode->Entry.GroupID), EntryNode->Entry.FileID,
header_to_ext(EntryNode->Entry.DecompressedData, EntryNode->Entry.DecompressedSize));
}else{
printf(" (%u/%u) Skipped (%s): %s\n", file, filescount, "entry data is corrupt", destination);
continue;
}
if(mkpath(destination) != 0){
fprintf(stderr, "%sCould not create path '%s'.", "farextract: error: ", destination);
return -1;
}
if(!overwrite){
hFile = fopen(destination, "rb");
if(hFile != NULL){
/* File exists */
fclose(hFile);
printf(" (%u/%u) Skipped (%s): %s\n", file, filescount, "file exists", destination);
if(EntryNode->Entry.DecompressedData != EntryNode->Entry.CompressedData)
libfar_free(EntryNode->Entry.DecompressedData);
continue;
}
}
hFile = fopen(destination, "wb");
if(hFile == NULL){
printf(" (%u/%u) Skipped (%s): %s\n", file, filescount, "could not open", destination);
if(EntryNode->Entry.DecompressedData != EntryNode->Entry.CompressedData)
libfar_free(EntryNode->Entry.DecompressedData);
continue;
}
printf(" (%u/%u) %s (Group ID: 0x%08X, File ID: 0x%08X, Type ID: 0x%08X) (%u bytes)\n", file, filescount,
destination, EntryNode->Entry.GroupID, EntryNode->Entry.FileID, EntryNode->Entry.TypeID,
EntryNode->Entry.DecompressedSize);
fwrite(EntryNode->Entry.DecompressedData, 1, EntryNode->Entry.DecompressedSize, hFile);
fclose(hFile);
if(EntryNode->Entry.DecompressedData != EntryNode->Entry.CompressedData)
libfar_free(EntryNode->Entry.DecompressedData);
extracted++;
}
printf("\nFinished extracting %u of %u files in %.2f seconds.", extracted, filescount,
((float) (clock() - BeginningTime))/CLOCKS_PER_SEC);
}else{
/* Persist file */
PersistFile * PersistInfo;
/****
** Load header information
*/
PersistInfo = far_create_persist();
if(PersistInfo == NULL){
fprintf(stderr, "%sMemory for this archive could not be allocated.", "farextract: error: ");
return -1;
}
if(!far_read_persist_header(PersistInfo, ArchiveData, ArchiveSize)){
fprintf(stderr, "%sNot a valid archive.", "farextract: error: ");
return -1;
}
/****
** Extract the data
*/
printf("Extracting\n");
BeginningTime = clock();
if(!far_read_persist_data(PersistInfo, ArchiveData+18)){
fprintf(stderr, "%sNot a valid archive.", "farextract: error: ");
return -1;
}
EndingTime = clock();
if(!overwrite){
hFile = fopen(InFile, "rb");
if(hFile != NULL){
/* File exists */
fclose(hFile);
fprintf(stderr, "%sFile exists.", "farextract: error: ");
libfar_free(PersistInfo->DecompressedData);
return -1;
}
}
hFile = fopen(InFile, "wb");
if(hFile == NULL){
fprintf(stderr, "%sCould not open.", "farextract: error: ");
libfar_free(PersistInfo->DecompressedData);
return -1;
}
fwrite(PersistInfo->DecompressedData, 1, PersistInfo->DecompressedSize, hFile);
fclose(hFile);
printf("Extracted %u bytes in %.2f seconds.\n", PersistInfo->DecompressedSize,
((float) (EndingTime - BeginningTime))/CLOCKS_PER_SEC);
}
return 0;
}

View file

@ -0,0 +1,200 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="191.67342"
height="69.682022"
id="svg2"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="libfar.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="209.27206"
inkscape:cy="113.29596"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1030"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
fit-margin-top="2"
fit-margin-left="2"
fit-margin-right="2"
fit-margin-bottom="2" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-98.729108,-354.59789)">
<g
style="font-size:80.0009613px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:ParkAvenue BT;-inkscape-font-specification:ParkAvenue BT"
id="text2989">
<path
d="m 100.72911,361.63701 6.56014,-4.1602 0,45.6817 -6.56014,0 z"
style="font-family:Blue Highway;-inkscape-font-specification:Blue Highway"
id="path3052" />
<path
d="m 115.10672,368.99794 6.56014,0 0,34.16057 -6.56014,0 z m 3.28129,-3.52055 c -1.12144,4e-5 -2.01541,-0.4264 -2.68192,-1.27931 -0.66651,-0.85284 -0.99977,-1.89289 -0.99976,-3.12016 -10e-6,-1.27926 0.32023,-2.34576 0.9607,-3.1995 0.64047,-0.85364 1.54746,-1.28048 2.72098,-1.28053 1.01238,5e-5 1.87868,0.42689 2.59891,1.28053 0.72021,0.85374 1.08032,1.92024 1.08034,3.1995 -2e-5,1.22727 -0.37355,2.26732 -1.12062,3.12016 -0.74709,0.85291 -1.59997,1.27935 -2.55863,1.27931 z"
style="font-family:Blue Highway;-inkscape-font-specification:Blue Highway"
id="path3054" />
<path
d="m 135.88578,391.31755 c 0.10741,0.53387 0.34749,1.13405 0.72022,1.80055 0.37272,0.66653 0.83903,1.27973 1.39895,1.83963 0.55989,0.55991 1.19995,1.04005 1.92019,1.44044 0.7202,0.4004 1.50757,0.6006 2.36208,0.6006 1.17188,0 2.22454,-0.27995 3.158,-0.83986 0.93342,-0.55989 1.72038,-1.30656 2.36087,-2.24001 0.64045,-0.93344 1.1206,-2.04022 1.44045,-3.32036 0.3198,-1.28011 0.47971,-2.64039 0.47974,-4.08086 -3e-5,-3.57261 -0.55993,-6.34567 -1.67971,-8.31919 -1.11983,-1.97347 -3.12017,-2.96021 -6.00105,-2.96024 -1.59997,3e-5 -2.91997,0.60021 -3.96001,1.80056 -1.04006,1.2004 -1.7733,2.68031 -2.19973,4.43975 z m -6.56014,-30.55945 6.56014,-2.8809 0,13.92107 c 0.69336,-0.90656 1.76026,-1.66666 3.20072,-2.2803 1.44043,-0.61358 2.96063,-0.92039 4.5606,-0.92042 3.89326,3e-5 6.91982,1.57353 9.0797,4.72051 2.15983,3.14704 3.23976,7.54691 3.23979,13.19962 -3e-5,2.40076 -0.29341,4.64118 -0.88014,6.72128 -0.58679,2.08011 -1.44007,3.89328 -2.55984,5.43951 -1.11984,1.54625 -2.46669,2.75964 -4.04058,3.64018 -1.57393,0.88055 -3.34723,1.32082 -5.31989,1.32082 -1.49417,0 -2.84103,-0.29338 -4.04057,-0.88014 -1.19958,-0.58675 -2.2795,-1.73382 -3.23979,-3.4412 l 0,3.84038 -6.56014,0 z"
style="font-family:Blue Highway;-inkscape-font-specification:Blue Highway"
id="path3056" />
<path
d="m 169.59468,403.15851 -6.00105,0 0,-27.60043 -3.59868,0 0,-6.56014 3.59868,0 c -1e-5,-3.83952 0.74667,-6.82621 2.24002,-8.96007 1.49333,-2.13377 3.78706,-3.20067 6.88118,-3.20072 1.01237,5e-5 2.07846,0.0806 3.19828,0.2417 l 0,5.99861 c -1.27933,-0.21318 -2.34583,-0.30636 -3.1995,-0.27954 -0.8537,0.0269 -1.53364,0.25354 -2.03982,0.67994 -0.5062,0.42647 -0.86591,1.07996 -1.07911,1.96047 -0.21323,0.88058 -0.31984,2.06712 -0.31983,3.55961 l 6.71883,0 0,6.56014 -6.399,0 z"
style="font-family:Blue Highway;-inkscape-font-specification:Blue Highway"
id="path3058" />
<path
d="m 199.10675,388.91761 c -2e-5,-0.42642 -0.17336,-0.83943 -0.52002,-1.23902 -0.34671,-0.39957 -0.78657,-0.74625 -1.3196,-1.04006 -0.53307,-0.29376 -1.09297,-0.52041 -1.67971,-0.67994 -0.58677,-0.15949 -1.14708,-0.23924 -1.68093,-0.23926 -4.53294,2e-5 -6.7994,1.89295 -6.79939,5.67878 -1e-5,1.59997 0.59977,2.89352 1.79933,3.88066 1.19955,0.98717 2.62616,1.48074 4.27984,1.48074 0.53385,0 1.13403,-0.0802 1.80056,-0.24049 0.66649,-0.16031 1.30656,-0.38696 1.92019,-0.67994 0.61359,-0.29296 1.13362,-0.65307 1.56008,-1.08033 0.42641,-0.42724 0.63963,-0.93384 0.63965,-1.51979 z m 0.0806,11.28188 c -0.53388,0.79916 -1.49418,1.54543 -2.8809,2.23879 -1.38675,0.69337 -3.06645,1.04006 -5.03912,1.04006 -1.49417,0 -2.89433,-0.26653 -4.20049,-0.79957 -1.30617,-0.53305 -2.45283,-1.3196 -3.43998,-2.35965 -0.98716,-1.04005 -1.76069,-2.29332 -2.32059,-3.75981 -0.5599,-1.46648 -0.83985,-3.13317 -0.83985,-5.00006 0,-3.84118 1.10678,-6.77497 3.32035,-8.80138 2.21356,-2.02637 5.10666,-3.03956 8.67931,-3.03958 1.28092,2e-5 2.48129,0.1465 3.60111,0.43945 1.11979,0.293 2.13298,0.94649 3.03959,1.96048 -2e-5,-1.44043 -0.14651,-2.60052 -0.43946,-3.48027 -0.29299,-0.87971 -0.70641,-1.55964 -1.24025,-2.03982 -0.53388,-0.48012 -1.21422,-0.81338 -2.04104,-0.99977 -0.82685,-0.18633 -1.74645,-0.27951 -2.75882,-0.27954 -1.22724,3e-5 -2.28072,0.19982 -3.16044,0.59937 -0.87974,0.39961 -1.66629,0.89319 -2.35964,1.48073 l -2.96147,-5.04156 c 1.06772,-1.17349 2.40155,-2.08007 4.00152,-2.71976 1.59994,-0.63962 3.38625,-0.95945 5.35895,-0.95949 3.68004,4e-5 6.64027,1.10682 8.88072,3.32036 2.2404,2.21359 3.36061,5.24016 3.36064,9.07969 l 0,22.08035 -6.56014,0 z"
style="font-family:Blue Highway;-inkscape-font-specification:Blue Highway"
id="path3060" />
<path
d="m 226.83658,376.19774 c -1.06611,-0.58592 -1.86609,-0.87889 -2.39994,-0.87892 -1.70576,3e-5 -2.93217,0.65311 -3.67924,1.95925 -0.74709,1.30619 -1.12063,2.91957 -1.12062,4.84015 l 0,21.04029 -6.56014,0 0,-34.16057 6.56014,0 0,4.07964 c 0.37272,-1.3867 1.13241,-2.4532 2.27908,-3.1995 1.14665,-0.74623 2.4402,-1.11936 3.88066,-1.1194 1.28093,4e-5 2.37469,0.29301 3.28129,0.87892 z"
style="font-family:Blue Highway;-inkscape-font-specification:Blue Highway"
id="path3062" />
</g>
<rect
style="fill:#105785;fill-opacity:1;stroke:none"
id="rect2995"
width="20.804075"
height="20.804075"
x="240.98857"
y="356.87091" />
<rect
y="356.87091"
x="267.59845"
height="20.804075"
width="20.804075"
id="rect2997"
style="fill:#105785;fill-opacity:1;stroke:none" />
<rect
style="fill:#105785;fill-opacity:1;stroke:none"
id="rect2999"
width="20.804075"
height="20.804075"
x="267.59845"
y="382.02936" />
<rect
y="382.02936"
x="240.98863"
height="20.804075"
width="20.804075"
id="rect3001"
style="fill:#105785;fill-opacity:1;stroke:none" />
<g
style="font-size:80.0009613px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:ParkAvenue BT;-inkscape-font-specification:ParkAvenue BT"
id="text3831">
<path
d="m 106.6453,409.23288 -4.37505,0 0,3.87505 4.04692,0 0,1.1797 -4.04692,0 0,4.961 -1.31251,0 0,-11.20326 5.68756,0 z"
style="font-size:16.00019073px;font-family:Gisha;-inkscape-font-specification:Gisha"
id="path3011" />
<path
d="m 117.44231,419.24863 -1.45315,0 -1.18751,-3.14067 -4.75006,0 -1.1172,3.14067 -1.46095,0 4.29692,-11.20326 1.3594,0 z m -3.07035,-4.32037 -1.75784,-4.77349 c -0.0573,-0.15624 -0.11459,-0.40625 -0.17187,-0.75001 l -0.0312,0 c -0.0521,0.31772 -0.11199,0.56772 -0.17969,0.75001 l -1.74221,4.77349 z"
style="font-size:16.00019073px;font-family:Gisha;-inkscape-font-specification:Gisha"
id="path3013" />
<path
d="m 127.1143,419.24863 -1.56252,0 -1.87502,-3.14067 c -0.17189,-0.29166 -0.33856,-0.54036 -0.50001,-0.7461 -0.16147,-0.20573 -0.32683,-0.3737 -0.4961,-0.50391 -0.16928,-0.13021 -0.35157,-0.22526 -0.54688,-0.28516 -0.19532,-0.0599 -0.41538,-0.0898 -0.66017,-0.0899 l -1.07813,0 0,4.76569 -1.31252,0 0,-11.20326 3.34379,0 c 0.48958,1e-5 0.94141,0.0612 1.35549,0.18359 0.41406,0.12241 0.77344,0.30861 1.07813,0.5586 0.30469,0.25002 0.54297,0.56122 0.71486,0.93361 0.17186,0.37241 0.2578,0.80861 0.25781,1.30861 -10e-6,0.39064 -0.0586,0.74871 -0.17578,1.07423 -0.1172,0.32553 -0.28387,0.6159 -0.50001,0.8711 -0.21615,0.25522 -0.47657,0.47267 -0.78126,0.65236 -0.30469,0.17969 -0.64715,0.31902 -1.02735,0.41797 l 0,0.0312 c 0.18749,0.0833 0.35026,0.17839 0.48828,0.28516 0.13802,0.10678 0.26953,0.23308 0.39454,0.37891 0.12499,0.14584 0.24869,0.31121 0.3711,0.4961 0.12239,0.1849 0.25911,0.39975 0.41016,0.64454 z m -6.71883,-10.01575 0,4.06255 1.78127,0 c 0.32812,10e-6 0.63151,-0.0495 0.91016,-0.14844 0.27865,-0.099 0.51954,-0.24088 0.72267,-0.42578 0.20312,-0.1849 0.36198,-0.41146 0.47657,-0.6797 0.11458,-0.26823 0.17187,-0.56901 0.17188,-0.90235 -1e-5,-0.59896 -0.19402,-1.06641 -0.58204,-1.40237 -0.38803,-0.33593 -0.94924,-0.5039 -1.68362,-0.50391 z"
style="font-size:16.00019073px;font-family:Gisha;-inkscape-font-specification:Gisha"
id="path3015" />
<path
d="m 135.31752,416.06109 c -0.54167,0 -1.00783,-0.1901 -1.39845,-0.57032 -0.39063,-0.38021 -0.58595,-0.84115 -0.58595,-1.38283 0,-0.53646 0.19532,-1.00131 0.58595,-1.39455 0.39062,-0.39322 0.85678,-0.58984 1.39845,-0.58985 0.54167,1e-5 1.00261,0.19532 1.38283,0.58595 0.38021,0.39063 0.57031,0.85678 0.57032,1.39845 -1e-5,0.54168 -0.19011,1.00262 -0.57032,1.38283 -0.38022,0.38022 -0.84116,0.57032 -1.38283,0.57032 z"
style="letter-spacing:0.50000596px"
id="path3017" />
<path
d="m 145.39577,419.24863 0,-11.20326 3.09378,0 c 3.94796,1e-5 5.92194,1.82034 5.92195,5.461 -1e-5,1.72919 -0.5482,3.11853 -1.64455,4.16802 -1.09638,1.04949 -2.56384,1.57424 -4.4024,1.57424 z m 1.31251,-10.01575 0,8.82823 1.6719,0 c 1.46876,0 2.612,-0.39323 3.42972,-1.1797 0.81771,-0.78646 1.22657,-1.90106 1.22658,-3.34379 -1e-5,-2.86982 -1.52607,-4.30473 -4.57818,-4.30474 z"
style="font-size:16.00019073px;font-family:Gisha;-inkscape-font-specification:Gisha"
id="path3019" />
<path
d="m 156.61465,419.24863 0,-11.20326 3.18754,0 c 0.96875,1e-5 1.73699,0.23699 2.30471,0.71094 0.56771,0.47398 0.85157,1.09117 0.85157,1.85159 0,0.63543 -0.17188,1.18752 -0.51563,1.65627 -0.34376,0.46876 -0.81772,0.8021 -1.42189,1.00001 l 0,0.0312 c 0.75521,0.0885 1.35939,0.37371 1.81252,0.85548 0.45313,0.48178 0.67969,1.10809 0.6797,1.87893 -1e-5,0.95835 -0.34376,1.7344 -1.03126,2.32815 -0.68752,0.59376 -1.55472,0.89064 -2.6016,0.89064 z m 1.31251,-10.01575 0,3.61723 1.34377,0 c 0.71875,1e-5 1.28386,-0.17317 1.69533,-0.51953 0.41146,-0.34636 0.61719,-0.83464 0.6172,-1.46487 -1e-5,-1.08854 -0.71616,-1.63282 -2.14846,-1.63283 z m 0,4.79693 0,4.0313 1.78128,0 c 0.77083,0 1.3685,-0.18229 1.79299,-0.54688 0.42447,-0.36458 0.63672,-0.86459 0.63672,-1.50002 0,-1.32292 -0.90106,-1.98439 -2.70315,-1.9844 z"
style="font-size:16.00019073px;font-family:Gisha;-inkscape-font-specification:Gisha"
id="path3021" />
<path
d="m 167.11477,415.0142 0,4.23443 -1.31251,0 0,-11.20326 3.07816,0 c 1.19792,1e-5 2.12632,0.29168 2.78519,0.87501 0.65885,0.58335 0.98828,1.40627 0.98829,2.46878 -1e-5,1.06252 -0.3659,1.93232 -1.09767,2.6094 -0.73179,0.6771 -1.72008,1.01565 -2.96488,1.01564 z m 0,-5.78132 0,4.59381 1.37502,0 c 0.90625,0 1.59767,-0.20703 2.07424,-0.6211 0.47656,-0.41407 0.71485,-0.99871 0.71485,-1.75393 0,-1.47918 -0.87501,-2.21877 -2.62503,-2.21878 z"
style="font-size:16.00019073px;font-family:Gisha;-inkscape-font-specification:Gisha"
id="path3023" />
<path
d="m 180.45868,409.23288 -4.37505,0 0,3.87505 4.04692,0 0,1.1797 -4.04692,0 0,4.961 -1.31252,0 0,-11.20326 5.68757,0 z"
style="font-size:16.00019073px;font-family:Gisha;-inkscape-font-specification:Gisha"
id="path3025" />
<path
d="m 189.25566,416.06109 c -0.54167,0 -1.00782,-0.1901 -1.39845,-0.57032 -0.39063,-0.38021 -0.58595,-0.84115 -0.58595,-1.38283 0,-0.53646 0.19532,-1.00131 0.58595,-1.39455 0.39063,-0.39322 0.85678,-0.58984 1.39845,-0.58985 0.54167,1e-5 1.00261,0.19532 1.38283,0.58595 0.38021,0.39063 0.57031,0.85678 0.57032,1.39845 -1e-5,0.54168 -0.19011,1.00262 -0.57032,1.38283 -0.38022,0.38022 -0.84116,0.57032 -1.38283,0.57032 z"
style="letter-spacing:0.50000596px"
id="path3027" />
<path
d="m 200.64643,415.0142 0,4.23443 -1.31252,0 0,-11.20326 3.07816,0 c 1.19793,1e-5 2.12632,0.29168 2.78519,0.87501 0.65886,0.58335 0.98829,1.40627 0.98829,2.46878 0,1.06252 -0.36589,1.93232 -1.09766,2.6094 -0.73179,0.6771 -1.72008,1.01565 -2.96488,1.01564 z m 0,-5.78132 0,4.59381 1.37501,0 c 0.90626,0 1.59767,-0.20703 2.07425,-0.6211 0.47656,-0.41407 0.71484,-0.99871 0.71485,-1.75393 -1e-5,-1.47918 -0.87502,-2.21877 -2.62503,-2.21878 z"
style="font-size:16.00019073px;font-family:Gisha;-inkscape-font-specification:Gisha"
id="path3029" />
<path
d="m 214.56065,415.5689 -5.6485,0 c 0.0208,0.89063 0.26042,1.57814 0.71876,2.06252 0.45833,0.48438 1.08855,0.72657 1.89065,0.72657 0.90104,0 1.72918,-0.29688 2.4844,-0.89063 l 0,1.20313 c -0.70314,0.51043 -1.63284,0.76564 -2.7891,0.76564 -1.13022,0 -2.01825,-0.36329 -2.66409,-1.08986 -0.64584,-0.72657 -0.96876,-1.74871 -0.96876,-3.06644 0,-1.2448 0.35287,-2.25914 1.0586,-3.04301 0.70574,-0.78385 1.58205,-1.17578 2.62894,-1.17579 1.04688,10e-6 1.85679,0.33855 2.42972,1.01564 0.57292,0.67709 0.85938,1.61721 0.85938,2.82034 z m -1.31251,-1.08596 c -0.005,-0.73958 -0.1836,-1.31511 -0.53516,-1.72658 -0.35158,-0.41145 -0.83986,-0.61719 -1.46487,-0.61719 -0.60417,0 -1.1172,0.21615 -1.53908,0.64844 -0.42188,0.43231 -0.6823,0.99742 -0.78126,1.69533 z"
style="font-size:16.00019073px;font-family:Gisha;-inkscape-font-specification:Gisha"
id="path3031" />
<path
d="m 220.67791,412.54542 c -0.22396,-0.17187 -0.54688,-0.25781 -0.96876,-0.25781 -0.54688,0 -1.00392,0.25782 -1.37111,0.77344 -0.36719,0.51564 -0.55079,1.21877 -0.55079,2.1094 l 0,4.07818 -1.28126,0 0,-8.0001 1.28126,0 0,1.64846 0.0312,0 c 0.1823,-0.5625 0.46094,-1.00131 0.83595,-1.31642 0.375,-0.3151 0.79428,-0.47266 1.25783,-0.47267 0.33333,1e-5 0.58854,0.0365 0.76563,0.10938 z"
style="font-size:16.00019073px;font-family:Gisha;-inkscape-font-specification:Gisha"
id="path3033" />
<path
d="m 221.58417,418.95956 0,-1.37502 c 0.69792,0.51564 1.46616,0.77345 2.30471,0.77345 1.12501,0 1.68752,-0.375 1.68752,-1.12501 0,-0.21354 -0.0482,-0.39454 -0.14453,-0.54298 -0.0964,-0.14843 -0.22657,-0.27995 -0.39063,-0.39453 -0.16407,-0.11459 -0.35678,-0.21745 -0.57813,-0.3086 -0.22136,-0.0911 -0.45964,-0.1862 -0.71485,-0.28516 -0.35418,-0.14062 -0.66538,-0.28255 -0.93361,-0.42579 -0.26823,-0.14322 -0.49219,-0.30468 -0.67188,-0.48438 -0.17969,-0.17968 -0.31511,-0.38411 -0.40625,-0.61329 -0.0911,-0.22916 -0.13673,-0.49739 -0.13673,-0.80469 0,-0.375 0.0859,-0.70704 0.25782,-0.99611 0.17188,-0.28906 0.40105,-0.53125 0.68751,-0.72657 0.28646,-0.19531 0.61328,-0.34244 0.98048,-0.44141 0.36719,-0.099 0.7461,-0.14843 1.13673,-0.14844 0.69271,10e-6 1.31251,0.1198 1.8594,0.35938 l 0,1.29689 c -0.58856,-0.38542 -1.26565,-0.57813 -2.03128,-0.57813 -0.23959,0 -0.45573,0.0274 -0.64844,0.082 -0.19271,0.0547 -0.35808,0.13152 -0.4961,0.23047 -0.13803,0.099 -0.2448,0.21746 -0.32032,0.35547 -0.0755,0.13803 -0.11328,0.29038 -0.11328,0.45704 0,0.20834 0.0378,0.38282 0.11328,0.52344 0.0755,0.14064 0.1862,0.26564 0.33204,0.37501 0.14583,0.10938 0.32292,0.20834 0.53125,0.29688 0.20834,0.0885 0.44532,0.1849 0.71095,0.28906 0.35417,0.13543 0.67188,0.27475 0.95314,0.41798 0.28125,0.14323 0.52083,0.30469 0.71876,0.48438 0.19791,0.17969 0.35025,0.38672 0.45703,0.6211 0.10677,0.23438 0.16015,0.51303 0.16016,0.83595 -1e-5,0.39584 -0.0873,0.73959 -0.26172,1.03126 -0.17449,0.29167 -0.40756,0.53386 -0.69923,0.72657 -0.29167,0.19271 -0.62761,0.33594 -1.00782,0.42969 -0.38022,0.0937 -0.77866,0.14063 -1.19533,0.14063 -0.82293,0 -1.53648,-0.15886 -2.14065,-0.47657 z"
style="font-size:16.00019073px;font-family:Gisha;-inkscape-font-specification:Gisha"
id="path3035" />
<path
d="m 229.4202,409.21726 c -0.22917,10e-6 -0.42448,-0.0781 -0.58594,-0.23438 -0.16146,-0.15624 -0.24219,-0.35416 -0.24219,-0.59376 0,-0.23957 0.0807,-0.43879 0.24219,-0.59766 0.16146,-0.15885 0.35677,-0.23827 0.58594,-0.23829 0.23438,2e-5 0.4336,0.0794 0.59767,0.23829 0.16406,0.15887 0.24609,0.35809 0.24609,0.59766 0,0.22918 -0.082,0.4245 -0.24609,0.58595 -0.16407,0.16147 -0.36329,0.2422 -0.59767,0.24219 z m 0.62501,7.79697 c 0,0.73438 0.28386,1.10157 0.85157,1.10157 0.22917,0 0.4349,-0.0286 0.6172,-0.0859 l 0,1.15627 c -0.099,0.026 -0.23048,0.0508 -0.39454,0.0742 -0.16407,0.0234 -0.33724,0.0351 -0.51953,0.0351 -0.25522,0 -0.49481,-0.0417 -0.71876,-0.125 -0.22397,-0.0833 -0.41798,-0.21094 -0.58204,-0.38282 -0.16407,-0.17187 -0.29428,-0.38672 -0.39063,-0.64454 -0.0964,-0.25781 -0.14454,-0.55859 -0.14453,-0.90235 l 0,-5.99226 1.28126,0 z"
style="font-size:16.00019073px;font-family:Gisha;-inkscape-font-specification:Gisha"
id="path3037" />
<path
d="m 232.42805,418.95956 0,-1.37502 c 0.69792,0.51564 1.46616,0.77345 2.30471,0.77345 1.12501,0 1.68752,-0.375 1.68752,-1.12501 0,-0.21354 -0.0482,-0.39454 -0.14453,-0.54298 -0.0964,-0.14843 -0.22657,-0.27995 -0.39063,-0.39453 -0.16407,-0.11459 -0.35678,-0.21745 -0.57813,-0.3086 -0.22136,-0.0911 -0.45964,-0.1862 -0.71485,-0.28516 -0.35418,-0.14062 -0.66538,-0.28255 -0.93361,-0.42579 -0.26823,-0.14322 -0.49219,-0.30468 -0.67188,-0.48438 -0.17969,-0.17968 -0.31511,-0.38411 -0.40626,-0.61329 -0.0911,-0.22916 -0.13672,-0.49739 -0.13672,-0.80469 0,-0.375 0.0859,-0.70704 0.25782,-0.99611 0.17188,-0.28906 0.40104,-0.53125 0.68751,-0.72657 0.28646,-0.19531 0.61328,-0.34244 0.98048,-0.44141 0.36719,-0.099 0.7461,-0.14843 1.13673,-0.14844 0.69271,10e-6 1.31251,0.1198 1.8594,0.35938 l 0,1.29689 c -0.58856,-0.38542 -1.26565,-0.57813 -2.03128,-0.57813 -0.23959,0 -0.45573,0.0274 -0.64844,0.082 -0.19271,0.0547 -0.35808,0.13152 -0.4961,0.23047 -0.13803,0.099 -0.2448,0.21746 -0.32032,0.35547 -0.0755,0.13803 -0.11328,0.29038 -0.11328,0.45704 0,0.20834 0.0378,0.38282 0.11328,0.52344 0.0755,0.14064 0.1862,0.26564 0.33204,0.37501 0.14583,0.10938 0.32292,0.20834 0.53125,0.29688 0.20834,0.0885 0.44532,0.1849 0.71095,0.28906 0.35417,0.13543 0.67188,0.27475 0.95314,0.41798 0.28124,0.14323 0.52083,0.30469 0.71876,0.48438 0.19791,0.17969 0.35025,0.38672 0.45703,0.6211 0.10677,0.23438 0.16015,0.51303 0.16016,0.83595 -1e-5,0.39584 -0.0873,0.73959 -0.26172,1.03126 -0.17449,0.29167 -0.40756,0.53386 -0.69923,0.72657 -0.29167,0.19271 -0.62762,0.33594 -1.00782,0.42969 -0.38022,0.0937 -0.77866,0.14063 -1.19533,0.14063 -0.82293,0 -1.53648,-0.15886 -2.14065,-0.47657 z"
style="font-size:16.00019073px;font-family:Gisha;-inkscape-font-specification:Gisha"
id="path3039" />
<path
d="m 243.40474,419.1705 c -0.30209,0.16667 -0.70054,0.25 -1.19533,0.25 -1.40106,0 -2.10159,-0.78125 -2.10159,-2.34377 l 0,-4.73444 -1.37501,0 0,-1.09376 1.37501,0 0,-1.95315 1.28127,-0.41406 0,2.36721 2.01565,0 0,1.09376 -2.01565,0 0,4.50787 c 0,0.53647 0.0911,0.91928 0.27344,1.14845 0.18229,0.22917 0.48438,0.34376 0.90626,0.34376 0.32292,0 0.60157,-0.0885 0.83595,-0.26563 z"
style="font-size:16.00019073px;font-family:Gisha;-inkscape-font-specification:Gisha"
id="path3041" />
<path
d="m 251.97517,416.06109 c -0.54168,0 -1.00783,-0.1901 -1.39846,-0.57032 -0.39063,-0.38021 -0.58594,-0.84115 -0.58594,-1.38283 0,-0.53646 0.19531,-1.00131 0.58594,-1.39455 0.39063,-0.39322 0.85678,-0.58984 1.39846,-0.58985 0.54167,1e-5 1.00261,0.19532 1.38283,0.58595 0.3802,0.39063 0.57031,0.85678 0.57032,1.39845 -1e-5,0.54168 -0.19012,1.00262 -0.57032,1.38283 -0.38022,0.38022 -0.84116,0.57032 -1.38283,0.57032 z"
style="letter-spacing:0.50000596px"
id="path3043" />
<path
d="m 266.49096,419.43613 c -0.33334,0 -0.67189,-0.0326 -1.01564,-0.0977 -0.34375,-0.0651 -0.67709,-0.16406 -1.00001,-0.29688 -0.32292,-0.13281 -0.63152,-0.29688 -0.92579,-0.49219 -0.29428,-0.19531 -0.56121,-0.42318 -0.80079,-0.6836 -0.95314,-1.04168 -1.42971,-2.40367 -1.42971,-4.08599 0,-1.8073 0.48438,-3.24482 1.45315,-4.31255 0.97917,-1.07292 2.31773,-1.60938 4.01567,-1.60939 1.52084,1e-5 2.75523,0.52085 3.70317,1.56251 0.94792,1.04169 1.42188,2.40369 1.42189,4.08599 -10e-6,0.70835 -0.0794,1.37632 -0.23828,2.00393 -0.15887,0.62762 -0.39976,1.19403 -0.72267,1.69924 -0.32293,0.50522 -0.72918,0.93361 -1.21876,1.28517 -0.4896,0.35157 -1.06773,0.60287 -1.7344,0.75392 0.27083,0.29167 0.52474,0.54948 0.76173,0.77344 0.23697,0.22396 0.47395,0.41277 0.71095,0.56642 0.23697,0.15364 0.48306,0.26953 0.73829,0.34766 0.2552,0.0781 0.53645,0.11718 0.84376,0.11719 0.0833,-10e-6 0.17447,-0.004 0.27344,-0.0117 0.0989,-0.008 0.19921,-0.0208 0.30078,-0.0391 0.10155,-0.0182 0.19921,-0.0391 0.29297,-0.0625 0.0937,-0.0234 0.17968,-0.0508 0.25782,-0.082 l 0,1.26564 c -0.0833,0.026 -0.1771,0.0482 -0.28125,0.0664 -0.10418,0.0182 -0.20965,0.0339 -0.31641,0.0469 -0.10679,0.013 -0.21226,0.0234 -0.31641,0.0312 -0.10418,0.008 -0.20054,0.0117 -0.28907,0.0117 -0.50002,0 -0.94924,-0.0742 -1.34767,-0.22266 -0.39845,-0.14844 -0.77085,-0.35157 -1.1172,-0.60938 -0.34637,-0.25782 -0.68101,-0.5586 -1.00392,-0.90235 -0.32293,-0.34376 -0.66147,-0.71355 -1.01564,-1.10939 z m 0.17188,-10.39075 c -1.1771,10e-6 -2.13284,0.42449 -2.86722,1.27345 -0.73439,0.84898 -1.10158,1.96357 -1.10158,3.34379 0,1.37502 0.35677,2.48701 1.07033,3.33598 0.71875,0.83855 1.65366,1.25783 2.80472,1.25783 1.22917,0 2.19793,-0.40105 2.90628,-1.20314 0.70833,-0.80209 1.0625,-1.9245 1.06251,-3.36723 -10e-6,-1.48439 -0.34376,-2.62763 -1.03126,-3.42973 -0.68751,-0.80729 -1.63544,-1.21094 -2.84378,-1.21095 z"
style="font-size:16.00019073px;font-family:Gisha;-inkscape-font-specification:Gisha"
id="path3045" />
<path
d="m 279.80361,409.23288 -4.37505,0 0,3.87505 4.04692,0 0,1.1797 -4.04692,0 0,4.961 -1.31251,0 0,-11.20326 5.68756,0 z"
style="font-size:16.00019073px;font-family:Gisha;-inkscape-font-specification:Gisha"
id="path3047" />
<path
d="m 281.40519,418.7955 0,-1.5469 c 0.17709,0.15626 0.38933,0.29688 0.63673,0.42188 0.2474,0.12501 0.50782,0.23048 0.78126,0.31641 0.27344,0.0859 0.54818,0.15235 0.82423,0.19922 0.27604,0.0469 0.53125,0.0703 0.76563,0.0703 0.8073,0 1.41017,-0.14974 1.80862,-0.44923 0.39843,-0.29948 0.59765,-0.73047 0.59766,-1.29298 -1e-5,-0.30208 -0.0664,-0.56511 -0.19922,-0.78907 -0.13282,-0.22396 -0.31642,-0.42839 -0.55079,-0.61329 -0.23438,-0.1849 -0.51173,-0.36198 -0.83204,-0.53126 -0.32032,-0.16927 -0.66538,-0.34765 -1.03517,-0.53516 -0.39063,-0.19791 -0.75522,-0.39844 -1.09376,-0.60157 -0.33855,-0.20312 -0.63282,-0.42708 -0.88282,-0.67188 -0.25001,-0.24479 -0.44663,-0.52214 -0.58986,-0.83204 -0.14323,-0.3099 -0.21484,-0.67318 -0.21484,-1.08986 0,-0.51041 0.11198,-0.95443 0.33594,-1.33205 0.22396,-0.3776 0.51823,-0.6888 0.88282,-0.9336 0.36459,-0.24479 0.77996,-0.42708 1.24611,-0.54688 0.46615,-0.11979 0.94141,-0.17968 1.4258,-0.17969 1.10417,1e-5 1.90887,0.13282 2.41409,0.39844 l 0,1.47658 c -0.66147,-0.45833 -1.51044,-0.6875 -2.5469,-0.68751 -0.28647,10e-6 -0.57293,0.03 -0.85939,0.0898 -0.28646,0.0599 -0.54168,0.15757 -0.76563,0.29298 -0.22397,0.13543 -0.40626,0.30991 -0.54689,0.52344 -0.14062,0.21355 -0.21094,0.47397 -0.21094,0.78126 0,0.28647 0.0534,0.53387 0.16016,0.7422 0.10677,0.20834 0.26433,0.39845 0.47266,0.57032 0.20834,0.17188 0.46225,0.33855 0.76173,0.5 0.29948,0.16147 0.64454,0.33855 1.03517,0.53126 0.40104,0.19792 0.78125,0.40626 1.14064,0.62501 0.35937,0.21875 0.67448,0.46094 0.94532,0.72657 0.27083,0.26563 0.48568,0.5599 0.64454,0.88282 0.15885,0.32292 0.23828,0.69272 0.23829,1.10939 -1e-5,0.55209 -0.10809,1.01954 -0.32423,1.40236 -0.21615,0.38282 -0.50782,0.69402 -0.87501,0.9336 -0.36719,0.23959 -0.79038,0.41277 -1.26954,0.51954 -0.47918,0.10677 -0.98439,0.16016 -1.51565,0.16016 -0.17708,0 -0.39584,-0.0143 -0.65625,-0.043 -0.26043,-0.0287 -0.52605,-0.0703 -0.79689,-0.125 -0.27084,-0.0547 -0.52735,-0.1224 -0.76954,-0.20313 -0.24219,-0.0807 -0.4362,-0.17057 -0.58204,-0.26953 z"
style="font-size:16.00019073px;font-family:Gisha;-inkscape-font-specification:Gisha"
id="path3049" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 25 KiB

View file

@ -0,0 +1,163 @@
/*
FileHandler - General-purpose file handling library for Niotso
refpack_dec.c - Copyright (c) 2011 Niotso Project <http://niotso.org/>
Author(s): Fatbag <X-Fi6@phppoll.org>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <string.h>
#include <stdint.h>
int RefPackDecompress(const uint8_t *__restrict CompressedData, size_t CompressedSize,
uint8_t *__restrict DecompressedData, size_t DecompressedSize, unsigned HNSV){
unsigned datawritten = 0;
int stopflag = 0, StopFlagData;
if(HNSV == 0) HNSV = 0xFB; /* EA default */
if (HNSV >= 0xFF) StopFlagData = 0x1F;
else if(HNSV >= 0xFE) StopFlagData = 0x00;
else if(HNSV >= 0xFD) StopFlagData = 0x01;
else if(HNSV >= 0xFB) StopFlagData = 0x03;
else if(HNSV >= 0xF7) StopFlagData = 0x07;
else StopFlagData = 0x0F;
while(CompressedSize > 0 && !stopflag){
unsigned ProceedingDataLength, ReferencedDataLength, ReferencedDataOffset;
unsigned currentbyte = *(CompressedData++);
CompressedSize--;
/****
** Fetch the opcode
*/
/* The first byte determines the size of the entire opcode. */
if(currentbyte <= 0x7F){ /* 2 bytes */
if(CompressedSize < 1) return 0;
CompressedSize -= 1;
/* First byte */
ProceedingDataLength = currentbyte & 0x03;
ReferencedDataLength = ((currentbyte & 0x1C) >> 2) + 3;
ReferencedDataOffset = (currentbyte & 0x60) << 3;
/* Second byte */
currentbyte = *(CompressedData++);
ReferencedDataOffset += currentbyte;
}else if(currentbyte <= 0xBF){ /* 3 bytes */
if(CompressedSize < 2) return 0;
CompressedSize -= 2;
/* First byte */
ReferencedDataLength = (currentbyte & 0x3F) + 4;
/* Second byte */
currentbyte = *(CompressedData++);
ProceedingDataLength = (currentbyte & 0xC0) >> 6;
ReferencedDataOffset = (currentbyte & 0x3F) << 8;
/* Third byte */
currentbyte = *(CompressedData++);
ReferencedDataOffset += currentbyte;
}else if(currentbyte <= 0xDF){ /* 4 bytes */
if(CompressedSize < 3) return 0;
CompressedSize -= 3;
/* First byte */
ProceedingDataLength = currentbyte & 0x03;
ReferencedDataLength = ((currentbyte & 0x0C) << 6) + 5;
ReferencedDataOffset = (currentbyte & 0x10) << 12;
/* Second byte */
currentbyte = *(CompressedData++);
ReferencedDataOffset += currentbyte << 8;
/* Third byte */
currentbyte = *(CompressedData++);
ReferencedDataOffset += currentbyte;
/* Fourth byte */
currentbyte = *(CompressedData++);
ReferencedDataLength += currentbyte;
}else{ /* 1 byte: Two different opcode types fall into this category */
if(currentbyte <= HNSV){
ProceedingDataLength = ((currentbyte & 0x1F) + 1) << 2;
}else{
ProceedingDataLength = currentbyte & StopFlagData;
stopflag++;
}
ReferencedDataLength = 0;
}
/****
** Copy proceeding data
*/
if(ProceedingDataLength != 0){
if(ProceedingDataLength > CompressedSize || ProceedingDataLength > DecompressedSize)
return 0;
memcpy(DecompressedData, CompressedData, ProceedingDataLength);
DecompressedSize -= ProceedingDataLength;
CompressedSize -= ProceedingDataLength;
datawritten += ProceedingDataLength;
DecompressedData += ProceedingDataLength;
CompressedData += ProceedingDataLength;
}
/****
** Copy referenced data
*/
if(ReferencedDataLength != 0){
/* It is possible that the offset specified does not provide for a large enough buffer to copy all at once from.
This event would be caused when the referenced data offset is set smaller than the referenced data length.
When this occurs, the decoder is to repeatedly copy/paste the referenced data until the length is satisfied.
We will do this in a way so that we call memcpy ceil(log2(N)) times instead of N times. */
ReferencedDataOffset++;
if(ReferencedDataLength > DecompressedSize || ReferencedDataOffset > datawritten)
return 0;
DecompressedSize -= ReferencedDataLength;
datawritten += ReferencedDataLength;
if(ReferencedDataOffset == 1){
memset(DecompressedData, *(DecompressedData-1), ReferencedDataLength);
DecompressedData += ReferencedDataLength;
}else{
unsigned copylength =
(ReferencedDataOffset < ReferencedDataLength) ? ReferencedDataOffset : ReferencedDataLength;
uint8_t *__restrict copysource = DecompressedData;
memcpy(DecompressedData, DecompressedData-ReferencedDataOffset, copylength);
DecompressedData += copylength;
ReferencedDataLength -= copylength;
while(ReferencedDataLength){
if(copylength > ReferencedDataLength)
copylength = ReferencedDataLength;
memcpy(DecompressedData, copysource, copylength);
DecompressedData += copylength;
ReferencedDataLength -= copylength;
if(!(copylength&0x80000000)) copylength <<= 1;
}
}
}
}
return (stopflag && !CompressedSize && !DecompressedSize);
}