1 package nom.tam.fits.compress;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.util.logging.Level;
6 import java.util.logging.Logger;
7
8 import nom.tam.fits.FitsException;
9
10 /*
11 * #%L
12 * nom.tam FITS library
13 * %%
14 * Copyright (C) 1996 - 2024 nom-tam-fits
15 * %%
16 * This is free and unencumbered software released into the public domain.
17 *
18 * Anyone is free to copy, modify, publish, use, compile, sell, or
19 * distribute this software, either in source code form or as a compiled
20 * binary, for any purpose, commercial or non-commercial, and by any
21 * means.
22 *
23 * In jurisdictions that recognize copyright laws, the author or authors
24 * of this software dedicate any and all copyright interest in the
25 * software to the public domain. We make this dedication for the benefit
26 * of the public at large and to the detriment of our heirs and
27 * successors. We intend this dedication to be an overt act of
28 * relinquishment in perpetuity of all present and future rights to this
29 * software under copyright law.
30 *
31 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
34 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
35 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
36 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
37 * OTHER DEALINGS IN THE SOFTWARE.
38 * #L%
39 */
40
41 import static nom.tam.util.LoggerHelper.getLogger;
42
43 /**
44 * (<i>for internal use</i>) UNIX compressed (<code>.Z</code>) input stream decompression with a preference for using an
45 * external system command. You can use this class to decompress files that have been compressed with the UNIX
46 * <b>compress</b> tool (or via <b>gzip</b>) and have the characteristic <code>.Z</code> file name extension. It
47 * effectively provides the same functionality as {@link ZCompressionProvider}, but has a preference for calling on the
48 * system <b>uncompress</b> command first to do the lifting. If that fails it will call on {@link CompressionManager} to
49 * provide a suitable decompressor (which will give it {@link ZCompressionProvider}). Since the <b>compress</b> tool is
50 * UNIX-specific, it is not entirely portable. As a result, you are probably better off relying on those other classes
51 * directly.
52 *
53 * @see CompressionManager
54 *
55 * @deprecated Use {@link ZCompressionProvider}. or the more generic {@link CompressionManager} with a preference toward
56 * using the system command if possible. instead.
57 */
58 @Deprecated
59 public class BasicCompressProvider implements ICompressProvider {
60
61 private static final int PRIORITY = 10;
62
63 private static final int COMPRESS_MAGIC_BYTE1 = 0x1f;
64
65 private static final int COMPRESS_MAGIC_BYTE2 = 0x9d;
66
67 private static final Logger LOG = getLogger(BasicCompressProvider.class);
68
69 private InputStream compressInputStream(final InputStream compressed) throws IOException, FitsException {
70 try {
71 Process proc = new ProcessBuilder("uncompress", "-c").start();
72 return new CloseIS(proc, compressed);
73 } catch (Exception e) {
74 ICompressProvider next = CompressionManager.nextCompressionProvider(COMPRESS_MAGIC_BYTE1, COMPRESS_MAGIC_BYTE2,
75 this);
76 if (next != null) {
77 LOG.log(Level.WARNING,
78 "Error initiating .Z decompression: " + e.getMessage() + " trying alternative decompressor", e);
79 return next.decompress(compressed);
80 }
81 throw new FitsException("Unable to read .Z compressed stream.\nIs 'uncompress' in the path?", e);
82 }
83 }
84
85 @Override
86 public InputStream decompress(InputStream in) throws IOException, FitsException {
87 return compressInputStream(in);
88 }
89
90 @Override
91 public int priority() {
92 return PRIORITY;
93 }
94
95 @Override
96 public boolean provides(int mag1, int mag2) {
97 return mag1 == COMPRESS_MAGIC_BYTE1 && mag2 == COMPRESS_MAGIC_BYTE2;
98 }
99 }