ssn-installer/src/inflate.c

101 lines
2.8 KiB
C
Raw Normal View History

2018-07-31 13:18:18 +02:00
//Based on https://github.com/richgel999/miniz/blob/master/examples/example5.c (Public domain, April 11 2012, Rich Geldreich, richgel99@gmail.com)
#include <stdbool.h>
#include <stdio.h>
//Include miniz, disabling what we don't need
#define MINIZ_NO_STDIO
#define MINIZ_NO_ARCHIVE_APIS
#define MINIZ_NO_TIME
#define MINIZ_NO_ZLIB_APIS
#define MINIZ_NO_MALLOC
#include "../lib/miniz/miniz.h"
#include "inflate.h"
//The compressed and uncompressed buffer arrays
2018-07-31 14:01:33 +02:00
const char* comprBuffer;
2018-07-31 13:18:18 +02:00
char* uncomprBuffer;
//Position of the inflater in the buffer arrays
2018-07-31 14:01:33 +02:00
const char* comprBufferNext;
2018-07-31 13:18:18 +02:00
char* uncomprBufferNext;
//Buffer lengths
unsigned long uncomprBufferSize;
unsigned long remainingInput;
unsigned long spaceInOutput;
//Internal variables used by miniz
tinfl_decompressor inflator;
tdefl_status status;
size_t in_bytes, out_bytes;
void inflateInit(char* comprBufferIn, char* uncomprBufferIn, unsigned long uncomprBufferSizeIn) {
comprBuffer = comprBufferIn;
uncomprBuffer = uncomprBufferIn;
uncomprBufferSize = uncomprBufferSizeIn;
tinfl_init(&inflator);
}
struct InflateOutput inflateInflate(unsigned long numInputBytes, bool hasMoreBytes) {
if (numInputBytes == 0) {
//continue in input buffer where we were before
} else {
//go back to beginning of input buffer
remainingInput = numInputBytes;
2018-07-31 13:50:30 +02:00
comprBufferNext = (const mz_uint8 *)comprBuffer;
2018-07-31 13:18:18 +02:00
}
//output buffer has been emptied
spaceInOutput = uncomprBufferSize;
2018-07-31 13:50:30 +02:00
uncomprBufferNext = (mz_uint8 *)uncomprBuffer;
2018-07-31 13:18:18 +02:00
struct InflateOutput out;
out.hasReachedEnd = false;
2018-07-31 13:18:18 +02:00
while (remainingInput > 0 && spaceInOutput > 0) {
in_bytes = remainingInput;
out_bytes = spaceInOutput;
//Call decompression
status = tinfl_decompress(
&inflator,
(const mz_uint8 *)comprBufferNext,
&in_bytes,
uncomprBuffer,
(mz_uint8 *)uncomprBufferNext,
&out_bytes,
(hasMoreBytes ? TINFL_FLAG_HAS_MORE_INPUT : 0)
);
//Adjust buffer positions by the amount of bytes processed
2018-07-31 13:50:30 +02:00
comprBufferNext = (const mz_uint8 *)comprBufferNext + in_bytes;
2018-07-31 13:18:18 +02:00
remainingInput -= in_bytes;
2018-07-31 13:50:30 +02:00
uncomprBufferNext = (mz_uint8 *)uncomprBufferNext + out_bytes;
2018-07-31 13:18:18 +02:00
spaceInOutput -= out_bytes;
//Check for errors
if (status <= TINFL_STATUS_DONE) {
if (status == TINFL_STATUS_DONE) {
// Decompression completed successfully.
out.hasReachedEnd = true;
2018-07-31 13:18:18 +02:00
break;
} else {
// Decompression failed.
fprintf(stderr, "tinfl_decompress() failed with status %i!\n", status);
exit(1);
}
}
//If output buffer is filled, we need to clear it before decompressing more data
2018-07-31 13:18:18 +02:00
if (spaceInOutput == 0) {
break;
}
}
//Return output
if (remainingInput == 0) {
out.needMoreInput = hasMoreBytes;
}
out.numBytesWrittenToOutput = uncomprBufferSize - spaceInOutput;
return out;
}