X-Git-Url: http://www2.svjatoslav.eu/gitweb/?p=imagesqueeze.git;a=blobdiff_plain;f=src%2Fmain%2Fjava%2Feu%2Fsvjatoslav%2Fimagesqueeze%2Fcodec%2FTable.java;h=164f3a6be59680b97006b41f84d9681b557f87e3;hp=4e714f4c8743b521caaf617058b3909d2c91e2de;hb=HEAD;hpb=c7d0b8e1723045c0df086d9214a35f54db47684c diff --git a/src/main/java/eu/svjatoslav/imagesqueeze/codec/Table.java b/src/main/java/eu/svjatoslav/imagesqueeze/codec/Table.java index 4e714f4..164f3a6 100755 --- a/src/main/java/eu/svjatoslav/imagesqueeze/codec/Table.java +++ b/src/main/java/eu/svjatoslav/imagesqueeze/codec/Table.java @@ -1,187 +1,167 @@ +/* + * 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{ - - 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 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); + } + } }