Small update to version number
[PyCatFile.git] / compression.py
blobab74ecef0d2c3b09f28ef4cf0825409886b2fd90
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
4 '''
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the Revised BSD License.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 Revised BSD License for more details.
13 Copyright 2018-2024 Cool Dude 2k - http://idb.berlios.de/
14 Copyright 2018-2024 Game Maker 2k - http://intdb.sourceforge.net/
15 Copyright 2018-2024 Kazuki Przyborowski - https://github.com/KazukiPrzyborowski
17 $FileInfo: compression.py - ast Update: 10/22/2024 Ver. 0.14.2 RC 1 - Author: cooldude2k $
18 '''
20 from __future__ import absolute_import, division, print_function, unicode_literals, generators, with_statement, nested_scopes
21 import os
22 import binascii
23 import argparse
24 import shutil
25 from io import open as open
28 def CompressionSupport():
29 compression_list = []
30 try:
31 import gzip
32 compression_list.append("gz")
33 compression_list.append("gzip")
34 except ImportError:
35 '''return False;'''
36 try:
37 import bz2
38 compression_list.append("bz2")
39 compression_list.append("bzip2")
40 except ImportError:
41 '''return False;'''
42 try:
43 import lz4
44 compression_list.append("lz4")
45 except ImportError:
46 '''return False;'''
47 try:
48 import lzo
49 compression_list.append("lzo")
50 compression_list.append("lzop")
51 except ImportError:
52 '''return False;'''
53 try:
54 import zstandard
55 compression_list.append("zstd")
56 compression_list.append("zstandard")
57 except ImportError:
58 '''return False;'''
59 try:
60 import lzma
61 compression_list.append("lzma")
62 compression_list.append("xz")
63 except ImportError:
64 '''return False;'''
65 return compression_list
68 def CheckCompressionType(infile, closefp=True):
69 if(hasattr(infile, "read") or hasattr(infile, "write")):
70 ckcomfp = infile
71 else:
72 ckcomfp = open(infile, "rb")
73 ckcomfp.seek(0, 0)
74 prefp = ckcomfp.read(2)
75 filetype = False
76 if(prefp == binascii.unhexlify("1f8b")):
77 filetype = "gzip"
78 ckcomfp.seek(0, 0)
79 prefp = ckcomfp.read(3)
80 if(prefp == binascii.unhexlify("425a68")):
81 filetype = "bzip2"
82 ckcomfp.seek(0, 0)
83 prefp = ckcomfp.read(4)
84 if(prefp == binascii.unhexlify("28b52ffd")):
85 filetype = "zstd"
86 if(prefp == binascii.unhexlify("04224d18")):
87 filetype = "lz4"
88 ckcomfp.seek(0, 0)
89 prefp = ckcomfp.read(7)
90 if(prefp == binascii.unhexlify("fd377a585a0000")):
91 filetype = "lzma"
92 ckcomfp.seek(0, 0)
93 prefp = ckcomfp.read(9)
94 if(prefp == binascii.unhexlify("894c5a4f000d0a1a0a")):
95 filetype = "lzo"
96 ckcomfp.seek(0, 0)
97 if(closefp):
98 ckcomfp.close()
99 return filetype
102 def gzip_file(infile, outfile, level=9, keepfile=True):
103 support_list = CompressionSupport()
104 if(not os.path.exists(infile) or not os.path.isfile(infile)):
105 return False
106 if(os.path.exists(outfile)):
107 return False
108 if("gzip" not in support_list):
109 return False
110 import gzip
111 ucfilefp = open(infile, "rb")
112 cfilefp = gzip.open(outfile, "wb", level)
113 shutil.copyfileobj(ucfilefp, cfilefp)
114 cfilefp.close()
115 ucfilefp.close()
116 if(CheckCompressionType(outfile) != "gzip"):
117 os.remove(outfile)
118 return False
119 if(not keepfile):
120 os.remove(infile)
121 return True
124 def gunzip_file(infile, outfile, keepfile=True):
125 support_list = CompressionSupport()
126 if(not os.path.exists(infile) or not os.path.isfile(infile)):
127 return False
128 if(os.path.exists(outfile)):
129 return False
130 if("gzip" not in support_list):
131 return False
132 if(CheckCompressionType(infile) != "gzip"):
133 return False
134 import gzip
135 ucfilefp = open(outfile, "wb")
136 cfilefp = gzip.open(infile, "rb")
137 shutil.copyfileobj(cfilefp, ucfilefp)
138 cfilefp.close()
139 ucfilefp.close()
140 if(not keepfile):
141 os.remove(infile)
142 return True
145 def bzip2_file(infile, outfile, level=9, keepfile=True):
146 support_list = CompressionSupport()
147 if(not os.path.exists(infile) or not os.path.isfile(infile)):
148 return False
149 if(os.path.exists(outfile)):
150 return False
151 if("bzip2" not in support_list):
152 return False
153 import bz2
154 ucfilefp = open(infile, "rb")
155 cfilefp = bz2.BZ2File(outfile, "wb", compresslevel=level)
156 shutil.copyfileobj(ucfilefp, cfilefp)
157 cfilefp.close()
158 ucfilefp.close()
159 if(CheckCompressionType(outfile) != "bzip2"):
160 os.remove(outfile)
161 return False
162 if(not keepfile):
163 os.remove(infile)
164 return True
167 def bunzip2_file(infile, outfile, keepfile=True):
168 support_list = CompressionSupport()
169 if(not os.path.exists(infile) or not os.path.isfile(infile)):
170 return False
171 if(os.path.exists(outfile)):
172 return False
173 if("bzip2" not in support_list):
174 return False
175 if(CheckCompressionType(infile) != "bzip2"):
176 return False
177 import bz2
178 ucfilefp = open(outfile, "wb")
179 cfilefp = bz2.BZ2File(infile, "rb")
180 shutil.copyfileobj(cfilefp, ucfilefp)
181 cfilefp.close()
182 ucfilefp.close()
183 if(not keepfile):
184 os.remove(infile)
185 return True
188 def zstd_file(infile, outfile, level=9, keepfile=True):
189 support_list = CompressionSupport()
190 if(not os.path.exists(infile) or not os.path.isfile(infile)):
191 return False
192 if(os.path.exists(outfile)):
193 return False
194 if("zstd" not in support_list):
195 return False
196 import zstandard
197 ucfilefp = open(infile, "rb")
198 cfilefp = zstandard.open(
199 outfile, "wb", zstandard.ZstdCompressor(level=level))
200 shutil.copyfileobj(ucfilefp, cfilefp)
201 cfilefp.close()
202 ucfilefp.close()
203 if(CheckCompressionType(outfile) != "zstd"):
204 os.remove(outfile)
205 return False
206 if(not keepfile):
207 os.remove(infile)
208 return True
211 def unzstd_file(infile, outfile, keepfile=True):
212 support_list = CompressionSupport()
213 if(not os.path.exists(infile) or not os.path.isfile(infile)):
214 return False
215 if(os.path.exists(outfile)):
216 return False
217 if("zstd" not in support_list):
218 return False
219 if(CheckCompressionType(infile) != "zstd"):
220 return False
221 import zstandard
222 ucfilefp = open(outfile, "wb")
223 cfilefp = zstandard.open(infile, "rb")
224 shutil.copyfileobj(cfilefp, ucfilefp)
225 cfilefp.close()
226 ucfilefp.close()
227 if(not keepfile):
228 os.remove(infile)
229 return True
232 def lz4_file(infile, outfile, level=9, keepfile=True):
233 support_list = CompressionSupport()
234 if(not os.path.exists(infile) or not os.path.isfile(infile)):
235 return False
236 if(os.path.exists(outfile)):
237 return False
238 if("lz4" not in support_list):
239 return False
240 import lz4
241 ucfilefp = open(infile, "rb")
242 cfilefp = lz4.frame.open(outfile, "wb", compression_level=level)
243 shutil.copyfileobj(ucfilefp, cfilefp)
244 cfilefp.close()
245 ucfilefp.close()
246 if(CheckCompressionType(outfile) != "lz4"):
247 os.remove(outfile)
248 return False
249 if(not keepfile):
250 os.remove(infile)
251 return True
254 def unlz4_file(infile, outfile, keepfile=True):
255 support_list = CompressionSupport()
256 if(not os.path.exists(infile) or not os.path.isfile(infile)):
257 return False
258 if(os.path.exists(outfile)):
259 return False
260 if("lz4" not in support_list):
261 return False
262 if(CheckCompressionType(infile) != "lz4"):
263 return False
264 import lz4
265 ucfilefp = open(outfile, "wb")
266 cfilefp = lz4.frame.open(infile, "rb")
267 shutil.copyfileobj(cfilefp, ucfilefp)
268 cfilefp.close()
269 ucfilefp.close()
270 if(not keepfile):
271 os.remove(infile)
272 return True
275 def lzo_file(infile, outfile, level=9, keepfile=True):
276 support_list = CompressionSupport()
277 if(not os.path.exists(infile) or not os.path.isfile(infile)):
278 return False
279 if(os.path.exists(outfile)):
280 return False
281 if("lzo" not in support_list):
282 return False
283 import lzo
284 ucfilefp = open(infile, "rb")
285 cfilefp = open(outfile, "wb")
286 cfilefp.write(lzo.compress(ucfilefp.read(), level))
287 cfilefp.close()
288 ucfilefp.close()
289 if(CheckCompressionType(outfile) != "lzo"):
290 os.remove(outfile)
291 return False
292 if(not keepfile):
293 os.remove(infile)
294 return True
297 def unlzo_file(infile, outfile, keepfile=True):
298 support_list = CompressionSupport()
299 if(not os.path.exists(infile) or not os.path.isfile(infile)):
300 return False
301 if(os.path.exists(outfile)):
302 return False
303 if("lzo" not in support_list):
304 return False
305 if(CheckCompressionType(infile) != "lzo"):
306 return False
307 import lzo
308 ucfilefp = open(outfile, "wb")
309 cfilefp = open(infile, "rb")
310 ucfilefp.write(lzo.decompress(cfilefp.read()))
311 cfilefp.close()
312 ucfilefp.close()
313 if(not keepfile):
314 os.remove(infile)
315 return True
318 def lzma_file(infile, outfile, level=9, keepfile=True):
319 support_list = CompressionSupport()
320 if(not os.path.exists(infile) or not os.path.isfile(infile)):
321 return False
322 if(os.path.exists(outfile)):
323 return False
324 if("lzma" not in support_list):
325 return False
326 import lzma
327 ucfilefp = open(infile, "rb")
328 cfilefp = lzma.open(outfile, "wb", format=lzma.FORMAT_ALONE, preset=level)
329 shutil.copyfileobj(ucfilefp, cfilefp)
330 cfilefp.close()
331 ucfilefp.close()
332 if(CheckCompressionType(outfile) != "lzma"):
333 os.remove(outfile)
334 return False
335 if(not keepfile):
336 os.remove(infile)
337 return True
340 def unlzma_file(infile, outfile, keepfile=True):
341 support_list = CompressionSupport()
342 if(not os.path.exists(infile) or not os.path.isfile(infile)):
343 return False
344 if(os.path.exists(outfile)):
345 return False
346 if("lzma" not in support_list):
347 return False
348 if(CheckCompressionType(infile) != "lzma"):
349 return False
350 import lzma
351 ucfilefp = open(outfile, "wb")
352 cfilefp = lzma.open(infile, "rb", format=lzma.FORMAT_ALONE)
353 shutil.copyfileobj(cfilefp, ucfilefp)
354 cfilefp.close()
355 ucfilefp.close()
356 if(not keepfile):
357 os.remove(infile)
358 return True
361 def xz_file(infile, outfile, level=9, keepfile=True):
362 support_list = CompressionSupport()
363 if(not os.path.exists(infile) or not os.path.isfile(infile)):
364 return False
365 if(os.path.exists(outfile)):
366 return False
367 if("xz" not in support_list):
368 return False
369 import lzma
370 ucfilefp = open(infile, "rb")
371 cfilefp = lzma.open(outfile, "wb", format=lzma.FORMAT_XZ, preset=level)
372 shutil.copyfileobj(ucfilefp, cfilefp)
373 cfilefp.close()
374 ucfilefp.close()
375 if(CheckCompressionType(outfile) != "xz"):
376 os.remove(outfile)
377 return False
378 if(not keepfile):
379 os.remove(infile)
380 return True
383 def unxz_file(infile, outfile, keepfile=True):
384 support_list = CompressionSupport()
385 if(not os.path.exists(infile) or not os.path.isfile(infile)):
386 return False
387 if(os.path.exists(outfile)):
388 return False
389 if("xz" not in support_list):
390 return False
391 if(CheckCompressionType(infile) != "xz"):
392 return False
393 import lzma
394 ucfilefp = open(outfile, "wb")
395 cfilefp = lzma.open(infile, "rb", format=lzma.FORMAT_XZ)
396 shutil.copyfileobj(cfilefp, ucfilefp)
397 cfilefp.close()
398 ucfilefp.close()
399 if(not keepfile):
400 os.remove(infile)
401 return True
404 if __name__ == "__main__":
405 argparser = argparse.ArgumentParser(
406 description="Compress Files", conflict_handler="resolve", add_help=True)
407 argparser.add_argument(
408 "-V", "--version", action="version", version="PyCompress 0.0.1")
409 argparser.add_argument(
410 "-c", "--compress", action="store_true", help="Compress file")
411 argparser.add_argument("-d", "--decompress",
412 action="store_true", help="Decompress file")
413 argparser.add_argument("-i", "-f", "--input",
414 help="Files to compress/decompress", required=True)
415 argparser.add_argument(
416 "-o", "--output", help="Output file after compress/decompress", required=True)
417 argparser.add_argument(
418 "-k", "--keep", action="store_false", help="Keep input file")
419 argparser.add_argument("-l", "--level", default="1",
420 help="Compression level")
421 argparser.add_argument("-compression", "--compression", default="auto",
422 help="File compression to use for compress/decompress")
423 getargs = argparser.parse_args()
424 chkcompression = CompressionSupport()
425 if(getargs.compression not in chkcompression):
426 exit()
427 if(not getargs.compress and not getargs.decompress):
428 exit()
429 if(getargs.compress and getargs.decompress):
430 exit()
431 if(getargs.compress and not getargs.decompress):
432 if(getargs.compression == "gzip" and "gzip" in chkcompression):
433 gzip_file(getargs.input, getargs.output,
434 int(getargs.level), getargs.keep)
435 if(getargs.compression == "bzip2" and "bzip2" in chkcompression):
436 bzip2_file(getargs.input, getargs.output,
437 int(getargs.level), getargs.keep)
438 if(getargs.compression == "zstd" and "zstd" in chkcompression):
439 zstd_file(getargs.input, getargs.output,
440 int(getargs.level), getargs.keep)
441 if(getargs.compression == "lz4" and "lz4" in chkcompression):
442 lz4_file(getargs.input, getargs.output,
443 int(getargs.level), getargs.keep)
444 if(getargs.compression == "lzo" and "lzo" in chkcompression):
445 lzo_file(getargs.input, getargs.output,
446 int(getargs.level), getargs.keep)
447 if(getargs.compression == "lzma" and "lzma" in chkcompression):
448 lzma_file(getargs.input, getargs.output,
449 int(getargs.level), getargs.keep)
450 if(getargs.compression == "xz" and "xz" in chkcompression):
451 xz_file(getargs.input, getargs.output,
452 int(getargs.level), getargs.keep)
453 exit()
454 if(not getargs.compress and getargs.decompress):
455 if(getargs.compression == "gzip" and "gzip" in chkcompression):
456 gunzip_file(getargs.input, getargs.output, getargs.keep)
457 if(getargs.compression == "bzip2" and "bzip2" in chkcompression):
458 bunzip2_file(getargs.input, getargs.output, getargs.keep)
459 if(getargs.compression == "zstd" and "zstd" in chkcompression):
460 unzstd_file(getargs.input, getargs.output, getargs.keep)
461 if(getargs.compression == "lz4" and "lz4" in chkcompression):
462 unlz4_file(getargs.input, getargs.output, getargs.keep)
463 if(getargs.compression == "lzo" and "lzo" in chkcompression):
464 unlzo_file(getargs.input, getargs.output, getargs.keep)
465 if(getargs.compression == "lzma" and "lzma" in chkcompression):
466 unlzma_file(getargs.input, getargs.output, getargs.keep)
467 if(getargs.compression == "xz" and "xz" in chkcompression):
468 unxz_file(getargs.input, getargs.output, getargs.keep)
469 exit()