Last active
January 7, 2021 23:55
-
-
Save iGlitch/74790206e7e9c774d5ae80cc0e5d24fe to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// LZSS decompressor | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <sys\stat.h> | |
char *decode_lzss_stuff(FILE *fp_i, unsigned int *length_ptr) { | |
unsigned char *outbuffer = NULL; // decoded data | |
// should check for size overflow, but I'm going to be stupid and not do so | |
unsigned int buffersize = 163840; // arbitrary initial size | |
//unsigned char curbyte, controlbyte; | |
unsigned char controlbyte; | |
unsigned int bufferindex = 0; | |
unsigned int i = 0; // used for looping | |
unsigned char tempbuffer[10]; // actually only 2-3 bytes should be needed | |
unsigned int num_bytes_to_copy = 0; | |
unsigned int backwards_offset = 0; | |
unsigned int iter_count = 0; | |
int copy_start_index = 0; | |
unsigned int copy_counter = 0; | |
outbuffer = malloc(buffersize); | |
if(outbuffer == NULL) { | |
printf("Unable to allocate memory.\n"); | |
return NULL; | |
} | |
// copy the first 16 bytes (or 32) | |
for(i = 0; i < 16; i++) { //i < 32 | |
outbuffer[bufferindex] = fgetc(fp_i); | |
bufferindex++; | |
} | |
//check that the next byte is 0x11 | |
if (fgetc(fp_i) != 0x11) { | |
printf("Input file does not appear to be LZSS compressed.\n"); | |
exit(-1); | |
} | |
//skip the next 3 bytes | |
for(i = 0; i < 3; i++) { | |
fgetc(fp_i); | |
} | |
while(!feof(fp_i)) { | |
if(bufferindex > (buffersize-8000)) { // give a big safety margin for fun | |
buffersize *= 2; // increase buffer size | |
outbuffer = realloc(outbuffer, buffersize); | |
if(outbuffer == NULL) { | |
printf("Unable to allocate memory.\n"); | |
return NULL; | |
} | |
} | |
controlbyte = fgetc(fp_i); | |
if(feof(fp_i)) { | |
continue; | |
} | |
//printf("Control byte: 0x%02x\n", controlbyte); | |
//if(bufferindex > 0xC70 && bufferindex < 0xCF0) { | |
/*if(bufferindex > 0xC70) { | |
printf("Control byte: 0x%02x\n", controlbyte); | |
}*/ | |
for(i = 0; i < 8; i++) { | |
if(controlbyte & (0x80 >> i)) { | |
//printf("Encoded data...\n"); | |
// decode encoded data | |
tempbuffer[0] = fgetc(fp_i); | |
tempbuffer[1] = fgetc(fp_i); | |
if((tempbuffer[0] & 0xF0) == 0x10) { | |
tempbuffer[2] = fgetc(fp_i); | |
tempbuffer[3] = fgetc(fp_i); | |
num_bytes_to_copy = (((unsigned int) (tempbuffer[0] & 0x0F)) * 0x1000) + (((unsigned int) tempbuffer[1]) * 0x10) + (tempbuffer[2] >> 4) + 0x111; | |
backwards_offset = (((unsigned int) (tempbuffer[2] & 0x0F)) * 0x100) + tempbuffer[3] + 1; | |
} | |
// if the first nibble is 0, get a third byte | |
else if((tempbuffer[0] & 0xF0) == 0) { | |
tempbuffer[2] = fgetc(fp_i); | |
//printf("0x %02x %02x %02x\n", tempbuffer[0], tempbuffer[1], tempbuffer[2]); | |
//*length_ptr = bufferindex; | |
//return outbuffer; | |
//num_bytes_to_copy = (((unsigned int) tempbuffer[0] >> 4) * 0x100) + tempbuffer[2] + 0x2F; | |
//num_bytes_to_copy = (((unsigned int) tempbuffer[0] >> 4) * 0x100) + tempbuffer[2] + 0x13; | |
num_bytes_to_copy = (((unsigned int) tempbuffer[0]) * 0x10) + (tempbuffer[1] >> 4) + 0x11; | |
backwards_offset = (((unsigned int) (tempbuffer[1] & 0x0F)) * 0x100) + tempbuffer[2] + 1; | |
//backwards_offset = (((unsigned int) (tempbuffer[0] & 0x0F)) * 0x100) + tempbuffer[1]; | |
//printf("0x %02x %02x %02x #B %x\n", tempbuffer[0], tempbuffer[1], tempbuffer[2], num_bytes_to_copy); | |
} | |
else { | |
tempbuffer[2] = 0x00; | |
//printf("0x %02x %02x\n", tempbuffer[0], tempbuffer[1]); | |
num_bytes_to_copy = (tempbuffer[0] >> 4) + 0x01; | |
//num_bytes_to_copy = (tempbuffer[0] >> 4) - 0x00; | |
backwards_offset = (((unsigned int) (tempbuffer[0] & 0x0F)) * 0x100) + tempbuffer[1] + 1; | |
//backwards_offset = (((unsigned int) (tempbuffer[0] & 0x0F)) * 0x100) + tempbuffer[1] - 2; | |
} | |
if(backwards_offset <= 0) { | |
printf("Error: Backwards offset is <= 0, this probably is wrong.\n"); | |
} | |
else { | |
//printf("0x%03x bytes to copy, from an backwards offset of 0x%03x.\n", | |
// num_bytes_to_copy, backwards_offset); | |
copy_start_index = bufferindex - backwards_offset; | |
if(copy_start_index < 0) { | |
printf("Error: Copy start index is < 0, this probably is wrong.\n"); | |
} | |
for(copy_counter = 0; copy_counter < num_bytes_to_copy; copy_counter++) { | |
if(bufferindex > (buffersize - 16)) { | |
printf("Buffer overflow ahoy! Trying to save things! bufferindex = %d\n", bufferindex); | |
break; | |
} | |
else if((copy_start_index + copy_counter) >= bufferindex) { | |
printf("Copying uninitialized data? I think not!\n"); | |
//printf("copy_start_index = %d\n", copy_start_index); | |
//printf("copy_counter = %d\n", copy_counter); | |
//printf("Backwards offset coding bytes: 0x %02x %02x %02x\n", | |
// tempbuffer[0], tempbuffer[1], tempbuffer[2]); | |
//printf("num_bytes_to_copy = %d\n", num_bytes_to_copy); | |
//printf("backwards_offset = %d\n", backwards_offset); | |
//printf("bufferindex = %d\n", bufferindex); | |
//printf("buffersize = %d\n", buffersize); | |
break; | |
} | |
else { | |
outbuffer[bufferindex] = outbuffer[copy_start_index + copy_counter]; | |
bufferindex++; | |
} | |
} // end copy loop | |
//if(bufferindex > 0xC70 && bufferindex < 0xCF0) { | |
/*if(bufferindex > 0xC70) { | |
printf("(end copy loop)\n"); | |
}*/ | |
} // end valid backwards offset | |
} // end encoded data | |
else { | |
outbuffer[bufferindex] = fgetc(fp_i); | |
//if(bufferindex > 0xC70 && bufferindex < 0xCF0) { | |
/*if(bufferindex > 0xC70) { | |
printf("0x%02x (literal)\n", outbuffer[bufferindex]); | |
}*/ | |
bufferindex++; | |
} // end literal data | |
} | |
/*if(iter_count > 40) { | |
break; | |
}*/ | |
iter_count++; | |
} | |
if(length_ptr != NULL) { | |
*length_ptr = bufferindex; | |
} | |
else { | |
printf("Hey, invalid length pointer supplied!\n"); | |
} | |
return outbuffer; | |
} | |
int main(int argc, char *argv[]) { | |
FILE *fp_i, *fp_o; | |
unsigned char curbyte = 0; | |
unsigned int i = 0; | |
unsigned int decoded_length = 0; | |
//int startfound = 0; | |
char *outbuffer = NULL; | |
if(argc != 3) { | |
printf("Usage: delzss input output\n"); | |
exit(-1); | |
} | |
fp_i = fopen(argv[1], "rb"); | |
if(fp_i == NULL) { | |
printf("Error opening input file %s.\n", argv[1]); | |
exit(-1); | |
} | |
fp_o = fopen(argv[2], "wb"); | |
if(fp_o == NULL) { | |
printf("Error opening output file %s.\n", argv[2]); | |
fclose(fp_i); | |
exit(-1); | |
} | |
outbuffer = decode_lzss_stuff(fp_i, &decoded_length); | |
// write the output, dropping the first 3c bytes to get to the start of the JPG data | |
fwrite(outbuffer, 1, decoded_length, fp_o); | |
// TODO: drop data past the end of JPG marker? | |
if(outbuffer != NULL) { | |
free(outbuffer); | |
} | |
fclose(fp_i); | |
fclose(fp_o); | |
chmod(argv[2], 0777); // for some reason umask didn't seem to work for this | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Split stages into header (first 0x10 bytes), data (next 0x4A4 bytes), and JPEG (remainder) | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <sys\stat.h> | |
int main(int argc, char *argv[]) { | |
FILE *fp_i, *fp_o1, *fp_o2, *fp_o3; | |
unsigned int i = 0; | |
if(argc != 5) { | |
printf("Usage: SplitStage input_file output_header output_data output_jpeg\n"); | |
exit(-1); | |
} | |
fp_i = fopen(argv[1], "rb"); | |
if(fp_i == NULL) { | |
printf("Error opening input file %s.\n", argv[1]); | |
exit(-1); | |
} | |
fp_o1 = fopen(argv[2], "wb"); | |
if(fp_o1 == NULL) { | |
printf("Error opening output file %s.\n", argv[2]); | |
fclose(fp_i); | |
exit(-1); | |
} | |
fp_o2 = fopen(argv[3], "wb"); | |
if(fp_o2 == NULL) { | |
printf("Error opening output file %s.\n", argv[3]); | |
fclose(fp_i); | |
fclose(fp_o1); | |
exit(-1); | |
} | |
fp_o3 = fopen(argv[4], "wb"); | |
if(fp_o3 == NULL) { | |
printf("Error opening output file %s.\n", argv[4]); | |
fclose(fp_i); | |
fclose(fp_o1); | |
fclose(fp_o2); | |
exit(-1); | |
} | |
for (i = 0; i < 0x10; i++) { | |
fputc(fgetc(fp_i), fp_o1); | |
} | |
for (i = 0; i < 0x4A4; i++) { | |
fputc(fgetc(fp_i), fp_o2); | |
} | |
while(!feof(fp_i)) { | |
fputc(fgetc(fp_i), fp_o3); | |
} | |
fclose(fp_i); | |
fclose(fp_o1); | |
fclose(fp_o2); | |
fclose(fp_o3); | |
//chmod(argv[2], 0777); // for some reason umask didn't seem to work for this | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment