1/*
2 * DeltaOptions
3 *
4 * Author: Lasse Collin <lasse.collin@tukaani.org>
5 *
6 * This file has been put into the public domain.
7 * You can do whatever you want with this file.
8 */
9
10package org.tukaani.xz;
11
12import java.io.InputStream;
13
14/**
15 * Delta filter options. The Delta filter can be used only as a non-last
16 * filter in the chain, for example Delta + LZMA2.
17 * <p>
18 * Currently only simple byte-wise delta is supported. The only option
19 * is the delta distance, which you should set to match your data.
20 * It's not possible to provide a generic default value for it.
21 * <p>
22 * For example, with distance = 2 and eight-byte input
23 * A1 B1 A2 B3 A3 B5 A4 B7, the output will be A1 B1 01 02 01 02 01 02.
24 * <p>
25 * The Delta filter can be good with uncompressed bitmap images. It can
26 * also help with PCM audio, although special-purpose compressors like
27 * FLAC will give much smaller result at much better compression speed.
28 */
29public class DeltaOptions extends FilterOptions {
30    /**
31     * Smallest supported delta calculation distance.
32     */
33    public static final int DISTANCE_MIN = 1;
34
35    /**
36     * Largest supported delta calculation distance.
37     */
38    public static final int DISTANCE_MAX = 256;
39
40    private int distance = DISTANCE_MIN;
41
42    /**
43     * Creates new Delta options and sets the delta distance to 1 byte.
44     */
45    public DeltaOptions() {}
46
47    /**
48     * Creates new Delta options and sets the distance to the given value.
49     */
50    public DeltaOptions(int distance) throws UnsupportedOptionsException {
51        setDistance(distance);
52    }
53
54    /**
55     * Sets the delta distance in bytes. The new distance must be in
56     * the range [DISTANCE_MIN, DISTANCE_MAX].
57     */
58    public void setDistance(int distance) throws UnsupportedOptionsException {
59        if (distance < DISTANCE_MIN || distance > DISTANCE_MAX)
60            throw new UnsupportedOptionsException(
61                    "Delta distance must be in the range [" + DISTANCE_MIN
62                    + ", " + DISTANCE_MAX + "]: " + distance);
63
64        this.distance = distance;
65    }
66
67    /**
68     * Gets the delta distance.
69     */
70    public int getDistance() {
71        return distance;
72    }
73
74    public int getEncoderMemoryUsage() {
75        return DeltaOutputStream.getMemoryUsage();
76    }
77
78    public FinishableOutputStream getOutputStream(FinishableOutputStream out) {
79        return new DeltaOutputStream(out, this);
80    }
81
82    public int getDecoderMemoryUsage() {
83        return 1;
84    }
85
86    public InputStream getInputStream(InputStream in) {
87        return new DeltaInputStream(in, distance);
88    }
89
90    FilterEncoder getFilterEncoder() {
91        return new DeltaEncoder(this);
92    }
93
94    public Object clone() {
95        try {
96            return super.clone();
97        } catch (CloneNotSupportedException e) {
98            assert false;
99            throw new RuntimeException();
100        }
101    }
102}
103