11e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan/*
21e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * DeltaOptions
31e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan *
41e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * Author: Lasse Collin <lasse.collin@tukaani.org>
51e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan *
61e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * This file has been put into the public domain.
71e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * You can do whatever you want with this file.
81e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan */
91e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
101e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnanpackage org.tukaani.xz;
111e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
121e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnanimport java.io.InputStream;
131e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
141e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan/**
151e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * Delta filter options. The Delta filter can be used only as a non-last
161e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * filter in the chain, for example Delta + LZMA2.
171e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * <p>
181e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * Currently only simple byte-wise delta is supported. The only option
191e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * is the delta distance, which you should set to match your data.
201e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * It's not possible to provide a generic default value for it.
211e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * <p>
221e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * For example, with distance = 2 and eight-byte input
231e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * A1 B1 A2 B3 A3 B5 A4 B7, the output will be A1 B1 01 02 01 02 01 02.
241e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * <p>
251e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * The Delta filter can be good with uncompressed bitmap images. It can
261e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * also help with PCM audio, although special-purpose compressors like
271e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * FLAC will give much smaller result at much better compression speed.
281e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan */
291e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnanpublic class DeltaOptions extends FilterOptions {
301e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    /**
311e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan     * Smallest supported delta calculation distance.
321e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan     */
331e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    public static final int DISTANCE_MIN = 1;
341e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
351e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    /**
361e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan     * Largest supported delta calculation distance.
371e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan     */
381e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    public static final int DISTANCE_MAX = 256;
391e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
401e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    private int distance = DISTANCE_MIN;
411e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
421e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    /**
431e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan     * Creates new Delta options and sets the delta distance to 1 byte.
441e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan     */
451e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    public DeltaOptions() {}
461e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
471e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    /**
481e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan     * Creates new Delta options and sets the distance to the given value.
491e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan     */
501e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    public DeltaOptions(int distance) throws UnsupportedOptionsException {
511e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan        setDistance(distance);
521e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    }
531e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
541e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    /**
551e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan     * Sets the delta distance in bytes. The new distance must be in
561e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan     * the range [DISTANCE_MIN, DISTANCE_MAX].
571e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan     */
581e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    public void setDistance(int distance) throws UnsupportedOptionsException {
591e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan        if (distance < DISTANCE_MIN || distance > DISTANCE_MAX)
601e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan            throw new UnsupportedOptionsException(
611e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan                    "Delta distance must be in the range [" + DISTANCE_MIN
621e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan                    + ", " + DISTANCE_MAX + "]: " + distance);
631e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
641e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan        this.distance = distance;
651e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    }
661e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
671e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    /**
681e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan     * Gets the delta distance.
691e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan     */
701e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    public int getDistance() {
711e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan        return distance;
721e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    }
731e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
741e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    public int getEncoderMemoryUsage() {
751e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan        return DeltaOutputStream.getMemoryUsage();
761e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    }
771e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
781e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    public FinishableOutputStream getOutputStream(FinishableOutputStream out) {
791e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan        return new DeltaOutputStream(out, this);
801e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    }
811e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
821e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    public int getDecoderMemoryUsage() {
831e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan        return 1;
841e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    }
851e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
861e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    public InputStream getInputStream(InputStream in) {
871e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan        return new DeltaInputStream(in, distance);
881e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    }
891e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
901e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    FilterEncoder getFilterEncoder() {
911e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan        return new DeltaEncoder(this);
921e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    }
931e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
941e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    public Object clone() {
951e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan        try {
961e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan            return super.clone();
971e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan        } catch (CloneNotSupportedException e) {
981e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan            assert false;
991e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan            throw new RuntimeException();
1001e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan        }
1011e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    }
1021e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan}
103