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