Permalink
Browse files

Merge pull request #17 from psfree/master

Calypso: Added support for kip decompression
  • Loading branch information...
Reisyukaku committed Jul 27, 2018
2 parents b099883 + b974c75 commit 2bb0b8c904fd0a91e1173f82587caa7fd7e0315a
Showing with 117 additions and 0 deletions.
  1. +115 −0 src/hwinit/util.c
  2. +2 −0 src/hwinit/util.h
View
@@ -14,9 +14,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "heap.h"
#include <string.h>
#include "util.h"
#include "t210.h"
#include "heap.h"
u32 get_tmr_s()
{
@@ -62,3 +64,116 @@ uPtr memsearch(const u8 *startPos, u32 searchSize, const void *pattern, u32 patt
}
return 0;
}
typedef struct lsf_head {
u32 loc;
u32 size;
u32 filesize;
} lsf_head;
char * blz_decompress(unsigned char * compressed, u32 * isize) {
u32 size = *isize;
u32 compressed_size;
u32 init_index;
u32 uncompressed_addl_size;
memcpy(&compressed_size, compressed+size - 0xC, 4);
memcpy(&init_index, compressed+size - 0x8, 4);
memcpy(&uncompressed_addl_size, compressed+size - 0x4, 4);
u32 decompressed_size = size + uncompressed_addl_size;
unsigned char * decomp = malloc(decompressed_size);
memcpy(decomp, compressed, size);
for(int i=size; i<decompressed_size; i++)
decomp[i]=0x0;
u32 index = compressed_size - init_index;
u32 outindex = decompressed_size;
while(outindex > 0) {
index -= 1;
unsigned char control;
memcpy(&control, compressed+index,1);
for(int i=0; i<8; i++) {
if(control & 0x80) {
if(index < 2) {
//printf("ERROR: Compression out of bounds\n");
return NULL;
}
index -= 2;
unsigned short int segmentoffset = compressed[index] | (compressed[index+1] <<8);
u32 segmentsize = ((segmentoffset >> 12) & 0xF) + 3;
segmentoffset &= 0x0FFF;
segmentoffset +=2;
if(outindex < segmentsize) {
//printf("ERROR: Compression out of bounds, outindex<segsize\n");
return NULL;
}
for(int j=0; j<segmentsize; j++) {
if(outindex +segmentoffset >= decompressed_size) {
//printf("ERROR: Compression out of bounds, 3\n");
return NULL;
}
char data = decomp[outindex+segmentoffset];
outindex -= 1;
decomp[outindex] = data;
}
}
else{
if(outindex < 1){
//printf("ERROR: compression out of bounds, 4 \n");
return NULL;
}
outindex -= 1;
index -= 1;
decomp[outindex] = compressed[index];
}
control <<= 1;
control &= 0xFF;
if(!outindex)
break;
}
}
*isize = decompressed_size;
return decomp;
}
char * kipread(char * bytes, int * sz) {
char magic[5];
memcpy(magic, bytes, 4);
magic[4]=0;
if(strcmp(magic, "KIP1")) {
//printf("KIP1 magic is missing, abort\n");
return NULL;
}
lsf_head text_h;
lsf_head ro_h;
lsf_head data_h;
memcpy(&text_h, bytes+0x20, 12);
memcpy(&ro_h, bytes+0x30, 12);
memcpy(&data_h, bytes+0x40, 12);
u32 toff = 0x100;
u32 roff = toff + text_h.filesize;
u32 doff = roff + ro_h.filesize;
u32 bsssize;
memcpy(&bsssize, bytes+0x18, 4);
char * text = malloc(text_h.filesize+1);
memcpy(text, bytes+toff, text_h.filesize);
char * ro = malloc(ro_h.filesize+1);
memcpy(ro, bytes+roff, ro_h.filesize);
char * data = malloc(data_h.filesize+1);
memcpy(data, bytes+doff, data_h.filesize);
text = blz_decompress(text, &text_h.filesize);
ro=blz_decompress(ro, &ro_h.filesize);
data=blz_decompress(data, &data_h.filesize);
u32 totalsize = text_h.filesize+ro_h.filesize+data_h.filesize;
char * out = malloc(totalsize+1);
memcpy(out, text, text_h.filesize);
memcpy(out+text_h.filesize, ro, ro_h.filesize);
memcpy(out+text_h.filesize+ro_h.filesize,data, data_h.filesize);
*sz = totalsize;
return out;
}
View
@@ -32,5 +32,7 @@ void musleep(u32 milliseconds);
void usleep(u32 microseconds);
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
uPtr memsearch(const u8 *startPos, u32 searchSize, const void *pattern, u32 patternSize);
char * blz_decompress(unsigned char * compressed, u32 * isize);
char * kipread(char * bytes, int * sz);
#endif

0 comments on commit 2bb0b8c

Please sign in to comment.