1 package eu.svjatoslav.imagesqueeze.codec;
3 import java.io.IOException;
9 public class Table implements Comparable<Table>{
11 int [] range = new int[100];
12 int [] switchTreshold = new int[100];
13 int [] bitcount = new int[100];
16 int [] bitCountForRange = new int[256];
17 int [] proposedRangeForActualRange = new int[256];
18 int [] proposedRangeForActualRangeLow = new int[256];
19 int [] proposedRangeForActualRangeHigh = new int[256];
20 byte [] proposedDecreasedRange = new byte[256];
26 public void computeLookupTables(){
27 int currentCheckPointer = 0;
29 for (int i=0; i<256; i++){
31 if (range[currentCheckPointer] == i){
32 currentCheckPointer++;
35 if (currentCheckPointer > 0){
36 bitCountForRange[i] = bitcount[currentCheckPointer-1];
38 bitCountForRange[i] = 0;
43 for (int i=0; i<256; i++){
47 for (seek = 0; seek < usedEntries; seek ++){
49 if (switchTreshold[seek] >= i) break seekLoop;
54 proposedRangeForActualRange[i] = range[seek];
56 proposedRangeForActualRangeLow[i] = 0;
58 proposedRangeForActualRangeLow[i] = switchTreshold[seek-1]+1;
60 proposedRangeForActualRangeHigh[i] = switchTreshold[seek];
64 currentCheckPointer = usedEntries - 2;
65 for (int i=255; i >= 0; i--){
66 if (range[currentCheckPointer] == i) currentCheckPointer--;
68 if (currentCheckPointer < 0){
69 proposedDecreasedRange[i] = 0;
71 proposedDecreasedRange[i] = (byte)(range[currentCheckPointer]);
78 * @param switchTreshold - switch to this range when actual range in equal or below this treshold
80 public void addEntry(int range, int switchTreshold, int bitcount){
81 if (range < 0) range = 0;
82 if (range > 255) range = 255;
84 if (switchTreshold < 0) switchTreshold = 0;
85 if (switchTreshold > 255) switchTreshold = 255;
87 if (bitcount < 0) bitcount = 0;
88 if (bitcount > 8) bitcount = 8;
91 this.range[usedEntries] = range;
92 this.switchTreshold[usedEntries] = switchTreshold;
93 this.bitcount[usedEntries] = bitcount;
100 public int proposeRangeForRange(int actualRange, int inheritedRange){
102 if (inheritedRange > 255) inheritedRange = 255;
103 if (inheritedRange < 0) inheritedRange = 0;
105 if (proposedRangeForActualRangeLow[inheritedRange] <= actualRange){
106 return inheritedRange;
109 return proposeDecreasedRange(inheritedRange);
113 public int proposeDecreasedRange(int range){
114 if (range > 255) range = 255;
115 if (range < 0) range = 0;
117 return ImageEncoder.byteToInt(proposedDecreasedRange[range]);
121 public int proposeBitcountForRange(int range){
122 if (range > 255) range = 255;
123 if (range < 0) range = 0;
124 int proposal = bitCountForRange[range];
129 * Compares two tables.
130 * Ignores table initialization.
132 public int compareTo(Table o) {
133 if (usedEntries < o.usedEntries) return -1;
134 if (usedEntries > o.usedEntries) return 1;
136 for (int i=0; i<usedEntries; i++){
137 if (range[i] < o.range[i]) return -1;
138 if (range[i] > o.range[i]) return 1;
140 if (switchTreshold[i] < o.switchTreshold[i]) return -1;
141 if (switchTreshold[i] > o.switchTreshold[i]) return 1;
143 if (bitcount[i] < o.bitcount[i]) return -1;
144 if (bitcount[i] > o.bitcount[i]) return 1;
150 public void save(BitOutputStream outputStream) throws IOException {
151 outputStream.storeIntegerCompressed8(usedEntries);
153 for (int i=0; i < usedEntries; i++){
154 outputStream.storeBits(this.range[i], 8);
155 outputStream.storeBits(this.switchTreshold[i], 8);
156 outputStream.storeBits(this.bitcount[i], 4);
161 range = new int[100];
162 switchTreshold = new int[100];
163 bitcount = new int[100];
166 bitCountForRange = new int[256];
167 proposedRangeForActualRange = new int[256];
168 proposedRangeForActualRangeLow = new int[256];
169 proposedRangeForActualRangeHigh = new int[256];
170 proposedDecreasedRange = new byte[256];
175 public void load(BitInputStream inputStream) throws IOException {
178 int availableEntries = inputStream.readIntegerCompressed8();
180 for (int i=0; i < availableEntries; i++){
181 addEntry(inputStream.readBits(8), inputStream.readBits(8), inputStream.readBits(4));