moved compressed integer support out of svjatoslavcommons
authorSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Fri, 20 Mar 2015 21:26:09 +0000 (23:26 +0200)
committerSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Fri, 20 Mar 2015 21:26:09 +0000 (23:26 +0200)
pom.xml
src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageDecoder.java
src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageEncoder.java
src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageMetaData.java
src/main/java/eu/svjatoslav/imagesqueeze/codec/Table.java

diff --git a/pom.xml b/pom.xml
index f261444..8655494 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -98,7 +98,7 @@
         <dependency>
             <groupId>eu.svjatoslav</groupId>
             <artifactId>svjatoslavcommons</artifactId>
-            <version>1.0-SNAPSHOT</version>
+            <version>1.5-SNAPSHOT</version>
         </dependency>
     </dependencies>
 
index 78bf715..53f2d91 100755 (executable)
@@ -1,7 +1,7 @@
 /*
  * 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.
@@ -21,24 +21,34 @@ import eu.svjatoslav.commons.data.BitInputStream;
 
 public class ImageDecoder {
 
+       public static int readIntegerCompressed8(final BitInputStream inputStream)
+                       throws IOException {
+
+               if (inputStream.readBits(1) == 0)
+                       return inputStream.readBits(8);
+               else
+                       return inputStream.readBits(32);
+       }
+
        int width, height;
-       Image image;
 
+       Image image;
        byte[] decodedYRangeMap;
-       byte[] decodedYMap;
 
+       byte[] decodedYMap;
        byte[] decodedURangeMap;
-       byte[] decodedUMap;
 
+       byte[] decodedUMap;
        byte[] decodedVRangeMap;
+
        byte[] decodedVMap;
 
        Color tmpColor = new Color();
-
        Approximator approximator;
-       BitInputStream bitInputStream;
 
+       BitInputStream bitInputStream;
        ColorStats colorStats = new ColorStats();
+
        OperatingContext context = new OperatingContext();
 
        public ImageDecoder(final Image image, final BitInputStream bitInputStream) {
@@ -91,15 +101,13 @@ public class ImageDecoder {
                // detect initial step
                int largestDimension;
                int initialStep = 2;
-               if (width > height) {
+               if (width > height)
                        largestDimension = width;
-               } else {
+               else
                        largestDimension = height;
-               }
 
-               while (initialStep < largestDimension) {
+               while (initialStep < largestDimension)
                        initialStep = initialStep * 2;
-               }
 
                grid(initialStep, pixels);
        }
@@ -110,15 +118,14 @@ public class ImageDecoder {
                gridSquare(step / 2, 0, step, pixels);
                gridSquare(0, step / 2, step, pixels);
 
-               if (step > 2) {
+               if (step > 2)
                        grid(step / 2, pixels);
-               }
        }
 
        public void gridDiagonal(final int offsetX, final int offsetY,
                        final int step, final byte[] pixels) throws IOException {
 
-               for (int y = offsetY; y < height; y = y + step) {
+               for (int y = offsetY; y < height; y = y + step)
                        for (int x = offsetX; x < width; x = x + step) {
 
                                final int halfStep = step / 2;
@@ -135,13 +142,12 @@ public class ImageDecoder {
                                                context.colorStats.getAverageV());
 
                        }
-               }
        }
 
        public void gridSquare(final int offsetX, final int offsetY,
                        final int step, final byte[] pixels) throws IOException {
 
-               for (int y = offsetY; y < height; y = y + step) {
+               for (int y = offsetY; y < height; y = y + step)
                        for (int x = offsetX; x < width; x = x + step) {
 
                                final int halfStep = step / 2;
@@ -158,7 +164,6 @@ public class ImageDecoder {
                                                context.colorStats.getAverageV());
 
                        }
-               }
        }
 
        private int loadChannel(final byte[] decodedRangeMap,
@@ -176,9 +181,8 @@ public class ImageDecoder {
                if (bitCount > 0) {
 
                        final int rangeDecreases = bitInputStream.readBits(1);
-                       if (rangeDecreases != 0) {
+                       if (rangeDecreases != 0)
                                computedRange = table.proposeDecreasedRange(inheritedRange);
-                       }
 
                        decodedRangeMap[index] = (byte) computedRange;
                        computedRangeBitCount = table
@@ -194,16 +198,13 @@ public class ImageDecoder {
                                                                computedRange, computedRangeBitCount);
 
                                decodedValue = averageDecodedValue - decodedDifference;
-                               if (decodedValue > 255) {
+                               if (decodedValue > 255)
                                        decodedValue = 255;
-                               }
-                               if (decodedValue < 0) {
+                               if (decodedValue < 0)
                                        decodedValue = 0;
-                               }
                        }
-               } else {
+               } else
                        decodedRangeMap[index] = (byte) inheritedRange;
-               }
                decodedMap[index] = (byte) decodedValue;
                return decodedValue;
        }
@@ -219,17 +220,15 @@ public class ImageDecoder {
 
                int parentIndex;
                if (offsetX > 0) {
-                       if (offsetY > 0) {
+                       if (offsetY > 0)
                                // diagonal approach
                                parentIndex = ((y - halfStep) * width) + (x - halfStep);
-                       } else {
+                       else
                                // take left pixel
                                parentIndex = (y * width) + (x - halfStep);
-                       }
-               } else {
+               } else
                        // take upper pixel
                        parentIndex = ((y - halfStep) * width) + x;
-               }
 
                final int colorBufferIndex = index * 3;
 
index 7e8af8d..5b0e8db 100755 (executable)
@@ -1,7 +1,7 @@
 /*
  * 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.
@@ -21,21 +21,114 @@ import eu.svjatoslav.commons.data.BitOutputStream;
 
 public class ImageEncoder {
 
+       public static int byteToInt(final byte input) {
+               int result = input;
+               if (result < 0)
+                       result = result + 256;
+               return result;
+       }
+
+       public static int decodeValueFromGivenBits(final int encodedBits,
+                       final int range, final int bitCount) {
+               final int negativeBit = encodedBits & 1;
+
+               final int remainingBitCount = bitCount - 1;
+
+               if (remainingBitCount == 0) {
+                       // no more bits remaining to encode actual value
+
+                       if (negativeBit == 0)
+                               return range;
+                       else
+                               return -range;
+
+               } else {
+                       // still one or more bits left, encode value as precisely as
+                       // possible
+
+                       final int encodedValue = (encodedBits >>> 1) + 1;
+
+                       final int realvalueForThisBitcount = 1 << remainingBitCount;
+
+                       // int valueMultiplier = range / realvalueForThisBitcount;
+                       int decodedValue = (range * encodedValue)
+                                       / realvalueForThisBitcount;
+
+                       if (decodedValue > range)
+                               decodedValue = range;
+
+                       if (negativeBit == 0)
+                               return decodedValue;
+                       else
+                               return -decodedValue;
+
+               }
+       }
+
+       public static int encodeValueIntoGivenBits(int value, final int range,
+                       final int bitCount) {
+
+               int negativeBit = 0;
+
+               if (value < 0) {
+                       negativeBit = 1;
+                       value = -value;
+               }
+
+               final int remainingBitCount = bitCount - 1;
+
+               if (remainingBitCount == 0)
+                       return negativeBit;
+               else {
+                       // still one or more bits left, encode value as precisely as
+                       // possible
+
+                       if (value > range)
+                               value = range;
+
+                       final int realvalueForThisBitcount = 1 << remainingBitCount;
+                       // int valueMultiplier = range / realvalueForThisBitcount;
+                       int encodedValue = (value * realvalueForThisBitcount) / range;
+
+                       if (encodedValue >= realvalueForThisBitcount)
+                               encodedValue = realvalueForThisBitcount - 1;
+
+                       encodedValue = (encodedValue << 1) + negativeBit;
+
+                       return encodedValue;
+               }
+       }
+
+       public static void storeIntegerCompressed8(
+                       final BitOutputStream outputStream, final int data)
+                       throws IOException {
+
+               if (data < 256) {
+                       outputStream.storeBits(0, 1);
+                       outputStream.storeBits(data, 8);
+               } else {
+                       outputStream.storeBits(1, 1);
+                       outputStream.storeBits(data, 32);
+               }
+       }
+
        Image image;
        int width, height;
 
        Channel yChannel;
+
        Channel uChannel;
        Channel vChannel;
-
        Approximator approximator;
 
        int bitsForY;
        int bitsForU;
+
        int bitsForV;
 
        // ColorStats colorStats = new ColorStats();
        OperatingContext context = new OperatingContext();
+
        OperatingContext context2 = new OperatingContext();
 
        BitOutputStream bitOutputStream;
@@ -64,47 +157,41 @@ public class ImageEncoder {
                final DataBufferByte dbi = (DataBufferByte) raster.getDataBuffer();
                final byte[] pixels = dbi.getData();
 
-               if (yChannel == null) {
+               if (yChannel == null)
                        yChannel = new Channel(width, height);
-               } else {
+               else
                        yChannel.reset();
-               }
 
-               if (uChannel == null) {
+               if (uChannel == null)
                        uChannel = new Channel(width, height);
-               } else {
+               else
                        uChannel.reset();
-               }
 
-               if (vChannel == null) {
+               if (vChannel == null)
                        vChannel = new Channel(width, height);
-               } else {
+               else
                        vChannel.reset();
-               }
 
                // create YUV map out of RGB raster data
                final Color color = new Color();
 
-               for (int y = 0; y < height; y++) {
+               for (int y = 0; y < height; y++)
                        for (int x = 0; x < width; x++) {
 
                                final int index = (y * width) + x;
                                final int colorBufferIndex = index * 3;
 
                                int blue = pixels[colorBufferIndex];
-                               if (blue < 0) {
+                               if (blue < 0)
                                        blue = blue + 256;
-                               }
 
                                int green = pixels[colorBufferIndex + 1];
-                               if (green < 0) {
+                               if (green < 0)
                                        green = green + 256;
-                               }
 
                                int red = pixels[colorBufferIndex + 2];
-                               if (red < 0) {
+                               if (red < 0)
                                        red = red + 256;
-                               }
 
                                color.r = red;
                                color.g = green;
@@ -116,7 +203,6 @@ public class ImageEncoder {
                                uChannel.map[index] = (byte) color.u;
                                vChannel.map[index] = (byte) color.v;
                        }
-               }
 
                yChannel.decodedMap[0] = yChannel.map[0];
                uChannel.decodedMap[0] = uChannel.map[0];
@@ -129,15 +215,13 @@ public class ImageEncoder {
                // detect initial step
                int largestDimension;
                int initialStep = 2;
-               if (width > height) {
+               if (width > height)
                        largestDimension = width;
-               } else {
+               else
                        largestDimension = height;
-               }
 
-               while (initialStep < largestDimension) {
+               while (initialStep < largestDimension)
                        initialStep = initialStep * 2;
-               }
 
                rangeGrid(initialStep);
                rangeRoundGrid(2);
@@ -162,13 +246,12 @@ public class ImageEncoder {
                        decodedRangeMap[index] = (byte) computedRange;
 
                        channel.bitCount++;
-                       if (computedRange != inheritedRange) {
+                       if (computedRange != inheritedRange)
                                // brightness range shrinked
                                bitOutputStream.storeBits(1, 1);
-                       } else {
+                       else
                                // brightness range stayed the same
                                bitOutputStream.storeBits(0, 1);
-                       }
 
                        // encode brightness into available amount of bits
                        final int computedBitCount = table
@@ -187,17 +270,14 @@ public class ImageEncoder {
                                final int decodedDifference = decodeValueFromGivenBits(
                                                bitEncodedDifference, computedRange, computedBitCount);
                                int decodedValue = averageDecodedValue - decodedDifference;
-                               if (decodedValue > 255) {
+                               if (decodedValue > 255)
                                        decodedValue = 255;
-                               }
-                               if (decodedValue < 0) {
+                               if (decodedValue < 0)
                                        decodedValue = 0;
-                               }
 
                                decodedMap[index] = (byte) decodedValue;
-                       } else {
+                       } else
                                decodedMap[index] = (byte) averageDecodedValue;
-                       }
 
                } else {
                        decodedRangeMap[index] = (byte) inheritedRange;
@@ -224,14 +304,13 @@ public class ImageEncoder {
                rangeGridSquare(step / 2, 0, step);
                rangeGridSquare(0, step / 2, step);
 
-               if (step > 2) {
+               if (step > 2)
                        rangeGrid(step / 2);
-               }
        }
 
        public void rangeGridDiagonal(final int offsetX, final int offsetY,
                        final int step) {
-               for (int y = offsetY; y < height; y = y + step) {
+               for (int y = offsetY; y < height; y = y + step)
                        for (int x = offsetX; x < width; x = x + step) {
 
                                final int index = (y * width) + x;
@@ -249,12 +328,11 @@ public class ImageEncoder {
                                uChannel.rangeMap[index] = (byte) context.getURange(index);
                                vChannel.rangeMap[index] = (byte) context.getVRange(index);
                        }
-               }
        }
 
        public void rangeGridSquare(final int offsetX, final int offsetY,
                        final int step) {
-               for (int y = offsetY; y < height; y = y + step) {
+               for (int y = offsetY; y < height; y = y + step)
                        for (int x = offsetX; x < width; x = x + step) {
 
                                final int index = (y * width) + x;
@@ -272,7 +350,6 @@ public class ImageEncoder {
                                uChannel.rangeMap[index] = (byte) context.getURange(index);
                                vChannel.rangeMap[index] = (byte) context.getVRange(index);
                        }
-               }
        }
 
        public void rangeRoundGrid(final int step) {
@@ -281,14 +358,13 @@ public class ImageEncoder {
                rangeRoundGridSquare(step / 2, 0, step);
                rangeRoundGridSquare(0, step / 2, step);
 
-               if (step < 1024) {
+               if (step < 1024)
                        rangeRoundGrid(step * 2);
-               }
        }
 
        public void rangeRoundGridDiagonal(final int offsetX, final int offsetY,
                        final int step) {
-               for (int y = offsetY; y < height; y = y + step) {
+               for (int y = offsetY; y < height; y = y + step)
                        for (int x = offsetX; x < width; x = x + step) {
 
                                final int index = (y * width) + x;
@@ -323,12 +399,11 @@ public class ImageEncoder {
                                        vChannel.rangeMap[parentIndex] = (byte) parentVRange;
                                }
                        }
-               }
        }
 
        public void rangeRoundGridSquare(final int offsetX, final int offsetY,
                        final int step) {
-               for (int y = offsetY; y < height; y = y + step) {
+               for (int y = offsetY; y < height; y = y + step)
                        for (int x = offsetX; x < width; x = x + step) {
 
                                final int index = (y * width) + x;
@@ -340,11 +415,10 @@ public class ImageEncoder {
                                final int halfStep = step / 2;
 
                                int parentIndex;
-                               if (offsetX > 0) {
+                               if (offsetX > 0)
                                        parentIndex = (y * width) + (x - halfStep);
-                               } else {
+                               else
                                        parentIndex = ((y - halfStep) * width) + x;
-                               }
 
                                int parentYRange = byteToInt(yChannel.rangeMap[parentIndex]);
 
@@ -368,7 +442,6 @@ public class ImageEncoder {
                                }
 
                        }
-               }
        }
 
        public void saveGrid(final int step) throws IOException {
@@ -377,14 +450,13 @@ public class ImageEncoder {
                saveGridSquare(step / 2, 0, step);
                saveGridSquare(0, step / 2, step);
 
-               if (step > 2) {
+               if (step > 2)
                        saveGrid(step / 2);
-               }
        }
 
        public void saveGridDiagonal(final int offsetX, final int offsetY,
                        final int step) throws IOException {
-               for (int y = offsetY; y < height; y = y + step) {
+               for (int y = offsetY; y < height; y = y + step)
                        for (int x = offsetX; x < width; x = x + step) {
 
                                final int halfStep = step / 2;
@@ -402,12 +474,11 @@ public class ImageEncoder {
                                                context2.colorStats.getAverageV());
 
                        }
-               }
        }
 
        public void saveGridSquare(final int offsetX, final int offsetY,
                        final int step) throws IOException {
-               for (int y = offsetY; y < height; y = y + step) {
+               for (int y = offsetY; y < height; y = y + step)
                        for (int x = offsetX; x < width; x = x + step) {
 
                                final int halfStep = step / 2;
@@ -425,7 +496,6 @@ public class ImageEncoder {
                                                context2.colorStats.getAverageV());
 
                        }
-               }
        }
 
        public void savePixel(final int step, final int offsetX, final int offsetY,
@@ -447,17 +517,15 @@ public class ImageEncoder {
 
                int parentIndex;
                if (offsetX > 0) {
-                       if (offsetY > 0) {
+                       if (offsetY > 0)
                                // diagonal approach
                                parentIndex = ((y - halfStep) * width) + (x - halfStep);
-                       } else {
+                       else
                                // take left pixel
                                parentIndex = (y * width) + (x - halfStep);
-                       }
-               } else {
+               } else
                        // take upper pixel
                        parentIndex = ((y - halfStep) * width) + x;
-               }
 
                encodeChannel(approximator.yTable, yChannel, averageDecodedY, index,
                                py, yRange, parentIndex);
@@ -470,91 +538,4 @@ public class ImageEncoder {
 
        }
 
-       public static int byteToInt(final byte input) {
-               int result = input;
-               if (result < 0) {
-                       result = result + 256;
-               }
-               return result;
-       }
-
-       public static int decodeValueFromGivenBits(final int encodedBits,
-                       final int range, final int bitCount) {
-               final int negativeBit = encodedBits & 1;
-
-               final int remainingBitCount = bitCount - 1;
-
-               if (remainingBitCount == 0) {
-                       // no more bits remaining to encode actual value
-
-                       if (negativeBit == 0) {
-                               return range;
-                       } else {
-                               return -range;
-                       }
-
-               } else {
-                       // still one or more bits left, encode value as precisely as
-                       // possible
-
-                       final int encodedValue = (encodedBits >>> 1) + 1;
-
-                       final int realvalueForThisBitcount = 1 << remainingBitCount;
-
-                       // int valueMultiplier = range / realvalueForThisBitcount;
-                       int decodedValue = (range * encodedValue)
-                                       / realvalueForThisBitcount;
-
-                       if (decodedValue > range) {
-                               decodedValue = range;
-                       }
-
-                       if (negativeBit == 0) {
-                               return decodedValue;
-                       } else {
-                               return -decodedValue;
-                       }
-
-               }
-       }
-
-       public static int encodeValueIntoGivenBits(int value, final int range,
-                       final int bitCount) {
-
-               int negativeBit = 0;
-
-               if (value < 0) {
-                       negativeBit = 1;
-                       value = -value;
-               }
-
-               final int remainingBitCount = bitCount - 1;
-
-               if (remainingBitCount == 0) {
-                       // no more bits remaining to encode actual value
-
-                       return negativeBit;
-
-               } else {
-                       // still one or more bits left, encode value as precisely as
-                       // possible
-
-                       if (value > range) {
-                               value = range;
-                       }
-
-                       final int realvalueForThisBitcount = 1 << remainingBitCount;
-                       // int valueMultiplier = range / realvalueForThisBitcount;
-                       int encodedValue = (value * realvalueForThisBitcount) / range;
-
-                       if (encodedValue >= realvalueForThisBitcount) {
-                               encodedValue = realvalueForThisBitcount - 1;
-                       }
-
-                       encodedValue = (encodedValue << 1) + negativeBit;
-
-                       return encodedValue;
-               }
-       }
-
 }
index 4b21a22..49e9000 100755 (executable)
@@ -1,7 +1,7 @@
 /*
  * 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.
@@ -11,7 +11,7 @@ package eu.svjatoslav.imagesqueeze.codec;
 
 /**
  * Class to hold image metadata.
- * Like image dimensions, header version, compression quality, etc.. 
+ * Like image dimensions, header version, compression quality, etc..
  */
 
 import java.io.IOException;
@@ -26,19 +26,15 @@ public class ImageMetaData {
        int height;
 
        public void load(final BitInputStream inputStream) throws IOException {
-
                version = inputStream.readBits(16);
-               width = inputStream.readIntegerCompressed8();
-               height = inputStream.readIntegerCompressed8();
-
+               width = ImageDecoder.readIntegerCompressed8(inputStream);
+               height = ImageDecoder.readIntegerCompressed8(inputStream);
        }
 
        public void save(final BitOutputStream outputStream) throws IOException {
-
                outputStream.storeBits(version, 16);
-               outputStream.storeIntegerCompressed8(width);
-               outputStream.storeIntegerCompressed8(height);
-
+               ImageEncoder.storeIntegerCompressed8(outputStream, width);
+               ImageEncoder.storeIntegerCompressed8(outputStream, height);
        }
 
 }
index 33637d7..4e6e638 100755 (executable)
@@ -1,7 +1,7 @@
 /*
  * 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.
@@ -94,15 +94,13 @@ public class Table implements Comparable<Table> {
 
                for (int i = 0; i < 256; i++) {
 
-                       if (range[currentCheckPointer] == i) {
+                       if (range[currentCheckPointer] == i)
                                currentCheckPointer++;
-                       }
 
-                       if (currentCheckPointer > 0) {
+                       if (currentCheckPointer > 0)
                                bitCountForRange[i] = bitcount[currentCheckPointer - 1];
-                       } else {
+                       else
                                bitCountForRange[i] = 0;
-                       }
 
                }
 
@@ -110,20 +108,16 @@ public class Table implements Comparable<Table> {
 
                        int seek;
                        seekLoop: {
-                               for (seek = 0; seek < usedEntries; seek++) {
-
+                               for (seek = 0; seek < usedEntries; seek++)
                                        if (switchTreshold[seek] >= i)
                                                break seekLoop;
-
-                               }
                        }
 
                        proposedRangeForActualRange[i] = range[seek];
-                       if (seek == 0) {
+                       if (seek == 0)
                                proposedRangeForActualRangeLow[i] = 0;
-                       } else {
+                       else
                                proposedRangeForActualRangeLow[i] = switchTreshold[seek - 1] + 1;
-                       }
                        proposedRangeForActualRangeHigh[i] = switchTreshold[seek];
                }
 
@@ -132,11 +126,10 @@ public class Table implements Comparable<Table> {
                        if (range[currentCheckPointer] == i)
                                currentCheckPointer--;
 
-                       if (currentCheckPointer < 0) {
+                       if (currentCheckPointer < 0)
                                proposedDecreasedRange[i] = 0;
-                       } else {
+                       else
                                proposedDecreasedRange[i] = (byte) (range[currentCheckPointer]);
-                       }
                }
 
        }
@@ -144,12 +137,12 @@ public class Table implements Comparable<Table> {
        public void load(final BitInputStream inputStream) throws IOException {
                reset();
 
-               final int availableEntries = inputStream.readIntegerCompressed8();
+               final int availableEntries = ImageDecoder
+                               .readIntegerCompressed8(inputStream);
 
-               for (int i = 0; i < availableEntries; i++) {
+               for (int i = 0; i < availableEntries; i++)
                        addEntry(inputStream.readBits(8), inputStream.readBits(8),
                                        inputStream.readBits(4));
-               }
        }
 
        public int proposeBitcountForRange(int range) {
@@ -177,9 +170,8 @@ public class Table implements Comparable<Table> {
                if (inheritedRange < 0)
                        inheritedRange = 0;
 
-               if (proposedRangeForActualRangeLow[inheritedRange] <= actualRange) {
+               if (proposedRangeForActualRangeLow[inheritedRange] <= actualRange)
                        return inheritedRange;
-               }
 
                return proposeDecreasedRange(inheritedRange);
        }
@@ -199,7 +191,7 @@ public class Table implements Comparable<Table> {
        }
 
        public void save(final BitOutputStream outputStream) throws IOException {
-               outputStream.storeIntegerCompressed8(usedEntries);
+               ImageEncoder.storeIntegerCompressed8(outputStream, usedEntries);
 
                for (int i = 0; i < usedEntries; i++) {
                        outputStream.storeBits(range[i], 8);