Home | History | Annotate | Download | only in examples
      1 // LZ4 streaming API example : double buffer
      2 // Copyright : Takayuki Matsuoka
      3 
      4 
      5 #if defined(_MSC_VER) && (_MSC_VER <= 1800)  /* Visual Studio <= 2013 */
      6 #  define _CRT_SECURE_NO_WARNINGS
      7 #  define snprintf sprintf_s
      8 #endif
      9 #include "lz4.h"
     10 
     11 #include <stdio.h>
     12 #include <stdint.h>
     13 #include <stdlib.h>
     14 #include <string.h>
     15 
     16 enum {
     17     BLOCK_BYTES = 1024 * 8,
     18 //  BLOCK_BYTES = 1024 * 64,
     19 };
     20 
     21 
     22 size_t write_int(FILE* fp, int i) {
     23     return fwrite(&i, sizeof(i), 1, fp);
     24 }
     25 
     26 size_t write_bin(FILE* fp, const void* array, size_t arrayBytes) {
     27     return fwrite(array, 1, arrayBytes, fp);
     28 }
     29 
     30 size_t read_int(FILE* fp, int* i) {
     31     return fread(i, sizeof(*i), 1, fp);
     32 }
     33 
     34 size_t read_bin(FILE* fp, void* array, size_t arrayBytes) {
     35     return fread(array, 1, arrayBytes, fp);
     36 }
     37 
     38 
     39 void test_compress(FILE* outFp, FILE* inpFp)
     40 {
     41     LZ4_stream_t lz4Stream_body;
     42     LZ4_stream_t* lz4Stream = &lz4Stream_body;
     43 
     44     char inpBuf[2][BLOCK_BYTES];
     45     int  inpBufIndex = 0;
     46 
     47     LZ4_resetStream(lz4Stream);
     48 
     49     for(;;) {
     50         char* const inpPtr = inpBuf[inpBufIndex];
     51         const int inpBytes = (int) read_bin(inpFp, inpPtr, BLOCK_BYTES);
     52         if(0 == inpBytes) {
     53             break;
     54         }
     55 
     56         {
     57             char cmpBuf[LZ4_COMPRESSBOUND(BLOCK_BYTES)];
     58             const int cmpBytes = LZ4_compress_fast_continue(
     59                 lz4Stream, inpPtr, cmpBuf, inpBytes, sizeof(cmpBuf), 1);
     60             if(cmpBytes <= 0) {
     61                 break;
     62             }
     63             write_int(outFp, cmpBytes);
     64             write_bin(outFp, cmpBuf, (size_t) cmpBytes);
     65         }
     66 
     67         inpBufIndex = (inpBufIndex + 1) % 2;
     68     }
     69 
     70     write_int(outFp, 0);
     71 }
     72 
     73 
     74 void test_decompress(FILE* outFp, FILE* inpFp)
     75 {
     76     LZ4_streamDecode_t lz4StreamDecode_body;
     77     LZ4_streamDecode_t* lz4StreamDecode = &lz4StreamDecode_body;
     78 
     79     char decBuf[2][BLOCK_BYTES];
     80     int  decBufIndex = 0;
     81 
     82     LZ4_setStreamDecode(lz4StreamDecode, NULL, 0);
     83 
     84     for(;;) {
     85         char cmpBuf[LZ4_COMPRESSBOUND(BLOCK_BYTES)];
     86         int  cmpBytes = 0;
     87 
     88         {
     89             const size_t readCount0 = read_int(inpFp, &cmpBytes);
     90             if(readCount0 != 1 || cmpBytes <= 0) {
     91                 break;
     92             }
     93 
     94             const size_t readCount1 = read_bin(inpFp, cmpBuf, (size_t) cmpBytes);
     95             if(readCount1 != (size_t) cmpBytes) {
     96                 break;
     97             }
     98         }
     99 
    100         {
    101             char* const decPtr = decBuf[decBufIndex];
    102             const int decBytes = LZ4_decompress_safe_continue(
    103                 lz4StreamDecode, cmpBuf, decPtr, cmpBytes, BLOCK_BYTES);
    104             if(decBytes <= 0) {
    105                 break;
    106             }
    107             write_bin(outFp, decPtr, (size_t) decBytes);
    108         }
    109 
    110         decBufIndex = (decBufIndex + 1) % 2;
    111     }
    112 }
    113 
    114 
    115 int compare(FILE* fp0, FILE* fp1)
    116 {
    117     int result = 0;
    118 
    119     while(0 == result) {
    120         char b0[65536];
    121         char b1[65536];
    122         const size_t r0 = read_bin(fp0, b0, sizeof(b0));
    123         const size_t r1 = read_bin(fp1, b1, sizeof(b1));
    124 
    125         result = (int) r0 - (int) r1;
    126 
    127         if(0 == r0 || 0 == r1) {
    128             break;
    129         }
    130         if(0 == result) {
    131             result = memcmp(b0, b1, r0);
    132         }
    133     }
    134 
    135     return result;
    136 }
    137 
    138 
    139 int main(int argc, char* argv[])
    140 {
    141     char inpFilename[256] = { 0 };
    142     char lz4Filename[256] = { 0 };
    143     char decFilename[256] = { 0 };
    144 
    145     if(argc < 2) {
    146         printf("Please specify input filename\n");
    147         return 0;
    148     }
    149 
    150     snprintf(inpFilename, 256, "%s", argv[1]);
    151     snprintf(lz4Filename, 256, "%s.lz4s-%d", argv[1], BLOCK_BYTES);
    152     snprintf(decFilename, 256, "%s.lz4s-%d.dec", argv[1], BLOCK_BYTES);
    153 
    154     printf("inp = [%s]\n", inpFilename);
    155     printf("lz4 = [%s]\n", lz4Filename);
    156     printf("dec = [%s]\n", decFilename);
    157 
    158     // compress
    159     {
    160         FILE* inpFp = fopen(inpFilename, "rb");
    161         FILE* outFp = fopen(lz4Filename, "wb");
    162 
    163         printf("compress : %s -> %s\n", inpFilename, lz4Filename);
    164         test_compress(outFp, inpFp);
    165         printf("compress : done\n");
    166 
    167         fclose(outFp);
    168         fclose(inpFp);
    169     }
    170 
    171     // decompress
    172     {
    173         FILE* inpFp = fopen(lz4Filename, "rb");
    174         FILE* outFp = fopen(decFilename, "wb");
    175 
    176         printf("decompress : %s -> %s\n", lz4Filename, decFilename);
    177         test_decompress(outFp, inpFp);
    178         printf("decompress : done\n");
    179 
    180         fclose(outFp);
    181         fclose(inpFp);
    182     }
    183 
    184     // verify
    185     {
    186         FILE* inpFp = fopen(inpFilename, "rb");
    187         FILE* decFp = fopen(decFilename, "rb");
    188 
    189         printf("verify : %s <-> %s\n", inpFilename, decFilename);
    190         const int cmp = compare(inpFp, decFp);
    191         if(0 == cmp) {
    192             printf("verify : OK\n");
    193         } else {
    194             printf("verify : NG\n");
    195         }
    196 
    197         fclose(decFp);
    198         fclose(inpFp);
    199     }
    200 
    201     return 0;
    202 }
    203