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=33637d7de36a4bd92afb313f143c8ad128d8eaa8;hb=HEAD;hpb=4bcffe8896c08c9f60b2707da71bb39a64618d93 diff --git a/src/main/java/eu/svjatoslav/imagesqueeze/codec/Table.java b/src/main/java/eu/svjatoslav/imagesqueeze/codec/Table.java index 33637d7..164f3a6 100755 --- a/src/main/java/eu/svjatoslav/imagesqueeze/codec/Table.java +++ b/src/main/java/eu/svjatoslav/imagesqueeze/codec/Table.java @@ -1,211 +1,167 @@ /* - * Imagesqueeze - Image codec optimized for photos. - * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public License - * as published by the Free Software Foundation. + * Image codec. Author: Svjatoslav Agejenko, svjatoslav@svjatoslav.eu + * This project is released under Creative Commons Zero (CC0) license. */ - package eu.svjatoslav.imagesqueeze.codec; -import java.io.IOException; - 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; - - /** - * @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++; - } - - /** - * Compares two tables. Ignores table initialization. - */ - @Override - public int compareTo(final 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 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]); - } - } - - } - - public void load(final BitInputStream inputStream) throws IOException { - reset(); - - final int availableEntries = inputStream.readIntegerCompressed8(); - - 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; - final int proposal = bitCountForRange[range]; - return proposal; - } - - 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]; - 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 save(final BitOutputStream outputStream) throws IOException { - outputStream.storeIntegerCompressed8(usedEntries); - - for (int i = 0; i < usedEntries; i++) { - outputStream.storeBits(range[i], 8); - outputStream.storeBits(switchTreshold[i], 8); - outputStream.storeBits(bitcount[i], 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); + } + } }