127b27ec6Sopenharmony_ci/* LZ4file API example : compress a file 227b27ec6Sopenharmony_ci * Modified from an example code by anjiahao 327b27ec6Sopenharmony_ci * 427b27ec6Sopenharmony_ci * This example will demonstrate how 527b27ec6Sopenharmony_ci * to manipulate lz4 compressed files like 627b27ec6Sopenharmony_ci * normal files */ 727b27ec6Sopenharmony_ci 827b27ec6Sopenharmony_ci#include <assert.h> 927b27ec6Sopenharmony_ci#include <stdio.h> 1027b27ec6Sopenharmony_ci#include <stdlib.h> 1127b27ec6Sopenharmony_ci#include <string.h> 1227b27ec6Sopenharmony_ci#include <sys/stat.h> 1327b27ec6Sopenharmony_ci 1427b27ec6Sopenharmony_ci#include <lz4file.h> 1527b27ec6Sopenharmony_ci 1627b27ec6Sopenharmony_ci 1727b27ec6Sopenharmony_ci#define CHUNK_SIZE (16*1024) 1827b27ec6Sopenharmony_ci 1927b27ec6Sopenharmony_cistatic size_t get_file_size(char *filename) 2027b27ec6Sopenharmony_ci{ 2127b27ec6Sopenharmony_ci struct stat statbuf; 2227b27ec6Sopenharmony_ci 2327b27ec6Sopenharmony_ci if (filename == NULL) { 2427b27ec6Sopenharmony_ci return 0; 2527b27ec6Sopenharmony_ci } 2627b27ec6Sopenharmony_ci 2727b27ec6Sopenharmony_ci if(stat(filename,&statbuf)) { 2827b27ec6Sopenharmony_ci return 0; 2927b27ec6Sopenharmony_ci } 3027b27ec6Sopenharmony_ci 3127b27ec6Sopenharmony_ci return statbuf.st_size; 3227b27ec6Sopenharmony_ci} 3327b27ec6Sopenharmony_ci 3427b27ec6Sopenharmony_cistatic int compress_file(FILE* f_in, FILE* f_out) 3527b27ec6Sopenharmony_ci{ 3627b27ec6Sopenharmony_ci assert(f_in != NULL); assert(f_out != NULL); 3727b27ec6Sopenharmony_ci 3827b27ec6Sopenharmony_ci LZ4F_errorCode_t ret = LZ4F_OK_NoError; 3927b27ec6Sopenharmony_ci size_t len; 4027b27ec6Sopenharmony_ci LZ4_writeFile_t* lz4fWrite; 4127b27ec6Sopenharmony_ci void* const buf = malloc(CHUNK_SIZE); 4227b27ec6Sopenharmony_ci if (!buf) { 4327b27ec6Sopenharmony_ci printf("error: memory allocation failed \n"); 4427b27ec6Sopenharmony_ci } 4527b27ec6Sopenharmony_ci 4627b27ec6Sopenharmony_ci /* Of course, you can also use prefsPtr to 4727b27ec6Sopenharmony_ci * set the parameters of the compressed file 4827b27ec6Sopenharmony_ci * NULL is use default 4927b27ec6Sopenharmony_ci */ 5027b27ec6Sopenharmony_ci ret = LZ4F_writeOpen(&lz4fWrite, f_out, NULL); 5127b27ec6Sopenharmony_ci if (LZ4F_isError(ret)) { 5227b27ec6Sopenharmony_ci printf("LZ4F_writeOpen error: %s\n", LZ4F_getErrorName(ret)); 5327b27ec6Sopenharmony_ci free(buf); 5427b27ec6Sopenharmony_ci return 1; 5527b27ec6Sopenharmony_ci } 5627b27ec6Sopenharmony_ci 5727b27ec6Sopenharmony_ci while (1) { 5827b27ec6Sopenharmony_ci len = fread(buf, 1, CHUNK_SIZE, f_in); 5927b27ec6Sopenharmony_ci 6027b27ec6Sopenharmony_ci if (ferror(f_in)) { 6127b27ec6Sopenharmony_ci printf("fread error\n"); 6227b27ec6Sopenharmony_ci goto out; 6327b27ec6Sopenharmony_ci } 6427b27ec6Sopenharmony_ci 6527b27ec6Sopenharmony_ci /* nothing to read */ 6627b27ec6Sopenharmony_ci if (len == 0) { 6727b27ec6Sopenharmony_ci break; 6827b27ec6Sopenharmony_ci } 6927b27ec6Sopenharmony_ci 7027b27ec6Sopenharmony_ci ret = LZ4F_write(lz4fWrite, buf, len); 7127b27ec6Sopenharmony_ci if (LZ4F_isError(ret)) { 7227b27ec6Sopenharmony_ci printf("LZ4F_write: %s\n", LZ4F_getErrorName(ret)); 7327b27ec6Sopenharmony_ci goto out; 7427b27ec6Sopenharmony_ci } 7527b27ec6Sopenharmony_ci } 7627b27ec6Sopenharmony_ci 7727b27ec6Sopenharmony_ciout: 7827b27ec6Sopenharmony_ci free(buf); 7927b27ec6Sopenharmony_ci if (LZ4F_isError(LZ4F_writeClose(lz4fWrite))) { 8027b27ec6Sopenharmony_ci printf("LZ4F_writeClose: %s\n", LZ4F_getErrorName(ret)); 8127b27ec6Sopenharmony_ci return 1; 8227b27ec6Sopenharmony_ci } 8327b27ec6Sopenharmony_ci 8427b27ec6Sopenharmony_ci return 0; 8527b27ec6Sopenharmony_ci} 8627b27ec6Sopenharmony_ci 8727b27ec6Sopenharmony_cistatic int decompress_file(FILE* f_in, FILE* f_out) 8827b27ec6Sopenharmony_ci{ 8927b27ec6Sopenharmony_ci assert(f_in != NULL); assert(f_out != NULL); 9027b27ec6Sopenharmony_ci 9127b27ec6Sopenharmony_ci LZ4F_errorCode_t ret = LZ4F_OK_NoError; 9227b27ec6Sopenharmony_ci LZ4_readFile_t* lz4fRead; 9327b27ec6Sopenharmony_ci void* const buf= malloc(CHUNK_SIZE); 9427b27ec6Sopenharmony_ci if (!buf) { 9527b27ec6Sopenharmony_ci printf("error: memory allocation failed \n"); 9627b27ec6Sopenharmony_ci } 9727b27ec6Sopenharmony_ci 9827b27ec6Sopenharmony_ci ret = LZ4F_readOpen(&lz4fRead, f_in); 9927b27ec6Sopenharmony_ci if (LZ4F_isError(ret)) { 10027b27ec6Sopenharmony_ci printf("LZ4F_readOpen error: %s\n", LZ4F_getErrorName(ret)); 10127b27ec6Sopenharmony_ci free(buf); 10227b27ec6Sopenharmony_ci return 1; 10327b27ec6Sopenharmony_ci } 10427b27ec6Sopenharmony_ci 10527b27ec6Sopenharmony_ci while (1) { 10627b27ec6Sopenharmony_ci ret = LZ4F_read(lz4fRead, buf, CHUNK_SIZE); 10727b27ec6Sopenharmony_ci if (LZ4F_isError(ret)) { 10827b27ec6Sopenharmony_ci printf("LZ4F_read error: %s\n", LZ4F_getErrorName(ret)); 10927b27ec6Sopenharmony_ci goto out; 11027b27ec6Sopenharmony_ci } 11127b27ec6Sopenharmony_ci 11227b27ec6Sopenharmony_ci /* nothing to read */ 11327b27ec6Sopenharmony_ci if (ret == 0) { 11427b27ec6Sopenharmony_ci break; 11527b27ec6Sopenharmony_ci } 11627b27ec6Sopenharmony_ci 11727b27ec6Sopenharmony_ci if(fwrite(buf, 1, ret, f_out) != ret) { 11827b27ec6Sopenharmony_ci printf("write error!\n"); 11927b27ec6Sopenharmony_ci goto out; 12027b27ec6Sopenharmony_ci } 12127b27ec6Sopenharmony_ci } 12227b27ec6Sopenharmony_ci 12327b27ec6Sopenharmony_ciout: 12427b27ec6Sopenharmony_ci free(buf); 12527b27ec6Sopenharmony_ci if (LZ4F_isError(LZ4F_readClose(lz4fRead))) { 12627b27ec6Sopenharmony_ci printf("LZ4F_readClose: %s\n", LZ4F_getErrorName(ret)); 12727b27ec6Sopenharmony_ci return 1; 12827b27ec6Sopenharmony_ci } 12927b27ec6Sopenharmony_ci 13027b27ec6Sopenharmony_ci if (ret) { 13127b27ec6Sopenharmony_ci return 1; 13227b27ec6Sopenharmony_ci } 13327b27ec6Sopenharmony_ci 13427b27ec6Sopenharmony_ci return 0; 13527b27ec6Sopenharmony_ci} 13627b27ec6Sopenharmony_ci 13727b27ec6Sopenharmony_ciint compareFiles(FILE* fp0, FILE* fp1) 13827b27ec6Sopenharmony_ci{ 13927b27ec6Sopenharmony_ci int result = 0; 14027b27ec6Sopenharmony_ci 14127b27ec6Sopenharmony_ci while (result==0) { 14227b27ec6Sopenharmony_ci char b0[1024]; 14327b27ec6Sopenharmony_ci char b1[1024]; 14427b27ec6Sopenharmony_ci size_t const r0 = fread(b0, 1, sizeof(b0), fp0); 14527b27ec6Sopenharmony_ci size_t const r1 = fread(b1, 1, sizeof(b1), fp1); 14627b27ec6Sopenharmony_ci 14727b27ec6Sopenharmony_ci result = (r0 != r1); 14827b27ec6Sopenharmony_ci if (!r0 || !r1) break; 14927b27ec6Sopenharmony_ci if (!result) result = memcmp(b0, b1, r0); 15027b27ec6Sopenharmony_ci } 15127b27ec6Sopenharmony_ci 15227b27ec6Sopenharmony_ci return result; 15327b27ec6Sopenharmony_ci} 15427b27ec6Sopenharmony_ci 15527b27ec6Sopenharmony_ciint main(int argc, const char **argv) { 15627b27ec6Sopenharmony_ci char inpFilename[256] = { 0 }; 15727b27ec6Sopenharmony_ci char lz4Filename[256] = { 0 }; 15827b27ec6Sopenharmony_ci char decFilename[256] = { 0 }; 15927b27ec6Sopenharmony_ci 16027b27ec6Sopenharmony_ci if (argc < 2) { 16127b27ec6Sopenharmony_ci printf("Please specify input filename\n"); 16227b27ec6Sopenharmony_ci return 0; 16327b27ec6Sopenharmony_ci } 16427b27ec6Sopenharmony_ci 16527b27ec6Sopenharmony_ci snprintf(inpFilename, 256, "%s", argv[1]); 16627b27ec6Sopenharmony_ci snprintf(lz4Filename, 256, "%s.lz4", argv[1]); 16727b27ec6Sopenharmony_ci snprintf(decFilename, 256, "%s.lz4.dec", argv[1]); 16827b27ec6Sopenharmony_ci 16927b27ec6Sopenharmony_ci printf("inp = [%s]\n", inpFilename); 17027b27ec6Sopenharmony_ci printf("lz4 = [%s]\n", lz4Filename); 17127b27ec6Sopenharmony_ci printf("dec = [%s]\n", decFilename); 17227b27ec6Sopenharmony_ci 17327b27ec6Sopenharmony_ci /* compress */ 17427b27ec6Sopenharmony_ci { FILE* const inpFp = fopen(inpFilename, "rb"); 17527b27ec6Sopenharmony_ci FILE* const outFp = fopen(lz4Filename, "wb"); 17627b27ec6Sopenharmony_ci printf("compress : %s -> %s\n", inpFilename, lz4Filename); 17727b27ec6Sopenharmony_ci LZ4F_errorCode_t ret = compress_file(inpFp, outFp); 17827b27ec6Sopenharmony_ci fclose(inpFp); 17927b27ec6Sopenharmony_ci fclose(outFp); 18027b27ec6Sopenharmony_ci 18127b27ec6Sopenharmony_ci if (ret) { 18227b27ec6Sopenharmony_ci printf("compression error: %s\n", LZ4F_getErrorName(ret)); 18327b27ec6Sopenharmony_ci return 1; 18427b27ec6Sopenharmony_ci } 18527b27ec6Sopenharmony_ci 18627b27ec6Sopenharmony_ci printf("%s: %zu → %zu bytes, %.1f%%\n", 18727b27ec6Sopenharmony_ci inpFilename, 18827b27ec6Sopenharmony_ci get_file_size(inpFilename), 18927b27ec6Sopenharmony_ci get_file_size(lz4Filename), /* might overflow is size_t is 32 bits and size_{in,out} > 4 GB */ 19027b27ec6Sopenharmony_ci (double)get_file_size(lz4Filename) / get_file_size(inpFilename) * 100); 19127b27ec6Sopenharmony_ci 19227b27ec6Sopenharmony_ci printf("compress : done\n"); 19327b27ec6Sopenharmony_ci } 19427b27ec6Sopenharmony_ci 19527b27ec6Sopenharmony_ci /* decompress */ 19627b27ec6Sopenharmony_ci { 19727b27ec6Sopenharmony_ci FILE* const inpFp = fopen(lz4Filename, "rb"); 19827b27ec6Sopenharmony_ci FILE* const outFp = fopen(decFilename, "wb"); 19927b27ec6Sopenharmony_ci 20027b27ec6Sopenharmony_ci printf("decompress : %s -> %s\n", lz4Filename, decFilename); 20127b27ec6Sopenharmony_ci LZ4F_errorCode_t ret = decompress_file(inpFp, outFp); 20227b27ec6Sopenharmony_ci 20327b27ec6Sopenharmony_ci fclose(outFp); 20427b27ec6Sopenharmony_ci fclose(inpFp); 20527b27ec6Sopenharmony_ci 20627b27ec6Sopenharmony_ci if (ret) { 20727b27ec6Sopenharmony_ci printf("compression error: %s\n", LZ4F_getErrorName(ret)); 20827b27ec6Sopenharmony_ci return 1; 20927b27ec6Sopenharmony_ci } 21027b27ec6Sopenharmony_ci 21127b27ec6Sopenharmony_ci printf("decompress : done\n"); 21227b27ec6Sopenharmony_ci } 21327b27ec6Sopenharmony_ci 21427b27ec6Sopenharmony_ci /* verify */ 21527b27ec6Sopenharmony_ci { FILE* const inpFp = fopen(inpFilename, "rb"); 21627b27ec6Sopenharmony_ci FILE* const decFp = fopen(decFilename, "rb"); 21727b27ec6Sopenharmony_ci 21827b27ec6Sopenharmony_ci printf("verify : %s <-> %s\n", inpFilename, decFilename); 21927b27ec6Sopenharmony_ci int const cmp = compareFiles(inpFp, decFp); 22027b27ec6Sopenharmony_ci 22127b27ec6Sopenharmony_ci fclose(decFp); 22227b27ec6Sopenharmony_ci fclose(inpFp); 22327b27ec6Sopenharmony_ci 22427b27ec6Sopenharmony_ci if (cmp) { 22527b27ec6Sopenharmony_ci printf("corruption detected : decompressed file differs from original\n"); 22627b27ec6Sopenharmony_ci return cmp; 22727b27ec6Sopenharmony_ci } 22827b27ec6Sopenharmony_ci 22927b27ec6Sopenharmony_ci printf("verify : OK\n"); 23027b27ec6Sopenharmony_ci } 23127b27ec6Sopenharmony_ci 23227b27ec6Sopenharmony_ci} 233