Add example which uses the frame api through the library
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 21 May 2015 13:17:21 +0000 (09:17 -0400)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 18 Jun 2015 03:45:15 +0000 (23:45 -0400)
Makefile
examples/Makefile
examples/frameCompress.c [new file with mode: 0644]

index ac48b65..ce5e9fc 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -118,6 +118,7 @@ versionstest: clean
        @cd test; $(MAKE)
 
 streaming-examples:
+       cd lib; $(MAKE) -e
        cd examples; $(MAKE) -e test
 
 prg-travis:
index 808b511..5d8bb0f 100644 (file)
@@ -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
 
diff --git a/examples/frameCompress.c b/examples/frameCompress.c
new file mode 100644 (file)
index 0000000..7b13579
--- /dev/null
@@ -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]);
+}