CompressionUtility.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. #include "CompressionUtility.h"
  2. #include "malloc.h"
  3. #include <cstring>
  4. #include "zlib.h"
  5. #include "minizip/unzip.h"
  6. #define dir_delimter '/'
  7. #define MAX_FILENAME 512
  8. #define READ_SIZE 8192
  9. /// <summary>
  10. /// Compress given buffer as GZIP.
  11. /// Dont forget to free out buffer!!!!
  12. /// </summary>
  13. /// <param name="input"></param>
  14. /// <param name="input_size"></param>
  15. /// <param name="ppvOut"></param>
  16. /// <param name="out_size"></param>
  17. /// <returns></returns>
  18. int CompressionUtility::CompressAsGZip(const void* input, size_t input_size, void** ppvOut, size_t& out_size)
  19. {
  20. z_stream zlib_stream;
  21. zlib_stream.next_in = (Bytef*)input;
  22. zlib_stream.avail_in = (uInt)input_size;
  23. zlib_stream.next_out = Z_NULL;
  24. zlib_stream.avail_out = Z_NULL;
  25. zlib_stream.zalloc = (alloc_func)0;
  26. zlib_stream.zfree = (free_func)0;
  27. zlib_stream.opaque = 0;
  28. int ret = deflateInit2(&zlib_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (16 + MAX_WBITS), 8, Z_DEFAULT_STRATEGY);
  29. unsigned full_length = 2000;
  30. unsigned half_length = input_size / 2;
  31. unsigned compLength = full_length;
  32. unsigned char* comp = (unsigned char*)malloc(compLength);
  33. bool done = false;
  34. while (!done)
  35. {
  36. if (zlib_stream.total_out >= compLength)
  37. {
  38. // Increase size of output buffer
  39. unsigned char* uncomp2 = (unsigned char*)malloc(compLength + half_length);
  40. memcpy(uncomp2, comp, compLength);
  41. compLength += half_length;
  42. free(comp);
  43. comp = uncomp2;
  44. }
  45. zlib_stream.next_out = (Bytef*)(comp + zlib_stream.total_out);
  46. zlib_stream.avail_out = compLength - zlib_stream.total_out;
  47. // Deflate another chunk.
  48. ret = deflate(&zlib_stream, Z_FINISH);
  49. if (Z_STREAM_END == ret)
  50. {
  51. done = true;
  52. }
  53. else if (Z_OK != ret)
  54. {
  55. break;
  56. }
  57. }
  58. if (Z_OK != deflateEnd(&zlib_stream))
  59. {
  60. free(comp);
  61. return ret;
  62. }
  63. *ppvOut = (void*)comp;
  64. out_size = zlib_stream.total_out;
  65. return ret;
  66. }
  67. /// <summary>
  68. /// Decompress given buffer.
  69. /// Dont forget to free out buffer!!!!
  70. /// </summary>
  71. /// <param name="input"></param>
  72. /// <param name="input_size"></param>
  73. /// <param name="ppvOut"></param>
  74. /// <param name="out_size"></param>
  75. /// <returns></returns>
  76. int CompressionUtility::DecompressGZip(const void* input, size_t input_size, void** ppvOut, size_t& out_size)
  77. {
  78. z_stream zlib_stream;
  79. zlib_stream.next_in = (Bytef*)input;
  80. zlib_stream.avail_in = (uInt)input_size;
  81. zlib_stream.next_out = Z_NULL;
  82. zlib_stream.avail_out = Z_NULL;
  83. zlib_stream.zalloc = (alloc_func)0;
  84. zlib_stream.zfree = (free_func)0;
  85. zlib_stream.opaque = Z_NULL;
  86. int ret = inflateInit2(&zlib_stream, (16 + MAX_WBITS));
  87. if (Z_OK != ret)
  88. {
  89. return ret;
  90. }
  91. unsigned full_length = input_size;
  92. unsigned half_length = input_size / 2;
  93. unsigned uncompLength = full_length;
  94. unsigned char* uncomp = (unsigned char*)malloc(uncompLength);
  95. bool done = false;
  96. while (!done)
  97. {
  98. if (zlib_stream.total_out >= uncompLength)
  99. {
  100. // Increase size of output buffer
  101. unsigned char* uncomp2 = (unsigned char*)malloc(uncompLength + half_length);
  102. memcpy(uncomp2, uncomp, uncompLength);
  103. uncompLength += half_length;
  104. free(uncomp);
  105. uncomp = uncomp2;
  106. }
  107. zlib_stream.next_out = (Bytef*)(uncomp + zlib_stream.total_out);
  108. zlib_stream.avail_out = uncompLength - zlib_stream.total_out;
  109. // Inflate another chunk.
  110. ret = inflate(&zlib_stream, Z_SYNC_FLUSH);
  111. if (Z_STREAM_END == ret)
  112. {
  113. done = true;
  114. }
  115. else if (Z_OK != ret)
  116. {
  117. break;
  118. }
  119. }
  120. if (Z_OK != inflateEnd(&zlib_stream))
  121. {
  122. free(uncomp);
  123. return ret;
  124. }
  125. *ppvOut = (void*)uncomp;
  126. out_size = zlib_stream.total_out;
  127. return ret;
  128. }
  129. /// <summary>
  130. /// Returns inflated first file inside the ZIP container,
  131. /// rest are ignored!!!!!
  132. /// </summary>
  133. /// <param name="input"></param>
  134. /// <param name="input_size"></param>
  135. /// <param name="ppvOut"></param>
  136. /// <param name="out_size"></param>
  137. /// <returns></returns>
  138. int CompressionUtility::DecompressPKZip(const char* fn, void** ppvOut, size_t& out_size)
  139. {
  140. // Open the zip file
  141. unzFile zipfile = unzOpen(fn);
  142. if (nullptr == zipfile)
  143. {
  144. // file not found
  145. return -1;
  146. }
  147. // Get info about the zip file
  148. unz_global_info global_info;
  149. if (UNZ_OK != unzGetGlobalInfo(zipfile, &global_info))
  150. {
  151. // could not read file global info
  152. unzClose(zipfile);
  153. return -1;
  154. }
  155. // Buffer to hold data read from the zip file.
  156. //char read_buffer[READ_SIZE];
  157. // Loop to extract all files
  158. for (uLong i = 0; i < global_info.number_entry; ++i)
  159. {
  160. // Get info about current file.
  161. unz_file_info file_info;
  162. char filename[MAX_FILENAME];
  163. if (unzGetCurrentFileInfo(
  164. zipfile,
  165. &file_info,
  166. filename,
  167. MAX_FILENAME,
  168. NULL, 0, NULL, 0) != UNZ_OK)
  169. {
  170. // could not read file info
  171. unzClose(zipfile);
  172. return -1;
  173. }
  174. // Check if this entry is a directory or file.
  175. const size_t filename_length = strlen(filename);
  176. if (filename[filename_length - 1] == dir_delimter)
  177. {
  178. // Entry is a directory, skip it
  179. }
  180. else
  181. {
  182. // Entry is a file, so extract it.
  183. if (unzOpenCurrentFile(zipfile) != UNZ_OK)
  184. {
  185. // could not open file
  186. unzClose(zipfile);
  187. return -1;
  188. }
  189. unsigned full_length = READ_SIZE * 2;
  190. unsigned half_length = READ_SIZE;
  191. unsigned uncompLength = full_length;
  192. unsigned char* uncomp = (unsigned char*)malloc(uncompLength);
  193. size_t total_out = 0;
  194. int error = UNZ_OK;
  195. do
  196. {
  197. if (total_out >= uncompLength)
  198. {
  199. // Increase size of output buffer
  200. unsigned char* uncomp2 = (unsigned char*)malloc(uncompLength + half_length);
  201. memcpy(uncomp2, uncomp, uncompLength);
  202. uncompLength += half_length;
  203. free(uncomp);
  204. uncomp = uncomp2;
  205. }
  206. error = unzReadCurrentFile(zipfile, uncomp + total_out, uncompLength - total_out);
  207. if (error < 0)
  208. {
  209. // something happened
  210. unzCloseCurrentFile(zipfile);
  211. unzClose(zipfile);
  212. return -1;
  213. }
  214. // Write data to buffer.
  215. if (error > 0)
  216. {
  217. total_out += error;
  218. }
  219. } while (error > 0);
  220. *ppvOut = (void*)uncomp;
  221. out_size = total_out;
  222. }
  223. unzCloseCurrentFile(zipfile);
  224. // Go the the next entry listed in the zip file.
  225. //if ((i + 1) < global_info.number_entry)
  226. //{
  227. // if (unzGoToNextFile(zipfile) != UNZ_OK)
  228. // {
  229. // printf("cound not read next file\n");
  230. // unzClose(zipfile);
  231. // return -1;
  232. // }
  233. //}
  234. }
  235. unzClose(zipfile);
  236. return UNZ_OK;
  237. }