]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.lz4/src/org/simantics/lz4/LZ4.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.lz4 / src / org / simantics / lz4 / LZ4.java
1 package org.simantics.lz4;\r
2 \r
3 import java.io.File;\r
4 import java.io.FileNotFoundException;\r
5 import java.io.FileOutputStream;\r
6 import java.io.InputStream;\r
7 import java.io.OutputStream;\r
8 import java.nio.ByteBuffer;\r
9 \r
10 import net.jpountz.lz4.LZ4Factory;\r
11 import net.jpountz.util.Native;\r
12 \r
13 import org.simantics.compressions.impl.Buffers;\r
14 import org.simantics.lz4.impl.LZ4InputStream;\r
15 import org.simantics.lz4.impl.LZ4OutputStream;\r
16 \r
17 public class LZ4 {\r
18 \r
19         private static LZ4Factory INSTANCE = null;\r
20         \r
21     static {\r
22         Native.load();\r
23         INSTANCE = LZ4Factory.fastestInstance();\r
24     }\r
25     \r
26     public static LZ4Factory getInstance() {\r
27         return INSTANCE;\r
28     }\r
29     \r
30     public static boolean isNativeInitialized() {\r
31         return Native.isLoaded();\r
32     }\r
33 \r
34     /**\r
35      * The output buffer must be at least 5% larger than the input buffer and\r
36      * can not be smaller than 66 bytes.\r
37      * \r
38      * @param inputSize size of uncompressed input data in bytes\r
39      * @return maximum amount of bytes needed for the compressed data\r
40      */\r
41     public static int compressBound(int inputSize) {\r
42         return INSTANCE.fastCompressor().maxCompressedLength(inputSize);\r
43     }\r
44     \r
45     /**\r
46      * Compress a block of data in the input buffer and returns the size of\r
47      * compressed block. The size of input buffer is specified by length. The\r
48      * minimum input buffer size is 16.\r
49      * \r
50      * <p>\r
51      * The output buffer must be at least 5% larger than the input buffer and\r
52      * can not be smaller than 66 bytes.\r
53      * \r
54      * <p>\r
55      * If the input is not compressible, the return value might be larger than\r
56      * length (input buffer size).\r
57      * \r
58      * <p>\r
59      * The input buffer and the output buffer can not overlap.\r
60      * \r
61      * <p>\r
62      * It is recommended to have both input buffers as direct or heap buffers,\r
63      * not mixed. Mixing different types of buffers will hurt performance a lot.\r
64      * If both buffers are direct byte buffers and native decompression is\r
65      * available, it will be employed.\r
66      */\r
67     public static int compressBuffer(ByteBuffer input, int inputOffset, int length,\r
68             ByteBuffer output, int outputOffset) {\r
69         \r
70         if (output.isReadOnly())\r
71             throw new IllegalArgumentException("read-only output buffer");\r
72 \r
73         if (input.isDirect() && output.isDirect()) {\r
74             return INSTANCE.fastCompressor().compress(input, inputOffset, length, output, outputOffset, output.capacity() - outputOffset);\r
75         }\r
76 \r
77         byte[] inarr = Buffers.getInputArray(input);\r
78         byte[] outarr = Buffers.getOutputArray(output);\r
79         int result = INSTANCE.fastCompressor().compress(inarr, inputOffset, length, outarr, outputOffset, outarr.length - outputOffset);\r
80         Buffers.writeOutput(output, outarr);\r
81         return result;\r
82     }\r
83 \r
84     /**\r
85      * Decompress a block of compressed data and returns the size of the\r
86      * decompressed block. If error occurs, e.g. the compressed data is\r
87      * corrupted or the output buffer is not large enough, then 0 (zero) will be\r
88      * returned instead.\r
89      * \r
90      * <p>\r
91      * The input buffer and the output buffer can not overlap.\r
92      * \r
93      * <p>\r
94      * Decompression is memory safe and guaranteed not to write the output\r
95      * buffer more than what is specified in maxout.\r
96      * \r
97      * <p>\r
98      * It is recommended to have both input buffers as direct or heap buffers,\r
99      * not mixed. Mixing different types of buffers will hurt performance a lot.\r
100      * If both buffers are direct byte buffers and native decompression is\r
101      * available, it will be employed.\r
102      */\r
103     public static int decompressBuffer(ByteBuffer input, int inputOffset, int length,\r
104             ByteBuffer output, int outputOffset, int maxout) {\r
105         if (output.isReadOnly())\r
106             throw new IllegalArgumentException("read-only output buffer");\r
107 \r
108         if (input.isDirect() && output.isDirect())\r
109             return INSTANCE.safeDecompressor().decompress(input, inputOffset, length, output, outputOffset, maxout);\r
110         \r
111 \r
112         byte[] inarr = Buffers.getInputArray(input);\r
113         byte[] outarr = Buffers.getOutputArray(output);\r
114         int result = INSTANCE.safeDecompressor().decompress(inarr, inputOffset, length, outarr, outputOffset, maxout);\r
115         Buffers.writeOutput(output, outarr);\r
116         return result;\r
117     }\r
118 \r
119     /**\r
120      * @param file the FastLZ-compressed file to read\r
121      * @return input stream that decompresses its output using the FastLZ\r
122      *         algorithm. Caller is responsible of closing the returned stream.\r
123      * @throws FileNotFoundException see\r
124      *         {@link FileOutputStream#FileOutputStream(File)} for when this is\r
125      *         thrown\r
126      */\r
127     public static InputStream read(File file) throws FileNotFoundException {\r
128         return new LZ4InputStream(file);\r
129     }\r
130 \r
131     /**\r
132      * @param input\r
133      * @return\r
134      * @param input\r
135      *            the input stream to decompress\r
136      * @return a stream that decompresses the specified FastLZ compressed input\r
137      *         stream\r
138      */\r
139     public static InputStream read(InputStream input) {\r
140         return new LZ4InputStream(input);\r
141     }\r
142 \r
143     /**\r
144      * @param file the FastLZ-compressed file to write\r
145      * @return output stream that compresses its input using the FastLZ\r
146      *         algorithm. Caller is responsible of closing the returned stream.\r
147      * @throws FileNotFoundException see\r
148      *         {@link FileOutputStream#FileOutputStream(File)} for when this is\r
149      *         thrown\r
150      */\r
151     public static OutputStream write(File file) throws FileNotFoundException {\r
152         return new LZ4OutputStream(file);\r
153     }\r
154 \r
155     /**\r
156      * @param output\r
157      *            the stream to write compressed output into\r
158      * @return a stream that compresses into the specified output stream with\r
159      *         FastLZ\r
160      */\r
161     public static OutputStream write(OutputStream output) {\r
162         return new LZ4OutputStream(output);\r
163     }\r
164 \r
165 }\r