Changed license to CC0
[imagesqueeze.git] / src / main / java / eu / svjatoslav / imagesqueeze / codec / Table.java
index 4e714f4..164f3a6 100755 (executable)
+/*
+ * Image codec. Author: Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ * This project is released under Creative Commons Zero (CC0) license.
+ */
 package eu.svjatoslav.imagesqueeze.codec;
 
+import eu.svjatoslav.commons.data.BitInputStream;
+import eu.svjatoslav.commons.data.BitOutputStream;
+
 import java.io.IOException;
 
 /**
  * Quick lookup table.
  */
 
-public class Table implements Comparable<Table>{
-
-       int [] range = new int[100];    
-       int [] switchTreshold = new int[100];
-       int [] bitcount = new int[100];
-
-
-       int [] bitCountForRange = new int[256];
-       int [] proposedRangeForActualRange = new int[256];
-       int [] proposedRangeForActualRangeLow = new int[256];
-       int [] proposedRangeForActualRangeHigh = new int[256];
-       byte [] proposedDecreasedRange = new byte[256];
-
-
-       int usedEntries = 0;
-
-
-       public void computeLookupTables(){
-               int currentCheckPointer = 0;
-
-               for (int i=0; i<256; i++){
-
-                       if (range[currentCheckPointer] == i){
-                               currentCheckPointer++;
-                       }
-
-                       if (currentCheckPointer > 0){
-                               bitCountForRange[i] = bitcount[currentCheckPointer-1];                          
-                       } else {
-                               bitCountForRange[i] = 0;
-                       }
-
-               }
-
-               for (int i=0; i<256; i++){
-
-                       int seek;
-                       seekLoop:{
-                               for (seek = 0; seek < usedEntries; seek ++){
-
-                                       if (switchTreshold[seek] >= i) break seekLoop;
-
-                               }
-                       }
-
-                       proposedRangeForActualRange[i] = range[seek];           
-                       if (seek == 0){
-                               proposedRangeForActualRangeLow[i] = 0;          
-                       } else {
-                               proposedRangeForActualRangeLow[i] = switchTreshold[seek-1]+1;                                           
-                       }
-                       proposedRangeForActualRangeHigh[i] = switchTreshold[seek];                              
-               }
-
-
-               currentCheckPointer = usedEntries - 2;
-               for (int i=255; i >= 0; i--){           
-                       if (range[currentCheckPointer] == i) currentCheckPointer--;
-
-                       if (currentCheckPointer < 0){
-                               proposedDecreasedRange[i] = 0;
-                       } else {
-                               proposedDecreasedRange[i] = (byte)(range[currentCheckPointer]);                         
-                       }
-               }
-
-       }
-
-       /**
-        * @param switchTreshold - switch to this range when actual range in equal or below this treshold
-        */
-       public void addEntry(int range, int switchTreshold, int bitcount){
-               if (range < 0) range = 0;
-               if (range > 255) range = 255;
-
-               if (switchTreshold < 0) switchTreshold = 0;
-               if (switchTreshold > 255) switchTreshold = 255;
-
-               if (bitcount < 0) bitcount = 0;
-               if (bitcount > 8) bitcount = 8;
-
-               
-               this.range[usedEntries] = range;
-               this.switchTreshold[usedEntries] = switchTreshold;
-               this.bitcount[usedEntries] = bitcount;
-               usedEntries++;
-       }
-
-
-       
-       
-       public int proposeRangeForRange(int actualRange, int inheritedRange){
-
-               if (inheritedRange > 255) inheritedRange = 255;
-               if (inheritedRange < 0) inheritedRange = 0;
-
-               if (proposedRangeForActualRangeLow[inheritedRange] <= actualRange){
-                       return inheritedRange;
-               }
-
-               return proposeDecreasedRange(inheritedRange);
-       }
-
-
-       public int proposeDecreasedRange(int range){
-               if (range > 255) range = 255;
-               if (range < 0) range = 0;
-
-               return ImageEncoder.byteToInt(proposedDecreasedRange[range]);
-       }
-
-
-       public int proposeBitcountForRange(int range){
-               if (range > 255) range = 255;
-               if (range < 0) range = 0;
-               int proposal = bitCountForRange[range];
-               return proposal;
-       }
-
-       /**
-        * Compares two tables.
-        * Ignores table initialization.
-        */
-       public int compareTo(Table o) {
-               if (usedEntries < o.usedEntries) return -1;
-               if (usedEntries > o.usedEntries) return 1;
-
-               for (int i=0; i<usedEntries; i++){
-                       if (range[i] < o.range[i]) return -1;
-                       if (range[i] > o.range[i]) return 1;
-
-                       if (switchTreshold[i] < o.switchTreshold[i]) return -1;
-                       if (switchTreshold[i] > o.switchTreshold[i]) return 1;
-
-                       if (bitcount[i] < o.bitcount[i]) return -1;
-                       if (bitcount[i] > o.bitcount[i]) return 1;
-               }
-
-               return 0;
-       }
-
-       public void save(BitOutputStream outputStream) throws IOException {
-               outputStream.storeIntegerCompressed8(usedEntries);
-
-               for (int i=0; i < usedEntries; i++){
-                       outputStream.storeBits(this.range[i], 8);
-                       outputStream.storeBits(this.switchTreshold[i], 8);
-                       outputStream.storeBits(this.bitcount[i], 4);
-               }
-       }
-       
-       public void reset(){
-               range = new int[100];   
-               switchTreshold = new int[100];
-               bitcount = new int[100];
-
-
-               bitCountForRange = new int[256];
-               proposedRangeForActualRange = new int[256];
-               proposedRangeForActualRangeLow = new int[256];
-               proposedRangeForActualRangeHigh = new int[256];
-               proposedDecreasedRange = new byte[256];
-
-               usedEntries = 0;
-       }
-       
-       public void load(BitInputStream inputStream) throws IOException {
-               reset();
-               
-               int availableEntries = inputStream.readIntegerCompressed8();
-               
-               for (int i=0; i < availableEntries; i++){
-                       addEntry(inputStream.readBits(8), inputStream.readBits(8), inputStream.readBits(4));                    
-               }
-       }
-
-
+public class Table {
+
+    private int[] range = new int[100];
+    private int[] switchThreshold = new int[100];
+    private int[] bitCount = new int[100];
+
+    private int[] bitCountForRange = new int[256];
+    private int[] proposedRangeForActualRange = new int[256];
+    private int[] proposedRangeForActualRangeLow = new int[256];
+    private int[] proposedRangeForActualRangeHigh = new int[256];
+    private byte[] proposedDecreasedRange = new byte[256];
+
+    private int usedEntries = 0;
+
+    /**
+     * @param switchThreshold - switch to this range when actual range in equal or below
+     *                        this threshold
+     */
+    public void addEntry(int range, int switchThreshold, int bitcount) {
+        if (range < 0)
+            range = 0;
+        if (range > 255)
+            range = 255;
+
+        if (switchThreshold < 0)
+            switchThreshold = 0;
+        if (switchThreshold > 255)
+            switchThreshold = 255;
+
+        if (bitcount < 0)
+            bitcount = 0;
+        if (bitcount > 8)
+            bitcount = 8;
+
+        this.range[usedEntries] = range;
+        this.switchThreshold[usedEntries] = switchThreshold;
+        this.bitCount[usedEntries] = bitcount;
+        usedEntries++;
+    }
+
+    public void computeLookupTables() {
+        int currentCheckPointer = 0;
+
+        for (int i = 0; i < 256; i++) {
+
+            if (range[currentCheckPointer] == i)
+                currentCheckPointer++;
+
+            if (currentCheckPointer > 0)
+                bitCountForRange[i] = bitCount[currentCheckPointer - 1];
+            else
+                bitCountForRange[i] = 0;
+
+        }
+
+        for (int i = 0; i < 256; i++) {
+
+            int seek;
+            seekLoop:
+            {
+                for (seek = 0; seek < usedEntries; seek++)
+                    if (switchThreshold[seek] >= i)
+                        break seekLoop;
+            }
+
+            proposedRangeForActualRange[i] = range[seek];
+            if (seek == 0)
+                proposedRangeForActualRangeLow[i] = 0;
+            else
+                proposedRangeForActualRangeLow[i] = switchThreshold[seek - 1] + 1;
+            proposedRangeForActualRangeHigh[i] = switchThreshold[seek];
+        }
+
+        currentCheckPointer = usedEntries - 2;
+        for (int i = 255; i >= 0; i--) {
+            if (range[currentCheckPointer] == i)
+                currentCheckPointer--;
+
+            if (currentCheckPointer < 0)
+                proposedDecreasedRange[i] = 0;
+            else
+                proposedDecreasedRange[i] = (byte) (range[currentCheckPointer]);
+        }
+
+    }
+
+    public void load(final BitInputStream inputStream) throws IOException {
+        reset();
+
+        final int availableEntries = ImageDecoder
+                .readIntegerCompressed8(inputStream);
+
+        for (int i = 0; i < availableEntries; i++)
+            addEntry(inputStream.readBits(8), inputStream.readBits(8),
+                    inputStream.readBits(4));
+    }
+
+    public int proposeBitcountForRange(int range) {
+        if (range > 255)
+            range = 255;
+        if (range < 0)
+            range = 0;
+        return bitCountForRange[range];
+    }
+
+    public int proposeDecreasedRange(int range) {
+        if (range > 255)
+            range = 255;
+        if (range < 0)
+            range = 0;
+
+        return ImageEncoder.byteToInt(proposedDecreasedRange[range]);
+    }
+
+    public int proposeRangeForRange(final int actualRange, int inheritedRange) {
+
+        if (inheritedRange > 255)
+            inheritedRange = 255;
+        if (inheritedRange < 0)
+            inheritedRange = 0;
+
+        if (proposedRangeForActualRangeLow[inheritedRange] <= actualRange)
+            return inheritedRange;
+
+        return proposeDecreasedRange(inheritedRange);
+    }
+
+    public void reset() {
+        range = new int[100];
+        switchThreshold = new int[100];
+        bitCount = new int[100];
+
+        bitCountForRange = new int[256];
+        proposedRangeForActualRange = new int[256];
+        proposedRangeForActualRangeLow = new int[256];
+        proposedRangeForActualRangeHigh = new int[256];
+        proposedDecreasedRange = new byte[256];
+
+        usedEntries = 0;
+    }
+
+    public void save(final BitOutputStream outputStream) throws IOException {
+        ImageEncoder.storeIntegerCompressed8(outputStream, usedEntries);
+
+        for (int i = 0; i < usedEntries; i++) {
+            outputStream.storeBits(range[i], 8);
+            outputStream.storeBits(switchThreshold[i], 8);
+            outputStream.storeBits(bitCount[i], 4);
+        }
+    }
 
 }