Skip to content

Instantly share code, notes, and snippets.

@t-mat
Last active August 29, 2015 14:05
Show Gist options
  • Save t-mat/8ef7accc04d5cd587bc2 to your computer and use it in GitHub Desktop.
Save t-mat/8ef7accc04d5cd587bc2 to your computer and use it in GitHub Desktop.
lz4-framing-api-memory-to-memory-compression.c
#include <stdio.h>
#include "lz4frame.h"
// Upper bound of total output frame size
size_t LZ4F_compressFrameBound(size_t srcSize, const LZ4F_preferences_t* preferences);
size_t compress(
LZ4F_compressionContext_t* ctx,
char* outPtr, size_t outSizeMax, const char* inpPtr, size_t inpSize,
const LZ4F_compressOptions_t* options, const LZ4F_preferences_t* preferences
{
char* const outTop = outPtr;
char* const outEnd = outPtr + outSizeMax;
const char* const inpEnd = inpPtr + inpSize;
const size_t srcBlockSize = LZ4F_getMaxSrcSize(0, &preferences);
if(LZ4F_isError(srcBlockSize)) {
return srcBlockSize;
}
// Maybe LZ4F_compressBegin()'s compressOptions seems to have overlooked.
const size_t headerSize = LZ4F_compressBegin(ctx, outPtr, outEnd - outPtr, options);
if(LZ4_isError(headerSize)) {
return headerSize;
}
outPtr += headerSize;
for(;;) {
size_t readSize = inpEnd - inpPtr;
if(readSize == 0) {
break;
}
if(readSize > srcBlockSize) {
readSize = srcBlockSize;
}
const size_t cmpSize = LZ4F_compress(ctx, outPtr, outEnd - outPtr, inpPtr, readSize, options);
if(LZ4F_isError(cmpSize)) {
return cmpSize;
}
outPtr += cmpSize;
inpPtr += readSize;
}
const size_t endSize = LZ4F_compressEnd(ctx, outPtr, outEnd - outPtr, options);
if(LZ4F_isError(endSize)) {
return endSize;
}
outPtr += endSize;
return (size_t) (outPtr - outTop);
}
int main() {
int result = EXIT_FAILURE;
const char* inpFilename = "inp.bin";
const char* outFilename = "out.lz4";
void* inpMem = NULL;
size_t inpSize = 0;
void* outMem = NULL;
size_t outSize = 0;
// read file
{
FILE* inpFp = fopen(inpFilename, "rb");
fseek(inpFp, 0, SEEK_END);
inpSize = (size_t) ftell(inpFp);
inpMem = malloc(inpSize);
rewind(inpFp);
fread(inpMem, 1, inpSize, inpFp);
fclose(inpFp);
}
LZ4F_preferences_t preferences = { 0 };
preferences.compressionLevel = 9;
preferences.maxBlockSize = max64KB;
preferences.blockMode = blockIndependent;
preferences.contentChecksum = contentChecksumEnabled;
LZ4F_compressOptions_t options = { 0 };
options.autoFlush = FALSE;
options.stableSrc = FALSE;
// outSizeMax : Upper bound of total output frame size
const size_t outSizeMax = LZ4F_compressFrameBound(inpSize, &preferences);
if(! LZ4F_isError(outSizeMax)) {
outMem = malloc(outSizeMax);
LZ4F_compressionContext_t* ctx = LZ4F_createCompressionContext(LZ4F_VERSION, &options, &preferences);
outSize = compress(ctx, outMem, outSizeMax, inpMem, inpSize, &options);
LZ4F_freeCompressionContext(ctx);
}
if(outMem && outSize && ! LZ4F_isError(outSize)) {
FILE* outFp = fopen(outFilename, "wb");
fwrite(outMem, 1, outSize, outFp);
fclose(outFp);
}
free(outMem);
free(inpMem);
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment