//Based on https://github.com/richgel999/miniz/blob/master/examples/example5.c (Public domain, April 11 2012, Rich Geldreich, richgel99@gmail.com) #include #include //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 char* comprBuffer; char* uncomprBuffer; //Position of the inflater in the buffer arrays char* comprBufferNext; 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; comprBufferNext = (const mz_uint8 *)comprBuffer; } //output buffer has been emptied spaceInOutput = uncomprBufferSize; uncomprBufferNext = (mz_uint8 *)uncomprBuffer; struct InflateOutput out; out.hasReachedEnd = false; 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 comprBufferNext = (const mz_uint8 *)comprBufferNext + in_bytes; remainingInput -= in_bytes; uncomprBufferNext = (mz_uint8 *)uncomprBufferNext + out_bytes; spaceInOutput -= out_bytes; //Check for errors if (status <= TINFL_STATUS_DONE) { if (status == TINFL_STATUS_DONE) { // Decompression completed successfully. out.hasReachedEnd = true; 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 if (spaceInOutput == 0) { break; } } //Return output if (remainingInput == 0) { out.needMoreInput = hasMoreBytes; } out.numBytesWrittenToOutput = uncomprBufferSize - spaceInOutput; return out; }