Add example which uses the frame api through the library
This commit is contained in:
parent
baf78e7e4d
commit
386d216cdf
1
Makefile
1
Makefile
@ -118,6 +118,7 @@ versionstest: clean
|
||||
@cd test; $(MAKE)
|
||||
|
||||
streaming-examples:
|
||||
cd lib; $(MAKE) -e
|
||||
cd examples; $(MAKE) -e test
|
||||
|
||||
prg-travis:
|
||||
|
@ -47,7 +47,7 @@ endif
|
||||
|
||||
default: all
|
||||
|
||||
all: printVersion doubleBuffer ringBuffer ringBufferHC lineCompress
|
||||
all: printVersion doubleBuffer ringBuffer ringBufferHC lineCompress frameCompress
|
||||
|
||||
printVersion: $(LZ4DIR)/lz4.c printVersion.c
|
||||
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
||||
@ -64,15 +64,20 @@ ringBufferHC: $(LZ4DIR)/lz4.c $(LZ4DIR)/lz4hc.c HCStreaming_ringBuffer.c
|
||||
lineCompress: $(LZ4DIR)/lz4.c blockStreaming_lineByLine.c
|
||||
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
||||
|
||||
frameCompress: frameCompress.c
|
||||
$(CC) $(FLAGS) $^ -o $@$(EXT) -L$(LZ4DIR) -llz4
|
||||
|
||||
test : all
|
||||
./printVersion$(EXT)
|
||||
./doubleBuffer$(EXT) $(TESTFILE)
|
||||
./ringBuffer$(EXT) $(TESTFILE)
|
||||
./ringBufferHC$(EXT) $(TESTFILE)
|
||||
./lineCompress$(EXT) $(TESTFILE)
|
||||
LD_LIBRARY_PATH=$(LZ4DIR) ./frameCompress$(EXT) $(TESTFILE)
|
||||
|
||||
clean:
|
||||
@rm -f core *.o *.dec *-0 *-9 *-8192 *.lz4s \
|
||||
printVersion$(EXT) doubleBuffer$(EXT) ringBuffer$(EXT) ringBufferHC$(EXT) lineCompress$(EXT)
|
||||
printVersion$(EXT) doubleBuffer$(EXT) ringBuffer$(EXT) ringBufferHC$(EXT) \
|
||||
lineCompress$(EXT) frameCompress$(EXT)
|
||||
@echo Cleaning completed
|
||||
|
||||
|
165
examples/frameCompress.c
Normal file
165
examples/frameCompress.c
Normal file
@ -0,0 +1,165 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <lz4frame.h>
|
||||
|
||||
#define BUF_SIZE (16*1024)
|
||||
#define LZ4_HEADER_SIZE 19
|
||||
#define LZ4_FOOTER_SIZE 4
|
||||
|
||||
static const LZ4F_preferences_t lz4_preferences = {
|
||||
{ 5, 0, 0, 0, 0, { 0, 0 } },
|
||||
0,
|
||||
0,
|
||||
{ 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
static int compress_file(FILE *in, FILE *out, size_t *size_in, size_t *size_out) {
|
||||
LZ4F_errorCode_t r;
|
||||
LZ4F_compressionContext_t ctx;
|
||||
char *src, *buf = NULL;
|
||||
size_t size, n, k, count_in = 0, count_out, offset = 0, frame_size;
|
||||
|
||||
r = LZ4F_createCompressionContext(&ctx, LZ4F_VERSION);
|
||||
if (LZ4F_isError(r)) {
|
||||
printf("Failed to create context: error %zu", r);
|
||||
return 1;
|
||||
}
|
||||
r = 1;
|
||||
|
||||
src = malloc(BUF_SIZE);
|
||||
if (!src) {
|
||||
printf("Not enough memory");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
frame_size = LZ4F_compressBound(BUF_SIZE, &lz4_preferences);
|
||||
size = frame_size + LZ4_HEADER_SIZE + LZ4_FOOTER_SIZE;
|
||||
buf = malloc(size);
|
||||
if (!buf) {
|
||||
printf("Not enough memory");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
n = offset = count_out = LZ4F_compressBegin(ctx, buf, size, &lz4_preferences);
|
||||
if (LZ4F_isError(n)) {
|
||||
printf("Failed to start compression: error %zu", n);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
printf("Buffer size is %zu bytes, header size %zu bytes\n", size, n);
|
||||
|
||||
for (;;) {
|
||||
k = fread(src, 1, BUF_SIZE, in);
|
||||
if (k == 0)
|
||||
break;
|
||||
count_in += k;
|
||||
|
||||
n = LZ4F_compressUpdate(ctx, buf + offset, size - offset, src, k, NULL);
|
||||
if (LZ4F_isError(n)) {
|
||||
printf("Compression failed: error %zu", n);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
offset += n;
|
||||
count_out += n;
|
||||
if (size - offset < frame_size + LZ4_FOOTER_SIZE) {
|
||||
printf("Writing %zu bytes\n", offset);
|
||||
|
||||
k = fwrite(buf, 1, offset, out);
|
||||
if (k < offset) {
|
||||
if (ferror(out))
|
||||
printf("Write failed");
|
||||
else
|
||||
printf("Short write");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
n = LZ4F_compressEnd(ctx, buf + offset, size - offset, NULL);
|
||||
if (LZ4F_isError(n)) {
|
||||
printf("Failed to end compression: error %zu", n);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
offset += n;
|
||||
count_out += n;
|
||||
printf("Writing %zu bytes\n", offset);
|
||||
|
||||
k = fwrite(buf, 1, offset, out);
|
||||
if (k < offset) {
|
||||
if (ferror(out))
|
||||
printf("Write failed");
|
||||
else
|
||||
printf("Short write");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
*size_in = count_in;
|
||||
*size_out = count_out;
|
||||
r = 0;
|
||||
cleanup:
|
||||
if (ctx)
|
||||
LZ4F_freeCompressionContext(ctx);
|
||||
free(src);
|
||||
free(buf);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int compress(const char *input, const char *output) {
|
||||
char *tmp = NULL;
|
||||
FILE *in = NULL, *out = NULL;
|
||||
size_t size_in = 0, size_out = 0;
|
||||
int r = 1;
|
||||
|
||||
if (!output) {
|
||||
size_t len = strlen(input);
|
||||
|
||||
output = tmp = malloc(len + 5);
|
||||
if (!tmp) {
|
||||
printf("Not enough memory");
|
||||
return 1;
|
||||
}
|
||||
strcpy(tmp, input);
|
||||
strcpy(tmp + len, ".lz4");
|
||||
}
|
||||
|
||||
in = fopen(input, "rb");
|
||||
if (!in) {
|
||||
fprintf(stderr, "Failed to open input file %s: %s\n", input, strerror(errno));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
out = fopen(output, "wb");
|
||||
if (!out) {
|
||||
fprintf(stderr, "Failed to open output file %s: %s\n", output, strerror(errno));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
r = compress_file(in, out, &size_in, &size_out);
|
||||
if (r == 0)
|
||||
printf("%s: %zu → %zu bytes, %.1f%%\n",
|
||||
input, size_in, size_out,
|
||||
(double)size_out / size_in * 100);
|
||||
cleanup:
|
||||
if (in)
|
||||
fclose(in);
|
||||
if (out)
|
||||
fclose(out);
|
||||
free(tmp);
|
||||
return r;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 2 || argc > 3) {
|
||||
fprintf(stderr, "Syntax: %s <input> <output>\n", argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return compress(argv[1], argv[2]);
|
||||
}
|
Loading…
Reference in New Issue
Block a user