Transition to hekate bdk layout
This commit is contained in:
parent
4425e81085
commit
4ffd4ce7f0
317 changed files with 60891 additions and 1003 deletions
98
bdk/libs/compr/blz.c
Normal file
98
bdk/libs/compr/blz.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2018 rajkosto
|
||||
* Copyright (c) 2018 SciresM
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "blz.h"
|
||||
|
||||
const blz_footer *blz_get_footer(const unsigned char *compData, unsigned int compDataLen, blz_footer *outFooter)
|
||||
{
|
||||
if (compDataLen < sizeof(blz_footer))
|
||||
return NULL;
|
||||
|
||||
const blz_footer *srcFooter = (const blz_footer*)&compData[compDataLen - sizeof(blz_footer)];
|
||||
if (outFooter != NULL)
|
||||
memcpy(outFooter, srcFooter, sizeof(blz_footer)); // Must be a memcpy because no umaligned accesses on ARMv4.
|
||||
|
||||
return srcFooter;
|
||||
}
|
||||
|
||||
// From https://github.com/SciresM/hactool/blob/master/kip.c which is exactly how kernel does it, thanks SciresM!
|
||||
int blz_uncompress_inplace(unsigned char *dataBuf, unsigned int compSize, const blz_footer *footer)
|
||||
{
|
||||
u32 addl_size = footer->addl_size;
|
||||
u32 header_size = footer->header_size;
|
||||
u32 cmp_and_hdr_size = footer->cmp_and_hdr_size;
|
||||
|
||||
unsigned char* cmp_start = &dataBuf[compSize] - cmp_and_hdr_size;
|
||||
u32 cmp_ofs = cmp_and_hdr_size - header_size;
|
||||
u32 out_ofs = cmp_and_hdr_size + addl_size;
|
||||
|
||||
while (out_ofs)
|
||||
{
|
||||
unsigned char control = cmp_start[--cmp_ofs];
|
||||
for (unsigned int i=0; i<8; i++)
|
||||
{
|
||||
if (control & 0x80)
|
||||
{
|
||||
if (cmp_ofs < 2)
|
||||
return 0; // Out of bounds.
|
||||
|
||||
cmp_ofs -= 2;
|
||||
u16 seg_val = ((unsigned int)(cmp_start[cmp_ofs + 1]) << 8) | cmp_start[cmp_ofs];
|
||||
u32 seg_size = ((seg_val >> 12) & 0xF) + 3;
|
||||
u32 seg_ofs = (seg_val & 0x0FFF) + 3;
|
||||
if (out_ofs < seg_size) // Kernel restricts segment copy to stay in bounds.
|
||||
seg_size = out_ofs;
|
||||
|
||||
out_ofs -= seg_size;
|
||||
|
||||
for (unsigned int j = 0; j < seg_size; j++)
|
||||
cmp_start[out_ofs + j] = cmp_start[out_ofs + j + seg_ofs];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy directly.
|
||||
if (cmp_ofs < 1)
|
||||
return 0; //out of bounds
|
||||
|
||||
cmp_start[--out_ofs] = cmp_start[--cmp_ofs];
|
||||
}
|
||||
control <<= 1;
|
||||
if (out_ofs == 0) // Blz works backwards, so if it reaches byte 0, it's done.
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int blz_uncompress_srcdest(const unsigned char *compData, unsigned int compDataLen, unsigned char *dstData, unsigned int dstSize)
|
||||
{
|
||||
blz_footer footer;
|
||||
const blz_footer *compFooterPtr = blz_get_footer(compData, compDataLen, &footer);
|
||||
if (compFooterPtr == NULL)
|
||||
return 0;
|
||||
|
||||
// Decompression must be done in-place, so need to copy the relevant compressed data first.
|
||||
unsigned int numCompBytes = (const unsigned char*)(compFooterPtr)-compData;
|
||||
memcpy(dstData, compData, numCompBytes);
|
||||
memset(&dstData[numCompBytes], 0, dstSize - numCompBytes);
|
||||
|
||||
return blz_uncompress_inplace(dstData, compDataLen, &footer);
|
||||
}
|
36
bdk/libs/compr/blz.h
Normal file
36
bdk/libs/compr/blz.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2018 rajkosto
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _BLZ_H_
|
||||
#define _BLZ_H_
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
typedef struct _blz_footer
|
||||
{
|
||||
u32 cmp_and_hdr_size;
|
||||
u32 header_size;
|
||||
u32 addl_size;
|
||||
} blz_footer;
|
||||
|
||||
// Returns pointer to footer in compData if present, additionally copies it to outFooter if not NULL.
|
||||
const blz_footer *blz_get_footer(const unsigned char *compData, unsigned int compDataLen, blz_footer *outFooter);
|
||||
// Returns 0 on failure.
|
||||
int blz_uncompress_inplace(unsigned char *dataBuf, unsigned int compSize, const blz_footer *footer);
|
||||
// Returns 0 on failure.
|
||||
int blz_uncompress_srcdest(const unsigned char *compData, unsigned int compDataLen, unsigned char *dstData, unsigned int dstSize);
|
||||
|
||||
#endif
|
179
bdk/libs/compr/lz.c
Normal file
179
bdk/libs/compr/lz.c
Normal file
|
@ -0,0 +1,179 @@
|
|||
/*************************************************************************
|
||||
* Name: lz.c
|
||||
* Author: Marcus Geelnard
|
||||
* Description: LZ77 coder/decoder implementation.
|
||||
* Reentrant: Yes
|
||||
*
|
||||
* The LZ77 compression scheme is a substitutional compression scheme
|
||||
* proposed by Abraham Lempel and Jakob Ziv in 1977. It is very simple in
|
||||
* its design, and uses no fancy bit level compression.
|
||||
*
|
||||
* This is my first attempt at an implementation of a LZ77 code/decoder.
|
||||
*
|
||||
* The principle of the LZ77 compression algorithm is to store repeated
|
||||
* occurrences of strings as references to previous occurrences of the same
|
||||
* string. The point is that the reference consumes less space than the
|
||||
* string itself, provided that the string is long enough (in this
|
||||
* implementation, the string has to be at least 4 bytes long, since the
|
||||
* minimum coded reference is 3 bytes long). Also note that the term
|
||||
* "string" refers to any kind of byte sequence (it does not have to be
|
||||
* an ASCII string, for instance).
|
||||
*
|
||||
* The coder uses a brute force approach to finding string matches in the
|
||||
* history buffer (or "sliding window", if you wish), which is very, very
|
||||
* slow. I recon the complexity is somewhere between O(n^2) and O(n^3),
|
||||
* depending on the input data.
|
||||
*
|
||||
* There is also a faster implementation that uses a large working buffer
|
||||
* in which a "jump table" is stored, which is used to quickly find
|
||||
* possible string matches (see the source code for LZ_CompressFast() for
|
||||
* more information). The faster method is an order of magnitude faster,
|
||||
* but still quite slow compared to other compression methods.
|
||||
*
|
||||
* The upside is that decompression is very fast, and the compression ratio
|
||||
* is often very good.
|
||||
*
|
||||
* The reference to a string is coded as a (length,offset) pair, where the
|
||||
* length indicates the length of the string, and the offset gives the
|
||||
* offset from the current data position. To distinguish between string
|
||||
* references and literal strings (uncompressed bytes), a string reference
|
||||
* is preceded by a marker byte, which is chosen as the least common byte
|
||||
* symbol in the input data stream (this marker byte is stored in the
|
||||
* output stream as the first byte).
|
||||
*
|
||||
* Occurrences of the marker byte in the stream are encoded as the marker
|
||||
* byte followed by a zero byte, which means that occurrences of the marker
|
||||
* byte have to be coded with two bytes.
|
||||
*
|
||||
* The lengths and offsets are coded in a variable length fashion, allowing
|
||||
* values of any magnitude (up to 4294967295 in this implementation).
|
||||
*
|
||||
* With this compression scheme, the worst case compression result is
|
||||
* (257/256)*insize + 1.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
* Copyright (c) 2003-2006 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.
|
||||
*
|
||||
* Marcus Geelnard
|
||||
* marcus.geelnard at home.se
|
||||
*************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* INTERNAL FUNCTIONS *
|
||||
*************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* _LZ_ReadVarSize() - Read unsigned integer with variable number of
|
||||
* bytes depending on value.
|
||||
*************************************************************************/
|
||||
|
||||
static int _LZ_ReadVarSize( unsigned int * x, const unsigned char * buf )
|
||||
{
|
||||
unsigned int y, b, num_bytes;
|
||||
|
||||
/* Read complete value (stop when byte contains zero in 8:th bit) */
|
||||
y = 0;
|
||||
num_bytes = 0;
|
||||
do
|
||||
{
|
||||
b = (unsigned int) (*buf ++);
|
||||
y = (y << 7) | (b & 0x0000007f);
|
||||
++ num_bytes;
|
||||
}
|
||||
while( b & 0x00000080 );
|
||||
|
||||
/* Store value in x */
|
||||
*x = y;
|
||||
|
||||
/* Return number of bytes read */
|
||||
return num_bytes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* PUBLIC FUNCTIONS *
|
||||
*************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* LZ_Uncompress() - Uncompress a block of data using an LZ77 decoder.
|
||||
* in - Input (compressed) buffer.
|
||||
* out - Output (uncompressed) buffer. This buffer must be large
|
||||
* enough to hold the uncompressed data.
|
||||
* insize - Number of input bytes.
|
||||
*************************************************************************/
|
||||
|
||||
void LZ_Uncompress( const unsigned char *in, unsigned char *out,
|
||||
unsigned int insize )
|
||||
{
|
||||
unsigned char marker, symbol;
|
||||
unsigned int i, inpos, outpos, length, offset;
|
||||
|
||||
/* Do we have anything to uncompress? */
|
||||
if( insize < 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get marker symbol from input stream */
|
||||
marker = in[ 0 ];
|
||||
inpos = 1;
|
||||
|
||||
/* Main decompression loop */
|
||||
outpos = 0;
|
||||
do
|
||||
{
|
||||
symbol = in[ inpos ++ ];
|
||||
if( symbol == marker )
|
||||
{
|
||||
/* We had a marker byte */
|
||||
if( in[ inpos ] == 0 )
|
||||
{
|
||||
/* It was a single occurrence of the marker byte */
|
||||
out[ outpos ++ ] = marker;
|
||||
++ inpos;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Extract true length and offset */
|
||||
inpos += _LZ_ReadVarSize( &length, &in[ inpos ] );
|
||||
inpos += _LZ_ReadVarSize( &offset, &in[ inpos ] );
|
||||
|
||||
/* Copy corresponding data from history window */
|
||||
for( i = 0; i < length; ++ i )
|
||||
{
|
||||
out[ outpos ] = out[ outpos - offset ];
|
||||
++ outpos;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No marker, plain copy */
|
||||
out[ outpos ++ ] = symbol;
|
||||
}
|
||||
}
|
||||
while( inpos < insize );
|
||||
}
|
52
bdk/libs/compr/lz.h
Normal file
52
bdk/libs/compr/lz.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*************************************************************************
|
||||
* Name: lz.h
|
||||
* Author: Marcus Geelnard
|
||||
* Description: LZ77 coder/decoder interface.
|
||||
* Reentrant: Yes
|
||||
*-------------------------------------------------------------------------
|
||||
* Copyright (c) 2003-2006 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.
|
||||
*
|
||||
* Marcus Geelnard
|
||||
* marcus.geelnard at home.se
|
||||
*************************************************************************/
|
||||
|
||||
#ifndef _lz_h_
|
||||
#define _lz_h_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* Function prototypes
|
||||
*************************************************************************/
|
||||
|
||||
void LZ_Uncompress( const unsigned char *in, unsigned char *out,
|
||||
unsigned int insize );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _lz_h_ */
|
Loading…
Add table
Add a link
Reference in a new issue