mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-17 00:39:17 +01:00
145 lines
3.3 KiB
C
145 lines
3.3 KiB
C
/***************************************************************************
|
|
* Copyright (C) 2010
|
|
* by Dimok
|
|
*
|
|
* 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.
|
|
*
|
|
* for WiiXplorer 2010
|
|
***************************************************************************/
|
|
#include <malloc.h>
|
|
#include <string.h>
|
|
|
|
#include "uncompress.h"
|
|
#include "lz77.h"
|
|
|
|
u8 * uncompressLZ77(const u8 *inBuf, u32 inLength, u32 * size)
|
|
{
|
|
if(!inBuf)
|
|
return NULL;
|
|
|
|
u8 *buffer = NULL;
|
|
if (*((const u32 *)inBuf) != 0x4C5A3737 /*"LZ77"*/)
|
|
return NULL;
|
|
|
|
decompressLZ77content( (u8*)inBuf + 4, inLength - 4, &buffer, size);
|
|
|
|
return buffer;
|
|
}
|
|
|
|
//Thanks to _demo_ for this function
|
|
//src points to the yaz0 source data (to the "real" source data, not at the header!)
|
|
//dst points to a buffer uncompressedSize bytes large (you get uncompressedSize from
|
|
//the second 4 bytes in the Yaz0 header).
|
|
void uncompressYaz0(const u8* srcBuf, u8* dst, int uncompressedSize)
|
|
{
|
|
if(!srcBuf || !dst)
|
|
return;
|
|
|
|
const u8 * src = srcBuf;
|
|
|
|
if(*((u32*)src) == 'Yaz0')
|
|
{
|
|
src += sizeof(Yaz0_Header);
|
|
}
|
|
|
|
int srcPlace = 0, dstPlace = 0; //current read/write positions
|
|
|
|
u32 validBitCount = 0; //number of valid bits left in "code" byte
|
|
u8 currCodeByte = 0;
|
|
|
|
while(dstPlace < uncompressedSize)
|
|
{
|
|
//read new "code" byte if the current one is used up
|
|
if(validBitCount == 0)
|
|
{
|
|
currCodeByte = src[srcPlace];
|
|
++srcPlace;
|
|
validBitCount = 8;
|
|
}
|
|
|
|
if((currCodeByte & 0x80) != 0)
|
|
{
|
|
//straight copy
|
|
dst[dstPlace] = src[srcPlace];
|
|
dstPlace++;
|
|
srcPlace++;
|
|
}
|
|
else
|
|
{
|
|
//RLE part
|
|
u8 byte1 = src[srcPlace];
|
|
u8 byte2 = src[srcPlace + 1];
|
|
srcPlace += 2;
|
|
|
|
u32 dist = ((byte1 & 0xF) << 8) | byte2;
|
|
u32 copySource = dstPlace - (dist + 1);
|
|
|
|
u32 numBytes = byte1 >> 4;
|
|
if(numBytes == 0)
|
|
{
|
|
numBytes = src[srcPlace] + 0x12;
|
|
srcPlace++;
|
|
}
|
|
else
|
|
numBytes += 2;
|
|
|
|
//copy run
|
|
u32 i = 0;
|
|
for(i = 0; i < numBytes; ++i)
|
|
{
|
|
dst[dstPlace] = dst[copySource];
|
|
copySource++;
|
|
dstPlace++;
|
|
}
|
|
}
|
|
|
|
//use next bit from "code" byte
|
|
currCodeByte <<= 1;
|
|
validBitCount-=1;
|
|
}
|
|
}
|
|
|
|
|
|
u32 CheckIMD5Type(const u8 * buffer, int length)
|
|
{
|
|
if(*((u32 *) buffer) != 'IMD5')
|
|
{
|
|
return *((u32 *) buffer);
|
|
}
|
|
|
|
const u8 * file = buffer+32;
|
|
|
|
if(*((u32 *) file) != 'LZ77')
|
|
{
|
|
return *((u32 *) file);
|
|
}
|
|
|
|
u32 uncSize = 0;
|
|
u8 * uncompressed_data = uncompressLZ77(file, length-32, &uncSize);
|
|
if(!uncompressed_data)
|
|
return 0;
|
|
|
|
u32 * magic = (u32 *) uncompressed_data;
|
|
u32 Type = magic[0];
|
|
free(uncompressed_data);
|
|
|
|
return Type;
|
|
}
|