dsi/exploits/minitwlpayload/source/exodecr.c
fincs 5d2fe1ab9f Major minitwlpayload cleanup:
- Use nds-bootloader submodule (latest official devkitPro code)
- Consequence of above: FAT12/FAT16 support restored
- Now compressing bootloader with exomizer (grab from here:)
  https://bitbucket.org/magli143/exomizer/wiki/browse/downloads
- Miscellaneous code cleanup & stability fixes
2017-09-07 20:39:30 +02:00

140 lines
3.2 KiB
C

/*
* Copyright (c) 2005 Magnus Lind.
*
* 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 distribution.
*
* 4. The names of this software and/or it's copyright holders may not be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*/
#include "exodecr.h"
static unsigned short int base[52];
static char bits[52];
static unsigned short int bit_buffer;
static unsigned short int
read_bits(const char **inp, int bit_count)
{
unsigned short int bits = 0;
while(bit_count-- > 0)
{
if(bit_buffer == 1)
{
bit_buffer = 0x100 | (*--(*inp) & 0xff);
}
bits <<= 1;
bits |= bit_buffer & 0x1;
bit_buffer >>= 1;
}
return bits;
}
static void
init_table(const char **inp)
{
int i;
unsigned short int b2 = 0;
for(i = 0; i < 52; ++i)
{
unsigned short int b1;
if((i & 15) == 0)
{
b2 = 1;
}
base[i] = b2;
b1 = read_bits(inp, 4);
bits[i] = b1;
b2 += 1 << b1;
}
}
char *
exo_decrunch(const char *in, char *out)
{
unsigned short int index;
unsigned short int length;
unsigned short int offset;
char c;
char literal;
bit_buffer = *--in;
init_table(&in);
for(;;)
{
literal = read_bits(&in, 1);
if(literal == 1)
{
/* literal byte */
length = 1;
goto copy;
}
index = 0;
while(read_bits(&in, 1) == 0)
{
++index;
}
if(index == 16)
{
break;
}
if(index == 17)
{
literal = 1;
length = read_bits(&in, 16);
goto copy;
}
length = base[index] + read_bits(&in, bits[index]);
switch(length)
{
case 1:
index = 48 + read_bits(&in, 2);
break;
case 2:
index = 32 + read_bits(&in, 4);
break;
default:
index = 16 + read_bits(&in, 4);
break;
}
offset = base[index] + read_bits(&in, bits[index]);
copy:
do
{
--out;
if(literal)
{
c = *--in;
}
else
{
c = out[offset];
}
*out = c;
}
while(--length > 0);
}
return out;
}