Port the changes and fixes to the C version.
This commit is contained in:
parent
82f4d5e2f1
commit
a350b7f94e
|
@ -1,3 +1,4 @@
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
@ -33,9 +34,9 @@ data_type getBit(struct Uncompressor* uncompressor)
|
||||||
return bit;
|
return bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
data_type getInterlacedEliasGamma(struct Uncompressor* uncompressor)
|
int getInterlacedEliasGamma(struct Uncompressor* uncompressor)
|
||||||
{
|
{
|
||||||
data_type value = 1;
|
int value = 1;
|
||||||
while (getBit(uncompressor))
|
while (getBit(uncompressor))
|
||||||
{
|
{
|
||||||
value = (value << 1) | getBit(uncompressor);
|
value = (value << 1) | getBit(uncompressor);
|
||||||
|
@ -43,23 +44,41 @@ data_type getInterlacedEliasGamma(struct Uncompressor* uncompressor)
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uncompress(struct Uncompressor* uncompressor, size_t in_data_length)
|
unsigned char * realloc_output(unsigned char * output, size_t output_position, size_t * output_max_size, size_t add_data_size)
|
||||||
{
|
{
|
||||||
unsigned char* output = (unsigned char*) malloc(in_data_length * 3);// * 3 is an arbitrary number...
|
if (output_position + add_data_size > *output_max_size)
|
||||||
|
{
|
||||||
|
*output_max_size *= 2;
|
||||||
|
output = (unsigned char*) realloc(output, *output_max_size);
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uncompress(struct Uncompressor* uncompressor, size_t in_data_length, bool dsk2rom_tweak)
|
||||||
|
{
|
||||||
|
unsigned char* output = (unsigned char*) malloc(in_data_length);// * 10 is an arbitrary number...
|
||||||
|
size_t output_max_size = in_data_length;
|
||||||
size_t output_position = 0;
|
size_t output_position = 0;
|
||||||
|
|
||||||
int q_value = (getBit(uncompressor) << 2 | getBit(uncompressor) << 1 | getBit(uncompressor)) + 1;
|
// The dsk2rom version has a fixed value of 2 for q_value and doesn't read it from the compressed variable stream
|
||||||
|
int q_value = 2;
|
||||||
|
if (!dsk2rom_tweak)
|
||||||
|
{
|
||||||
|
q_value = (getBit(uncompressor) << 2 | getBit(uncompressor) << 1 | getBit(uncompressor)) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
data_type first_byte = getByte(uncompressor);
|
data_type first_byte = getByte(uncompressor);
|
||||||
output[output_position++] = first_byte;
|
output[output_position++] = first_byte;
|
||||||
|
|
||||||
|
uncompressor->dataPosition = dsk2rom_tweak ? 1 : 2;
|
||||||
|
|
||||||
while (uncompressor->dataPosition < in_data_length)
|
while (uncompressor->dataPosition < in_data_length)
|
||||||
{
|
{
|
||||||
if (getBit(uncompressor))
|
if (getBit(uncompressor))
|
||||||
{
|
{
|
||||||
data_type length = getInterlacedEliasGamma(uncompressor) + 1;
|
int length = getInterlacedEliasGamma(uncompressor) + 1;
|
||||||
|
|
||||||
if (length == 255)
|
if (length == 262143 || (dsk2rom_tweak && length == 131072))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -70,6 +89,8 @@ void uncompress(struct Uncompressor* uncompressor, size_t in_data_length)
|
||||||
offset = offset & 0x7F;
|
offset = offset & 0x7F;
|
||||||
switch (q_value)
|
switch (q_value)
|
||||||
{
|
{
|
||||||
|
case 7:
|
||||||
|
offset = offset | (getBit(uncompressor) << 13);
|
||||||
case 6:
|
case 6:
|
||||||
offset = offset | (getBit(uncompressor) << 12);
|
offset = offset | (getBit(uncompressor) << 12);
|
||||||
case 5:
|
case 5:
|
||||||
|
@ -91,22 +112,38 @@ void uncompress(struct Uncompressor* uncompressor, size_t in_data_length)
|
||||||
}
|
}
|
||||||
offset += 1;
|
offset += 1;
|
||||||
|
|
||||||
|
output = realloc_output(output, output_position, &output_max_size, length);
|
||||||
for (int i = 0; i < length; i++)
|
for (int i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
|
// Realloc if necessary
|
||||||
|
if (output_position + 1 > output_max_size)
|
||||||
|
{
|
||||||
|
output_max_size *= 2;
|
||||||
|
output = (unsigned char*) realloc(output, output_max_size);
|
||||||
|
}
|
||||||
|
|
||||||
output[output_position] = output[output_position - offset];
|
output[output_position] = output[output_position - offset];
|
||||||
output_position += 1;
|
output_position += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
output = realloc_output(output, output_position, &output_max_size, 1);
|
||||||
output[output_position++] = getByte(uncompressor);
|
output[output_position++] = getByte(uncompressor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
for (int i = 0; i < output_position; i++)
|
for (int i = 0; i < output_position; i++)
|
||||||
{
|
{
|
||||||
printf("%c", output[i]);
|
printf("%02x ", output[i]);
|
||||||
|
if (++count % 30 == 0)
|
||||||
|
{
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
printf("\n");
|
||||||
|
printf("Output size: %zu\n", output_position);
|
||||||
free(output);
|
free(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +174,7 @@ int main(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Uncompressor uncompressor = {compressedData, 0, 0, 7};
|
struct Uncompressor uncompressor = {compressedData, 0, 0, 7};
|
||||||
uncompress(&uncompressor, length);
|
uncompress(&uncompressor, length, true);
|
||||||
|
|
||||||
free(compressedData);
|
free(compressedData);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
Loading…
Reference in New Issue