fileCompress.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /* LZ4file API example : compress a file
  2. * Modified from an example code by anjiahao
  3. *
  4. * This example will demonstrate how
  5. * to manipulate lz4 compressed files like
  6. * normal files */
  7. #include <assert.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <sys/stat.h>
  12. #include <lz4file.h>
  13. #define CHUNK_SIZE (16*1024)
  14. static size_t get_file_size(char *filename)
  15. {
  16. struct stat statbuf;
  17. if (filename == NULL) {
  18. return 0;
  19. }
  20. if(stat(filename,&statbuf)) {
  21. return 0;
  22. }
  23. return statbuf.st_size;
  24. }
  25. static int compress_file(FILE* f_in, FILE* f_out)
  26. {
  27. assert(f_in != NULL); assert(f_out != NULL);
  28. LZ4F_errorCode_t ret = LZ4F_OK_NoError;
  29. size_t len;
  30. LZ4_writeFile_t* lz4fWrite;
  31. void* const buf = malloc(CHUNK_SIZE);
  32. if (!buf) {
  33. printf("error: memory allocation failed \n");
  34. }
  35. /* Of course, you can also use prefsPtr to
  36. * set the parameters of the compressed file
  37. * NULL is use default
  38. */
  39. ret = LZ4F_writeOpen(&lz4fWrite, f_out, NULL);
  40. if (LZ4F_isError(ret)) {
  41. printf("LZ4F_writeOpen error: %s\n", LZ4F_getErrorName(ret));
  42. free(buf);
  43. return 1;
  44. }
  45. while (1) {
  46. len = fread(buf, 1, CHUNK_SIZE, f_in);
  47. if (ferror(f_in)) {
  48. printf("fread error\n");
  49. goto out;
  50. }
  51. /* nothing to read */
  52. if (len == 0) {
  53. break;
  54. }
  55. ret = LZ4F_write(lz4fWrite, buf, len);
  56. if (LZ4F_isError(ret)) {
  57. printf("LZ4F_write: %s\n", LZ4F_getErrorName(ret));
  58. goto out;
  59. }
  60. }
  61. out:
  62. free(buf);
  63. if (LZ4F_isError(LZ4F_writeClose(lz4fWrite))) {
  64. printf("LZ4F_writeClose: %s\n", LZ4F_getErrorName(ret));
  65. return 1;
  66. }
  67. return 0;
  68. }
  69. static int decompress_file(FILE* f_in, FILE* f_out)
  70. {
  71. assert(f_in != NULL); assert(f_out != NULL);
  72. LZ4F_errorCode_t ret = LZ4F_OK_NoError;
  73. LZ4_readFile_t* lz4fRead;
  74. void* const buf= malloc(CHUNK_SIZE);
  75. if (!buf) {
  76. printf("error: memory allocation failed \n");
  77. }
  78. ret = LZ4F_readOpen(&lz4fRead, f_in);
  79. if (LZ4F_isError(ret)) {
  80. printf("LZ4F_readOpen error: %s\n", LZ4F_getErrorName(ret));
  81. free(buf);
  82. return 1;
  83. }
  84. while (1) {
  85. ret = LZ4F_read(lz4fRead, buf, CHUNK_SIZE);
  86. if (LZ4F_isError(ret)) {
  87. printf("LZ4F_read error: %s\n", LZ4F_getErrorName(ret));
  88. goto out;
  89. }
  90. /* nothing to read */
  91. if (ret == 0) {
  92. break;
  93. }
  94. if(fwrite(buf, 1, ret, f_out) != ret) {
  95. printf("write error!\n");
  96. goto out;
  97. }
  98. }
  99. out:
  100. free(buf);
  101. if (LZ4F_isError(LZ4F_readClose(lz4fRead))) {
  102. printf("LZ4F_readClose: %s\n", LZ4F_getErrorName(ret));
  103. return 1;
  104. }
  105. if (ret) {
  106. return 1;
  107. }
  108. return 0;
  109. }
  110. int compareFiles(FILE* fp0, FILE* fp1)
  111. {
  112. int result = 0;
  113. while (result==0) {
  114. char b0[1024];
  115. char b1[1024];
  116. size_t const r0 = fread(b0, 1, sizeof(b0), fp0);
  117. size_t const r1 = fread(b1, 1, sizeof(b1), fp1);
  118. result = (r0 != r1);
  119. if (!r0 || !r1) break;
  120. if (!result) result = memcmp(b0, b1, r0);
  121. }
  122. return result;
  123. }
  124. int main(int argc, const char **argv) {
  125. char inpFilename[256] = { 0 };
  126. char lz4Filename[256] = { 0 };
  127. char decFilename[256] = { 0 };
  128. if (argc < 2) {
  129. printf("Please specify input filename\n");
  130. return 0;
  131. }
  132. snprintf(inpFilename, 256, "%s", argv[1]);
  133. snprintf(lz4Filename, 256, "%s.lz4", argv[1]);
  134. snprintf(decFilename, 256, "%s.lz4.dec", argv[1]);
  135. printf("inp = [%s]\n", inpFilename);
  136. printf("lz4 = [%s]\n", lz4Filename);
  137. printf("dec = [%s]\n", decFilename);
  138. /* compress */
  139. { FILE* const inpFp = fopen(inpFilename, "rb");
  140. FILE* const outFp = fopen(lz4Filename, "wb");
  141. printf("compress : %s -> %s\n", inpFilename, lz4Filename);
  142. LZ4F_errorCode_t ret = compress_file(inpFp, outFp);
  143. fclose(inpFp);
  144. fclose(outFp);
  145. if (ret) {
  146. printf("compression error: %s\n", LZ4F_getErrorName(ret));
  147. return 1;
  148. }
  149. printf("%s: %zu → %zu bytes, %.1f%%\n",
  150. inpFilename,
  151. get_file_size(inpFilename),
  152. get_file_size(lz4Filename), /* might overflow is size_t is 32 bits and size_{in,out} > 4 GB */
  153. (double)get_file_size(lz4Filename) / get_file_size(inpFilename) * 100);
  154. printf("compress : done\n");
  155. }
  156. /* decompress */
  157. {
  158. FILE* const inpFp = fopen(lz4Filename, "rb");
  159. FILE* const outFp = fopen(decFilename, "wb");
  160. printf("decompress : %s -> %s\n", lz4Filename, decFilename);
  161. LZ4F_errorCode_t ret = decompress_file(inpFp, outFp);
  162. fclose(outFp);
  163. fclose(inpFp);
  164. if (ret) {
  165. printf("compression error: %s\n", LZ4F_getErrorName(ret));
  166. return 1;
  167. }
  168. printf("decompress : done\n");
  169. }
  170. /* verify */
  171. { FILE* const inpFp = fopen(inpFilename, "rb");
  172. FILE* const decFp = fopen(decFilename, "rb");
  173. printf("verify : %s <-> %s\n", inpFilename, decFilename);
  174. int const cmp = compareFiles(inpFp, decFp);
  175. fclose(decFp);
  176. fclose(inpFp);
  177. if (cmp) {
  178. printf("corruption detected : decompressed file differs from original\n");
  179. return cmp;
  180. }
  181. printf("verify : OK\n");
  182. }
  183. }