From: Svjatoslav Agejenko Date: Sat, 25 Jun 2016 20:02:28 +0000 (+0200) Subject: Moved to java 1.8. Code cleanup and formatting. X-Git-Url: http://www2.svjatoslav.eu/gitweb/?a=commitdiff_plain;h=7b3e2cbabc6df4010fb50b129933ad91ada21e62;p=imagesqueeze.git Moved to java 1.8. Code cleanup and formatting. --- diff --git a/.gitignore b/.gitignore index 637d4dd..c2748b1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ -bin/ -target/ -.settings/ +/bin/ +/target/ +/.settings/ /.project /.classpath +/.idea/ diff --git a/doc/index.html b/doc/index.html index ad87c30..410d44e 100644 --- a/doc/index.html +++ b/doc/index.html @@ -1,18 +1,18 @@ - -ImageSqueeze + + ImageSqueeze -

ImageSqueeze - lossy image codec

- Download -    - Online homepage -    - Other applications hosted on svjatoslav.eu +

ImageSqueeze - lossy image codec

+Download +   +Online homepage +   +Other applications hosted on svjatoslav.eu
 Program author:
     Svjatoslav Agejenko
@@ -36,7 +36,7 @@ Current limitations / to do:
 
 
 Below are original photo and the same image being compressed down to ~93 Kb and then decompressed.
-
+
 
 When looking very closely, slight grainyness, loss of color precision and
 blurriness (loss of detail) could be noticed as a compression artifacts.
diff --git a/imagesqueeze.iml b/imagesqueeze.iml
new file mode 100644
index 0000000..6a36d37
--- /dev/null
+++ b/imagesqueeze.iml
@@ -0,0 +1,15 @@
+
+
+  
+    
+    
+    
+      
+      
+      
+    
+    
+    
+    
+  
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 8655494..8705ab2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,7 +1,7 @@
 
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xmlns="http://maven.apache.org/POM/4.0.0"
+        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     4.0.0
     eu.svjatoslav
     imagesqueeze
@@ -39,8 +39,8 @@
                 maven-compiler-plugin
                 2.3.1
                 
-                    1.6
-                    1.6
+                    1.8
+                    1.8
                     true
                     UTF-8
                 
@@ -88,8 +88,8 @@
         
             
                 org.apache.maven.wagon
-                wagon-ssh
-                2.2
+                wagon-ssh-external
+                2.6
             
         
     
@@ -102,6 +102,19 @@
         
     
 
+    
+        
+            svjatoslav.eu
+            svjatoslav.eu
+            scpexe://svjatoslav.eu/var/www/svjatoslav.eu/maven
+        
+        
+            svjatoslav.eu
+            svjatoslav.eu
+            scpexe://svjatoslav.eu/var/www/svjatoslav.eu/maven
+        
+    
+
     
         
             svjatoslav.eu
@@ -110,13 +123,10 @@
         
     
 
-
-    
-        
-            svjatoslav.eu
-            svjatoslav.eu
-            scp://svjatoslav.eu:7022/var/www/maven
-        
-    
+    
+        scm:git:ssh://git@svjatoslav.eu/home/git/repositories/imagesqueeze.git
+        scm:git:ssh://git@svjatoslav.eu/home/git/repositories/imagesqueeze.git
+        
+    
 
 
diff --git a/src/main/java/eu/svjatoslav/imagesqueeze/codec/Approximator.java b/src/main/java/eu/svjatoslav/imagesqueeze/codec/Approximator.java
index 0f3857b..355cb76 100755
--- a/src/main/java/eu/svjatoslav/imagesqueeze/codec/Approximator.java
+++ b/src/main/java/eu/svjatoslav/imagesqueeze/codec/Approximator.java
@@ -9,77 +9,62 @@
 
 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;
+
 /**
  * Since it is a lossy codec, instead of storing exact values, approximated
  * values are stored to save on bit count.
  */
 
-public class Approximator implements Comparable {
-
-	public Table yTable = new Table();
-	public Table uTable = new Table();
-	public Table vTable = new Table();
-
-	public Approximator() {
-	}
-
-	@Override
-	public int compareTo(final Approximator o) {
-		int result = yTable.compareTo(o.yTable);
-		if (result != 0) {
-			return result;
-		}
-
-		result = uTable.compareTo(o.uTable);
-		if (result != 0) {
-			return result;
-		}
-
-		result = vTable.compareTo(o.vTable);
-		return result;
-	}
-
-	public void computeLookupTables() {
-		yTable.computeLookupTables();
-		uTable.computeLookupTables();
-		vTable.computeLookupTables();
-	}
-
-	public void initialize() {
-		yTable.reset();
-		uTable.reset();
-		vTable.reset();
-
-		yTable.addEntry(0, 6, 0);
-		yTable.addEntry(27, 30, 4);
-		yTable.addEntry(255, 255, 6);
-
-		uTable.addEntry(0, 9, 0);
-		uTable.addEntry(27, 30, 4);
-		uTable.addEntry(255, 255, 6);
-
-		vTable.addEntry(0, 9, 0);
-		vTable.addEntry(27, 30, 4);
-		vTable.addEntry(255, 255, 6);
-
-		computeLookupTables();
-	}
-
-	public void load(final BitInputStream inputStream) throws IOException {
-		yTable.load(inputStream);
-		uTable.load(inputStream);
-		vTable.load(inputStream);
-	}
-
-	public void save(final BitOutputStream outputStream) throws IOException {
-		yTable.save(outputStream);
-		uTable.save(outputStream);
-		vTable.save(outputStream);
-	}
+class Approximator {
+
+    public final Table yTable = new Table();
+    public final Table uTable = new Table();
+    public final Table vTable = new Table();
+
+    public Approximator() {
+    }
+
+
+    public void computeLookupTables() {
+        yTable.computeLookupTables();
+        uTable.computeLookupTables();
+        vTable.computeLookupTables();
+    }
+
+    public void initialize() {
+        yTable.reset();
+        uTable.reset();
+        vTable.reset();
+
+        yTable.addEntry(0, 6, 0);
+        yTable.addEntry(27, 30, 4);
+        yTable.addEntry(255, 255, 6);
+
+        uTable.addEntry(0, 9, 0);
+        uTable.addEntry(27, 30, 4);
+        uTable.addEntry(255, 255, 6);
+
+        vTable.addEntry(0, 9, 0);
+        vTable.addEntry(27, 30, 4);
+        vTable.addEntry(255, 255, 6);
+
+        computeLookupTables();
+    }
+
+    public void load(final BitInputStream inputStream) throws IOException {
+        yTable.load(inputStream);
+        uTable.load(inputStream);
+        vTable.load(inputStream);
+    }
+
+    public void save(final BitOutputStream outputStream) throws IOException {
+        yTable.save(outputStream);
+        uTable.save(outputStream);
+        vTable.save(outputStream);
+    }
 
 }
diff --git a/src/main/java/eu/svjatoslav/imagesqueeze/codec/Channel.java b/src/main/java/eu/svjatoslav/imagesqueeze/codec/Channel.java
index a4f01cc..b5f5fcf 100755
--- a/src/main/java/eu/svjatoslav/imagesqueeze/codec/Channel.java
+++ b/src/main/java/eu/svjatoslav/imagesqueeze/codec/Channel.java
@@ -9,53 +9,53 @@
 
 package eu.svjatoslav.imagesqueeze.codec;
 
-public class Channel {
+class Channel {
 
-	byte[] rangeMap;
-	byte[] map;
+    final byte[] rangeMap;
+    final byte[] map;
 
-	byte[] decodedRangeMap;
-	byte[] decodedMap;
+    final byte[] decodedRangeMap;
+    final byte[] decodedMap;
 
-	int bitCount;
+    int bitCount;
 
-	public Channel(final int width, final int height) {
-		rangeMap = new byte[width * height];
+    public Channel(final int width, final int height) {
+        rangeMap = new byte[width * height];
 
-		map = new byte[width * height];
+        map = new byte[width * height];
 
-		decodedRangeMap = new byte[width * height];
-		decodedRangeMap[0] = (byte) 255;
+        decodedRangeMap = new byte[width * height];
+        decodedRangeMap[0] = (byte) 255;
 
-		decodedMap = new byte[width * height];
-	};
+        decodedMap = new byte[width * height];
+    }
 
-	public void printStatistics() {
-		final float bitsPerPixel = (float) bitCount / (float) rangeMap.length;
-		System.out.println((bitCount / 8) + " bytes. " + bitsPerPixel
-				+ " bits per pixel.");
-	}
+    public void printStatistics() {
+        final float bitsPerPixel = (float) bitCount / (float) rangeMap.length;
+        System.out.println((bitCount / 8) + " bytes. " + bitsPerPixel
+                + " bits per pixel.");
+    }
 
-	public void reset() {
+    public void reset() {
 
-		for (int i = 0; i < decodedMap.length; i++) {
-			decodedMap[i] = 0;
-		}
+        for (int i = 0; i < decodedMap.length; i++) {
+            decodedMap[i] = 0;
+        }
 
-		for (int i = 0; i < decodedRangeMap.length; i++) {
-			decodedRangeMap[i] = 0;
-		}
-		decodedRangeMap[0] = (byte) 255;
+        for (int i = 0; i < decodedRangeMap.length; i++) {
+            decodedRangeMap[i] = 0;
+        }
+        decodedRangeMap[0] = (byte) 255;
 
-		for (int i = 0; i < map.length; i++) {
-			map[i] = 0;
-		}
+        for (int i = 0; i < map.length; i++) {
+            map[i] = 0;
+        }
 
-		for (int i = 0; i < rangeMap.length; i++) {
-			rangeMap[i] = 0;
-		}
+        for (int i = 0; i < rangeMap.length; i++) {
+            rangeMap[i] = 0;
+        }
 
-		bitCount = 0;
-	}
+        bitCount = 0;
+    }
 
 }
diff --git a/src/main/java/eu/svjatoslav/imagesqueeze/codec/Color.java b/src/main/java/eu/svjatoslav/imagesqueeze/codec/Color.java
index 08535a2..e1963bc 100755
--- a/src/main/java/eu/svjatoslav/imagesqueeze/codec/Color.java
+++ b/src/main/java/eu/svjatoslav/imagesqueeze/codec/Color.java
@@ -12,58 +12,58 @@ package eu.svjatoslav.imagesqueeze.codec;
 /**
  * Helper class to convert between RGB and YUV
  */
-public class Color {
+class Color {
 
-	int r;
-	int g;
-	int b;
+    int r;
+    int g;
+    int b;
 
-	int y;
-	int u;
-	int v;
+    int y;
+    int u;
+    int v;
 
-	public void RGB2YUV() {
+    public void RGB2YUV() {
 
-		y = (int) ((r * 0.299000) + (g * 0.587000) + (b * 0.114000));
-		u = (int) ((r * -0.168736) + (g * -0.331264) + (b * 0.500000) + 128);
-		v = (int) ((r * 0.500000) + (g * -0.418688) + (b * -0.081312) + 128);
+        y = (int) ((r * 0.299000) + (g * 0.587000) + (b * 0.114000));
+        u = (int) ((r * -0.168736) + (g * -0.331264) + (b * 0.500000) + 128);
+        v = (int) ((r * 0.500000) + (g * -0.418688) + (b * -0.081312) + 128);
 
-		if (y < 0)
-			y = 0;
-		if (u < 0)
-			u = 0;
-		if (v < 0)
-			v = 0;
+        if (y < 0)
+            y = 0;
+        if (u < 0)
+            u = 0;
+        if (v < 0)
+            v = 0;
 
-		if (y > 255)
-			y = 255;
-		if (u > 255)
-			u = 255;
-		if (v > 255)
-			v = 255;
+        if (y > 255)
+            y = 255;
+        if (u > 255)
+            u = 255;
+        if (v > 255)
+            v = 255;
 
-	}
+    }
 
-	public void YUV2RGB() {
+    public void YUV2RGB() {
 
-		b = (int) (y + (1.4075 * (v - 128)));
-		g = (int) (y - (0.3455 * (u - 128)) - (0.7169 * (v - 128)));
-		r = (int) (y + (1.7790 * (u - 128)));
+        b = (int) (y + (1.4075 * (v - 128)));
+        g = (int) (y - (0.3455 * (u - 128)) - (0.7169 * (v - 128)));
+        r = (int) (y + (1.7790 * (u - 128)));
 
-		if (r < 0)
-			r = 0;
-		if (g < 0)
-			g = 0;
-		if (b < 0)
-			b = 0;
+        if (r < 0)
+            r = 0;
+        if (g < 0)
+            g = 0;
+        if (b < 0)
+            b = 0;
 
-		if (r > 255)
-			r = 255;
-		if (g > 255)
-			g = 255;
-		if (b > 255)
-			b = 255;
+        if (r > 255)
+            r = 255;
+        if (g > 255)
+            g = 255;
+        if (b > 255)
+            b = 255;
 
-	}
+    }
 
-};
+}
diff --git a/src/main/java/eu/svjatoslav/imagesqueeze/codec/ColorStats.java b/src/main/java/eu/svjatoslav/imagesqueeze/codec/ColorStats.java
index 8d206cf..5095855 100755
--- a/src/main/java/eu/svjatoslav/imagesqueeze/codec/ColorStats.java
+++ b/src/main/java/eu/svjatoslav/imagesqueeze/codec/ColorStats.java
@@ -9,35 +9,35 @@
 
 package eu.svjatoslav.imagesqueeze.codec;
 
-public class ColorStats {
+class ColorStats {
 
-	int ySum;
-	int uSum;
-	int vSum;
+    int ySum;
+    int uSum;
+    int vSum;
 
-	int pixelCount;
+    int pixelCount;
 
-	public ColorStats() {
-		reset();
-	}
+    public ColorStats() {
+        reset();
+    }
 
-	public int getAverageU() {
-		return uSum / pixelCount;
-	}
+    public int getAverageU() {
+        return uSum / pixelCount;
+    }
 
-	public int getAverageV() {
-		return vSum / pixelCount;
-	}
+    public int getAverageV() {
+        return vSum / pixelCount;
+    }
 
-	public int getAverageY() {
-		return ySum / pixelCount;
-	}
+    public int getAverageY() {
+        return ySum / pixelCount;
+    }
 
-	public void reset() {
-		ySum = 0;
-		uSum = 0;
-		vSum = 0;
-		pixelCount = 0;
-	}
+    public void reset() {
+        ySum = 0;
+        uSum = 0;
+        vSum = 0;
+        pixelCount = 0;
+    }
 
 }
diff --git a/src/main/java/eu/svjatoslav/imagesqueeze/codec/Image.java b/src/main/java/eu/svjatoslav/imagesqueeze/codec/Image.java
index 6ba0d1b..256ac26 100755
--- a/src/main/java/eu/svjatoslav/imagesqueeze/codec/Image.java
+++ b/src/main/java/eu/svjatoslav/imagesqueeze/codec/Image.java
@@ -9,128 +9,120 @@
 
 package eu.svjatoslav.imagesqueeze.codec;
 
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
 import eu.svjatoslav.commons.data.BitInputStream;
 import eu.svjatoslav.commons.data.BitOutputStream;
 
+import java.awt.image.BufferedImage;
+import java.io.*;
+
 /**
  * Main class representing compressed image.
  */
 
 public class Image {
 
-	public ImageMetaData metaData;
-
-	public BufferedImage bufferedImage;
-
-	ImageEncoder encoder;
+    public ImageMetaData metaData;
 
-	public Image() {
-	};
+    public BufferedImage bufferedImage;
 
-	/**
-	 * Initialize imagesqueeze image based on {@link BufferedImage}.
-	 * {@link BufferedImage} must be of type BufferedImage.TYPE_3BYTE_BGR .
-	 */
-	public Image(final BufferedImage image) {
+    private ImageEncoder encoder;
 
-		bufferedImage = image;
-		metaData = new ImageMetaData();
+    public Image() {
+    }
 
-		metaData.version = 1;
-		metaData.width = image.getWidth();
-		metaData.height = image.getHeight();
-	}
+    /**
+     * Initialize imagesqueeze image based on {@link BufferedImage}.
+     * {@link BufferedImage} must be of type BufferedImage.TYPE_3BYTE_BGR .
+     */
+    public Image(final BufferedImage image) {
 
-	/**
-	 * Initialize empty imagesqueeze image.
-	 */
-	public Image(final int width, final int height) {
+        bufferedImage = image;
+        metaData = new ImageMetaData();
 
-		bufferedImage = new BufferedImage(width, height,
-				BufferedImage.TYPE_3BYTE_BGR);
-		metaData = new ImageMetaData();
+        metaData.version = 1;
+        metaData.width = image.getWidth();
+        metaData.height = image.getHeight();
+    }
 
-		metaData.version = 1;
-		metaData.width = width;
-		metaData.height = height;
-	}
+    /**
+     * Initialize empty imagesqueeze image.
+     */
+    public Image(final int width, final int height) {
 
-	/**
-	 * Load ImgSqz image from {@link File}.
-	 */
-	public void loadImage(final File source) throws IOException {
+        bufferedImage = new BufferedImage(width, height,
+                BufferedImage.TYPE_3BYTE_BGR);
+        metaData = new ImageMetaData();
 
-		final byte[] fileContent = new byte[(int) source.length()];
+        metaData.version = 1;
+        metaData.width = width;
+        metaData.height = height;
+    }
 
-		final FileInputStream fileInputStream = new FileInputStream(source);
+    /**
+     * Load ImgSqz image from {@link File}.
+     */
+    public void loadImage(final File source) throws IOException {
 
-		fileInputStream.read(fileContent);
+        final byte[] fileContent = new byte[(int) source.length()];
 
-		fileInputStream.close();
+        try (FileInputStream fileInputStream = new FileInputStream(source)) {
+            if (fileInputStream.read(fileContent) != fileContent.length)
+                throw new RuntimeException("Failed to read file content");
+        }
 
-		final ByteArrayInputStream inputStream = new ByteArrayInputStream(
-				fileContent);
+        final ByteArrayInputStream inputStream = new ByteArrayInputStream(
+                fileContent);
 
-		loadImage(inputStream);
-	}
+        loadImage(inputStream);
+    }
 
-	/**
-	 * Load ImgSqz image from {@link InputStream}.
-	 */
-	public void loadImage(final InputStream source) throws IOException {
-		final BitInputStream bitInputStream = new BitInputStream(source);
+    /**
+     * Load ImgSqz image from {@link InputStream}.
+     */
+    public void loadImage(final InputStream source) throws IOException {
+        final BitInputStream bitInputStream = new BitInputStream(source);
 
-		metaData = new ImageMetaData();
-		metaData.load(bitInputStream);
+        metaData = new ImageMetaData();
+        metaData.load(bitInputStream);
 
-		bufferedImage = new BufferedImage(metaData.width, metaData.height,
-				BufferedImage.TYPE_3BYTE_BGR);
+        bufferedImage = new BufferedImage(metaData.width, metaData.height,
+                BufferedImage.TYPE_3BYTE_BGR);
 
-		final ImageDecoder imageDecoder = new ImageDecoder(this, bitInputStream);
+        final ImageDecoder imageDecoder = new ImageDecoder(this, bitInputStream);
 
-		imageDecoder.decode();
-	}
+        imageDecoder.decode();
+    }
 
-	/**
-	 * Save image into ImgSqz file format.
-	 */
-	public void saveImage(final File file) throws IOException {
-		final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-		saveImage(outputStream);
+    /**
+     * Save image into ImgSqz file format.
+     */
+    public void saveImage(final File file) throws IOException {
+        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        saveImage(outputStream);
 
-		final byte[] buffer = outputStream.toByteArray();
-		final FileOutputStream fileOutputStream = new FileOutputStream(file);
-		fileOutputStream.write(buffer);
-		fileOutputStream.close();
-	}
+        final byte[] buffer = outputStream.toByteArray();
+        try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
+            fileOutputStream.write(buffer);
+        }
+    }
 
-	/**
-	 * Save image into ImgSqz file format.
-	 */
-	public void saveImage(final OutputStream outputStream) throws IOException {
+    /**
+     * Save image into ImgSqz file format.
+     */
+    private void saveImage(final OutputStream outputStream) throws IOException {
 
-		final BitOutputStream bitOutputStream = new BitOutputStream(
-				outputStream);
+        final BitOutputStream bitOutputStream = new BitOutputStream(
+                outputStream);
 
-		metaData.save(bitOutputStream);
+        metaData.save(bitOutputStream);
 
-		if (encoder == null) {
-			encoder = new ImageEncoder(this);
-		}
+        if (encoder == null) {
+            encoder = new ImageEncoder(this);
+        }
 
-		encoder.encode(bitOutputStream);
+        encoder.encode(bitOutputStream);
 
-		bitOutputStream.finishByte();
-	}
+        bitOutputStream.finishByte();
+    }
 
 }
diff --git a/src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageDecoder.java b/src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageDecoder.java
index 53f2d91..24c1e27 100755
--- a/src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageDecoder.java
+++ b/src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageDecoder.java
@@ -13,239 +13,231 @@ package eu.svjatoslav.imagesqueeze.codec;
  * Compressed image pixels decoder.
  */
 
+import eu.svjatoslav.commons.data.BitInputStream;
+
 import java.awt.image.DataBufferByte;
 import java.awt.image.WritableRaster;
 import java.io.IOException;
 
-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;
-	byte[] decodedYRangeMap;
-
-	byte[] decodedYMap;
-	byte[] decodedURangeMap;
-
-	byte[] decodedUMap;
-	byte[] decodedVRangeMap;
-
-	byte[] decodedVMap;
-
-	Color tmpColor = new Color();
-	Approximator approximator;
-
-	BitInputStream bitInputStream;
-	ColorStats colorStats = new ColorStats();
-
-	OperatingContext context = new OperatingContext();
-
-	public ImageDecoder(final Image image, final BitInputStream bitInputStream) {
-		approximator = new Approximator();
-
-		this.image = image;
-		this.bitInputStream = bitInputStream;
-
-		width = image.metaData.width;
-		height = image.metaData.height;
-
-		decodedYRangeMap = new byte[width * height];
-		decodedYRangeMap[0] = (byte) (255);
-		decodedYMap = new byte[width * height];
-
-		decodedURangeMap = new byte[width * height];
-		decodedURangeMap[0] = (byte) (255);
-		decodedUMap = new byte[width * height];
-
-		decodedVRangeMap = new byte[width * height];
-		decodedVRangeMap[0] = (byte) (255);
-		decodedVMap = new byte[width * height];
-
-	}
-
-	public void decode() throws IOException {
-		approximator.load(bitInputStream);
-		approximator.computeLookupTables();
-
-		final WritableRaster raster = image.bufferedImage.getRaster();
-		final DataBufferByte dbi = (DataBufferByte) raster.getDataBuffer();
-		final byte[] pixels = dbi.getData();
+class ImageDecoder {
 
-		// load top-, left-most pixel.
-		decodedYMap[0] = (byte) bitInputStream.readBits(8);
-		decodedUMap[0] = (byte) bitInputStream.readBits(8);
-		decodedVMap[0] = (byte) bitInputStream.readBits(8);
+    private final int width;
+    private final int height;
+    private final Image image;
+    private final byte[] decodedYRangeMap;
+    private final byte[] decodedYMap;
+    private final byte[] decodedURangeMap;
+    private final byte[] decodedUMap;
+    private final byte[] decodedVRangeMap;
+    private final byte[] decodedVMap;
+    private final Approximator approximator;
+    private final BitInputStream bitInputStream;
+    private final OperatingContext context = new OperatingContext();
 
-		final Color color = new Color();
-		color.y = ImageEncoder.byteToInt(decodedYMap[0]);
-		color.u = ImageEncoder.byteToInt(decodedUMap[0]);
-		color.v = ImageEncoder.byteToInt(decodedVMap[0]);
+    public ImageDecoder(final Image image, final BitInputStream bitInputStream) {
+        approximator = new Approximator();
 
-		color.YUV2RGB();
+        this.image = image;
+        this.bitInputStream = bitInputStream;
 
-		pixels[0] = (byte) color.r;
-		pixels[0 + 1] = (byte) color.g;
-		pixels[0 + 2] = (byte) color.b;
+        width = image.metaData.width;
+        height = image.metaData.height;
 
-		// detect initial step
-		int largestDimension;
-		int initialStep = 2;
-		if (width > height)
-			largestDimension = width;
-		else
-			largestDimension = height;
+        decodedYRangeMap = new byte[width * height];
+        decodedYRangeMap[0] = (byte) (255);
+        decodedYMap = new byte[width * height];
 
-		while (initialStep < largestDimension)
-			initialStep = initialStep * 2;
+        decodedURangeMap = new byte[width * height];
+        decodedURangeMap[0] = (byte) (255);
+        decodedUMap = new byte[width * height];
 
-		grid(initialStep, pixels);
-	}
+        decodedVRangeMap = new byte[width * height];
+        decodedVRangeMap[0] = (byte) (255);
+        decodedVMap = new byte[width * height];
 
-	public void grid(final int step, final byte[] pixels) throws IOException {
+    }
 
-		gridDiagonal(step / 2, step / 2, step, pixels);
-		gridSquare(step / 2, 0, step, pixels);
-		gridSquare(0, step / 2, step, pixels);
+    public static int readIntegerCompressed8(final BitInputStream inputStream)
+            throws IOException {
 
-		if (step > 2)
-			grid(step / 2, pixels);
-	}
+        if (inputStream.readBits(1) == 0)
+            return inputStream.readBits(8);
+        else
+            return inputStream.readBits(32);
+    }
 
-	public void gridDiagonal(final int offsetX, final int offsetY,
-			final int step, final byte[] pixels) throws IOException {
+    public void decode() throws IOException {
+        approximator.load(bitInputStream);
+        approximator.computeLookupTables();
 
-		for (int y = offsetY; y < height; y = y + step)
-			for (int x = offsetX; x < width; x = x + step) {
+        final WritableRaster raster = image.bufferedImage.getRaster();
+        final DataBufferByte dbi = (DataBufferByte) raster.getDataBuffer();
+        final byte[] pixels = dbi.getData();
 
-				final int halfStep = step / 2;
+        // load top-, left-most pixel.
+        decodedYMap[0] = (byte) bitInputStream.readBits(8);
+        decodedUMap[0] = (byte) bitInputStream.readBits(8);
+        decodedVMap[0] = (byte) bitInputStream.readBits(8);
 
-				context.initialize(image, decodedYMap, decodedUMap, decodedVMap);
-				context.measureNeighborEncode(x - halfStep, y - halfStep);
-				context.measureNeighborEncode(x + halfStep, y - halfStep);
-				context.measureNeighborEncode(x - halfStep, y + halfStep);
-				context.measureNeighborEncode(x + halfStep, y + halfStep);
+        final Color color = new Color();
+        color.y = ImageEncoder.byteToInt(decodedYMap[0]);
+        color.u = ImageEncoder.byteToInt(decodedUMap[0]);
+        color.v = ImageEncoder.byteToInt(decodedVMap[0]);
 
-				loadPixel(step, offsetX, offsetY, x, y, pixels,
-						context.colorStats.getAverageY(),
-						context.colorStats.getAverageU(),
-						context.colorStats.getAverageV());
+        color.YUV2RGB();
 
-			}
-	}
+        pixels[0] = (byte) color.r;
+        pixels[0 + 1] = (byte) color.g;
+        pixels[0 + 2] = (byte) color.b;
 
-	public void gridSquare(final int offsetX, final int offsetY,
-			final int step, final byte[] pixels) throws IOException {
+        // detect initial step
+        int largestDimension;
+        int initialStep = 2;
+        if (width > height)
+            largestDimension = width;
+        else
+            largestDimension = height;
+
+        while (initialStep < largestDimension)
+            initialStep = initialStep * 2;
 
-		for (int y = offsetY; y < height; y = y + step)
-			for (int x = offsetX; x < width; x = x + step) {
+        grid(initialStep, pixels);
+    }
+
+    private void grid(final int step, final byte[] pixels) throws IOException {
+
+        gridDiagonal(step / 2, step / 2, step, pixels);
+        gridSquare(step / 2, 0, step, pixels);
+        gridSquare(0, step / 2, step, pixels);
 
-				final int halfStep = step / 2;
-
-				context.initialize(image, decodedYMap, decodedUMap, decodedVMap);
-				context.measureNeighborEncode(x - halfStep, y);
-				context.measureNeighborEncode(x + halfStep, y);
-				context.measureNeighborEncode(x, y - halfStep);
-				context.measureNeighborEncode(x, y + halfStep);
-
-				loadPixel(step, offsetX, offsetY, x, y, pixels,
-						context.colorStats.getAverageY(),
-						context.colorStats.getAverageU(),
-						context.colorStats.getAverageV());
-
-			}
-	}
-
-	private int loadChannel(final byte[] decodedRangeMap,
-			final byte[] decodedMap, final Table table,
-			final int averageDecodedValue, final int index,
-			final int parentIndex) throws IOException {
-		int decodedValue = averageDecodedValue;
-
-		final int inheritedRange = ImageEncoder
-				.byteToInt(decodedRangeMap[parentIndex]);
-		int computedRange = inheritedRange;
-
-		final int bitCount = table.proposeBitcountForRange(inheritedRange);
-		int computedRangeBitCount = 0;
-		if (bitCount > 0) {
-
-			final int rangeDecreases = bitInputStream.readBits(1);
-			if (rangeDecreases != 0)
-				computedRange = table.proposeDecreasedRange(inheritedRange);
-
-			decodedRangeMap[index] = (byte) computedRange;
-			computedRangeBitCount = table
-					.proposeBitcountForRange(computedRange);
-
-			if (computedRangeBitCount > 0) {
-
-				final int encodedDifference = bitInputStream
-						.readBits(computedRangeBitCount);
-
-				final int decodedDifference = ImageEncoder
-						.decodeValueFromGivenBits(encodedDifference,
-								computedRange, computedRangeBitCount);
-
-				decodedValue = averageDecodedValue - decodedDifference;
-				if (decodedValue > 255)
-					decodedValue = 255;
-				if (decodedValue < 0)
-					decodedValue = 0;
-			}
-		} else
-			decodedRangeMap[index] = (byte) inheritedRange;
-		decodedMap[index] = (byte) decodedValue;
-		return decodedValue;
-	}
+        if (step > 2)
+            grid(step / 2, pixels);
+    }
+
+    private 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 x = offsetX; x < width; x = x + step) {
+
+                final int halfStep = step / 2;
+
+                context.initialize(image, decodedYMap, decodedUMap, decodedVMap);
+                context.measureNeighborEncode(x - halfStep, y - halfStep);
+                context.measureNeighborEncode(x + halfStep, y - halfStep);
+                context.measureNeighborEncode(x - halfStep, y + halfStep);
+                context.measureNeighborEncode(x + halfStep, y + halfStep);
+
+                loadPixel(step, offsetX, offsetY, x, y, pixels,
+                        context.colorStats.getAverageY(),
+                        context.colorStats.getAverageU(),
+                        context.colorStats.getAverageV());
+
+            }
+    }
+
+    private 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 x = offsetX; x < width; x = x + step) {
+
+                final int halfStep = step / 2;
+
+                context.initialize(image, decodedYMap, decodedUMap, decodedVMap);
+                context.measureNeighborEncode(x - halfStep, y);
+                context.measureNeighborEncode(x + halfStep, y);
+                context.measureNeighborEncode(x, y - halfStep);
+                context.measureNeighborEncode(x, y + halfStep);
+
+                loadPixel(step, offsetX, offsetY, x, y, pixels,
+                        context.colorStats.getAverageY(),
+                        context.colorStats.getAverageU(),
+                        context.colorStats.getAverageV());
+
+            }
+    }
+
+    private int loadChannel(final byte[] decodedRangeMap,
+                            final byte[] decodedMap, final Table table,
+                            final int averageDecodedValue, final int index,
+                            final int parentIndex) throws IOException {
+        int decodedValue = averageDecodedValue;
+
+        final int inheritedRange = ImageEncoder
+                .byteToInt(decodedRangeMap[parentIndex]);
+        int computedRange = inheritedRange;
+
+        final int bitCount = table.proposeBitcountForRange(inheritedRange);
+        int computedRangeBitCount;
+        if (bitCount > 0) {
+
+            final int rangeDecreases = bitInputStream.readBits(1);
+            if (rangeDecreases != 0)
+                computedRange = table.proposeDecreasedRange(inheritedRange);
+
+            decodedRangeMap[index] = (byte) computedRange;
+            computedRangeBitCount = table
+                    .proposeBitcountForRange(computedRange);
+
+            if (computedRangeBitCount > 0) {
+
+                final int encodedDifference = bitInputStream
+                        .readBits(computedRangeBitCount);
+
+                final int decodedDifference = ImageEncoder
+                        .decodeValueFromGivenBits(encodedDifference,
+                                computedRange, computedRangeBitCount);
+
+                decodedValue = averageDecodedValue - decodedDifference;
+                if (decodedValue > 255)
+                    decodedValue = 255;
+                if (decodedValue < 0)
+                    decodedValue = 0;
+            }
+        } else
+            decodedRangeMap[index] = (byte) inheritedRange;
+        decodedMap[index] = (byte) decodedValue;
+        return decodedValue;
+    }
 
-	public void loadPixel(final int step, final int offsetX, final int offsetY,
-			final int x, final int y, final byte[] pixels,
-			final int averageDecodedY, final int averageDecodedU,
-			final int averageDecodedV) throws IOException {
-
-		final int index = (y * width) + x;
-
-		final int halfStep = step / 2;
-
-		int parentIndex;
-		if (offsetX > 0) {
-			if (offsetY > 0)
-				// diagonal approach
-				parentIndex = ((y - halfStep) * width) + (x - halfStep);
-			else
-				// take left pixel
-				parentIndex = (y * width) + (x - halfStep);
-		} else
-			// take upper pixel
-			parentIndex = ((y - halfStep) * width) + x;
-
-		final int colorBufferIndex = index * 3;
-
-		final Color color = new Color();
-		color.y = loadChannel(decodedYRangeMap, decodedYMap,
-				approximator.yTable, averageDecodedY, index, parentIndex);
-		color.u = loadChannel(decodedURangeMap, decodedUMap,
-				approximator.uTable, averageDecodedU, index, parentIndex);
-		color.v = loadChannel(decodedVRangeMap, decodedVMap,
-				approximator.vTable, averageDecodedV, index, parentIndex);
-
-		color.YUV2RGB();
-
-		pixels[colorBufferIndex] = (byte) color.r;
-		pixels[colorBufferIndex + 1] = (byte) color.g;
-		pixels[colorBufferIndex + 2] = (byte) color.b;
-
-	}
+    private void loadPixel(final int step, final int offsetX, final int offsetY,
+                           final int x, final int y, final byte[] pixels,
+                           final int averageDecodedY, final int averageDecodedU,
+                           final int averageDecodedV) throws IOException {
+
+        final int index = (y * width) + x;
+
+        final int halfStep = step / 2;
+
+        int parentIndex;
+        if (offsetX > 0) {
+            if (offsetY > 0)
+                // diagonal approach
+                parentIndex = ((y - halfStep) * width) + (x - halfStep);
+            else
+                // take left pixel
+                parentIndex = (y * width) + (x - halfStep);
+        } else
+            // take upper pixel
+            parentIndex = ((y - halfStep) * width) + x;
+
+        final int colorBufferIndex = index * 3;
+
+        final Color color = new Color();
+        color.y = loadChannel(decodedYRangeMap, decodedYMap,
+                approximator.yTable, averageDecodedY, index, parentIndex);
+        color.u = loadChannel(decodedURangeMap, decodedUMap,
+                approximator.uTable, averageDecodedU, index, parentIndex);
+        color.v = loadChannel(decodedVRangeMap, decodedVMap,
+                approximator.vTable, averageDecodedV, index, parentIndex);
+
+        color.YUV2RGB();
+
+        pixels[colorBufferIndex] = (byte) color.r;
+        pixels[colorBufferIndex + 1] = (byte) color.g;
+        pixels[colorBufferIndex + 2] = (byte) color.b;
+
+    }
 
 }
diff --git a/src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageEncoder.java b/src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageEncoder.java
index 5b0e8db..1ee823d 100755
--- a/src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageEncoder.java
+++ b/src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageEncoder.java
@@ -13,529 +13,523 @@ package eu.svjatoslav.imagesqueeze.codec;
  * Compressed image pixels encoder.
  */
 
+import eu.svjatoslav.commons.data.BitOutputStream;
+
 import java.awt.image.DataBufferByte;
 import java.awt.image.WritableRaster;
 import java.io.IOException;
 
-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;
+class ImageEncoder {
 
-		}
-	}
+    private final Image image;
+    private final Approximator approximator;
+    // ColorStats colorStats = new ColorStats();
+    private final OperatingContext context = new OperatingContext();
+    private final OperatingContext context2 = new OperatingContext();
+    int bitsForY;
+    int bitsForU;
+    int bitsForV;
+    private int width;
+    private int height;
+    private Channel yChannel;
+    private Channel uChannel;
+    private Channel vChannel;
+    private BitOutputStream bitOutputStream;
 
-	public static int encodeValueIntoGivenBits(int value, final int range,
-			final int bitCount) {
+    public ImageEncoder(final Image image) {
+        approximator = new Approximator();
 
-		int negativeBit = 0;
+        // bitOutputStream = outputStream;
 
-		if (value < 0) {
-			negativeBit = 1;
-			value = -value;
-		}
+        this.image = image;
 
-		final int remainingBitCount = bitCount - 1;
+    }
 
-		if (remainingBitCount == 0)
-			return negativeBit;
-		else {
-			// still one or more bits left, encode value as precisely as
-			// possible
+    public static int byteToInt(final byte input) {
+        int result = input;
+        if (result < 0)
+            result = result + 256;
+        return result;
+    }
 
-			if (value > range)
-				value = range;
+    public static int decodeValueFromGivenBits(final int encodedBits,
+                                               final int range, final int bitCount) {
+        final int negativeBit = encodedBits & 1;
 
-			final int realvalueForThisBitcount = 1 << remainingBitCount;
-			// int valueMultiplier = range / realvalueForThisBitcount;
-			int encodedValue = (value * realvalueForThisBitcount) / range;
+        final int remainingBitCount = bitCount - 1;
 
-			if (encodedValue >= realvalueForThisBitcount)
-				encodedValue = realvalueForThisBitcount - 1;
+        if (remainingBitCount == 0) {
+            // no more bits remaining to encode actual value
 
-			encodedValue = (encodedValue << 1) + negativeBit;
+            if (negativeBit == 0)
+                return range;
+            else
+                return -range;
 
-			return encodedValue;
-		}
-	}
+        } else {
+            // still one or more bits left, encode value as precisely as
+            // possible
 
-	public static void storeIntegerCompressed8(
-			final BitOutputStream outputStream, final int data)
-			throws IOException {
+            final int encodedValue = (encodedBits >>> 1) + 1;
 
-		if (data < 256) {
-			outputStream.storeBits(0, 1);
-			outputStream.storeBits(data, 8);
-		} else {
-			outputStream.storeBits(1, 1);
-			outputStream.storeBits(data, 32);
-		}
-	}
+            final int realvalueForThisBitcount = 1 << remainingBitCount;
 
-	Image image;
-	int width, height;
+            // int valueMultiplier = range / realvalueForThisBitcount;
+            int decodedValue = (range * encodedValue)
+                    / realvalueForThisBitcount;
 
-	Channel yChannel;
+            if (decodedValue > range)
+                decodedValue = range;
 
-	Channel uChannel;
-	Channel vChannel;
-	Approximator approximator;
+            if (negativeBit == 0)
+                return decodedValue;
+            else
+                return -decodedValue;
 
-	int bitsForY;
-	int bitsForU;
+        }
+    }
 
-	int bitsForV;
+    private static int encodeValueIntoGivenBits(int value, final int range,
+                                                final int bitCount) {
 
-	// ColorStats colorStats = new ColorStats();
-	OperatingContext context = new OperatingContext();
+        int negativeBit = 0;
 
-	OperatingContext context2 = new OperatingContext();
+        if (value < 0) {
+            negativeBit = 1;
+            value = -value;
+        }
 
-	BitOutputStream bitOutputStream;
+        final int remainingBitCount = bitCount - 1;
 
-	public ImageEncoder(final Image image) {
-		approximator = new Approximator();
+        if (remainingBitCount == 0)
+            return negativeBit;
+        else {
+            // still one or more bits left, encode value as precisely as
+            // possible
 
-		// bitOutputStream = outputStream;
+            if (value > range)
+                value = range;
 
-		this.image = image;
+            final int realvalueForThisBitcount = 1 << remainingBitCount;
+            // int valueMultiplier = range / realvalueForThisBitcount;
+            int encodedValue = (value * realvalueForThisBitcount) / range;
 
-	}
+            if (encodedValue >= realvalueForThisBitcount)
+                encodedValue = realvalueForThisBitcount - 1;
 
-	public void encode(final BitOutputStream bitOutputStream)
-			throws IOException {
-		this.bitOutputStream = bitOutputStream;
+            encodedValue = (encodedValue << 1) + negativeBit;
 
-		approximator.initialize();
+            return encodedValue;
+        }
+    }
 
-		approximator.save(bitOutputStream);
+    public static void storeIntegerCompressed8(
+            final BitOutputStream outputStream, final int data)
+            throws IOException {
 
-		width = image.metaData.width;
-		height = image.metaData.height;
+        if (data < 256) {
+            outputStream.storeBits(0, 1);
+            outputStream.storeBits(data, 8);
+        } else {
+            outputStream.storeBits(1, 1);
+            outputStream.storeBits(data, 32);
+        }
+    }
 
-		final WritableRaster raster = image.bufferedImage.getRaster();
-		final DataBufferByte dbi = (DataBufferByte) raster.getDataBuffer();
-		final byte[] pixels = dbi.getData();
+    public void encode(final BitOutputStream bitOutputStream)
+            throws IOException {
+        this.bitOutputStream = bitOutputStream;
 
-		if (yChannel == null)
-			yChannel = new Channel(width, height);
-		else
-			yChannel.reset();
+        approximator.initialize();
 
-		if (uChannel == null)
-			uChannel = new Channel(width, height);
-		else
-			uChannel.reset();
+        approximator.save(bitOutputStream);
 
-		if (vChannel == null)
-			vChannel = new Channel(width, height);
-		else
-			vChannel.reset();
+        width = image.metaData.width;
+        height = image.metaData.height;
 
-		// create YUV map out of RGB raster data
-		final Color color = new Color();
+        final WritableRaster raster = image.bufferedImage.getRaster();
+        final DataBufferByte dbi = (DataBufferByte) raster.getDataBuffer();
+        final byte[] pixels = dbi.getData();
 
-		for (int y = 0; y < height; y++)
-			for (int x = 0; x < width; x++) {
+        if (yChannel == null)
+            yChannel = new Channel(width, height);
+        else
+            yChannel.reset();
 
-				final int index = (y * width) + x;
-				final int colorBufferIndex = index * 3;
+        if (uChannel == null)
+            uChannel = new Channel(width, height);
+        else
+            uChannel.reset();
 
-				int blue = pixels[colorBufferIndex];
-				if (blue < 0)
-					blue = blue + 256;
+        if (vChannel == null)
+            vChannel = new Channel(width, height);
+        else
+            vChannel.reset();
 
-				int green = pixels[colorBufferIndex + 1];
-				if (green < 0)
-					green = green + 256;
+        // create YUV map out of RGB raster data
+        final Color color = new Color();
 
-				int red = pixels[colorBufferIndex + 2];
-				if (red < 0)
-					red = red + 256;
+        for (int y = 0; y < height; y++)
+            for (int x = 0; x < width; x++) {
 
-				color.r = red;
-				color.g = green;
-				color.b = blue;
+                final int index = (y * width) + x;
+                final int colorBufferIndex = index * 3;
 
-				color.RGB2YUV();
+                int blue = pixels[colorBufferIndex];
+                if (blue < 0)
+                    blue = blue + 256;
 
-				yChannel.map[index] = (byte) color.y;
-				uChannel.map[index] = (byte) color.u;
-				vChannel.map[index] = (byte) color.v;
-			}
+                int green = pixels[colorBufferIndex + 1];
+                if (green < 0)
+                    green = green + 256;
 
-		yChannel.decodedMap[0] = yChannel.map[0];
-		uChannel.decodedMap[0] = uChannel.map[0];
-		vChannel.decodedMap[0] = vChannel.map[0];
+                int red = pixels[colorBufferIndex + 2];
+                if (red < 0)
+                    red = red + 256;
 
-		bitOutputStream.storeBits(byteToInt(yChannel.map[0]), 8);
-		bitOutputStream.storeBits(byteToInt(uChannel.map[0]), 8);
-		bitOutputStream.storeBits(byteToInt(vChannel.map[0]), 8);
+                color.r = red;
+                color.g = green;
+                color.b = blue;
 
-		// detect initial step
-		int largestDimension;
-		int initialStep = 2;
-		if (width > height)
-			largestDimension = width;
-		else
-			largestDimension = height;
+                color.RGB2YUV();
 
-		while (initialStep < largestDimension)
-			initialStep = initialStep * 2;
+                yChannel.map[index] = (byte) color.y;
+                uChannel.map[index] = (byte) color.u;
+                vChannel.map[index] = (byte) color.v;
+            }
 
-		rangeGrid(initialStep);
-		rangeRoundGrid(2);
-		saveGrid(initialStep);
-	}
+        yChannel.decodedMap[0] = yChannel.map[0];
+        uChannel.decodedMap[0] = uChannel.map[0];
+        vChannel.decodedMap[0] = vChannel.map[0];
 
-	private void encodeChannel(final Table table, final Channel channel,
-			final int averageDecodedValue, final int index, final int value,
-			final int range, final int parentIndex) throws IOException {
+        bitOutputStream.storeBits(byteToInt(yChannel.map[0]), 8);
+        bitOutputStream.storeBits(byteToInt(uChannel.map[0]), 8);
+        bitOutputStream.storeBits(byteToInt(vChannel.map[0]), 8);
 
-		final byte[] decodedRangeMap = channel.decodedRangeMap;
-		final byte[] decodedMap = channel.decodedMap;
+        // detect initial step
+        int largestDimension;
+        int initialStep = 2;
+        if (width > height)
+            largestDimension = width;
+        else
+            largestDimension = height;
 
-		final int inheritedRange = byteToInt(decodedRangeMap[parentIndex]);
+        while (initialStep < largestDimension)
+            initialStep = initialStep * 2;
 
-		final int inheritedBitCount = table
-				.proposeBitcountForRange(inheritedRange);
+        rangeGrid(initialStep);
+        rangeRoundGrid(2);
+        saveGrid(initialStep);
+    }
+
+    private void encodeChannel(final Table table, final Channel channel,
+                               final int averageDecodedValue, final int index, final int value,
+                               final int range, final int parentIndex) throws IOException {
+
+        final byte[] decodedRangeMap = channel.decodedRangeMap;
+        final byte[] decodedMap = channel.decodedMap;
+
+        final int inheritedRange = byteToInt(decodedRangeMap[parentIndex]);
+
+        final int inheritedBitCount = table
+                .proposeBitcountForRange(inheritedRange);
 
-		if (inheritedBitCount > 0) {
-			int computedRange;
-			computedRange = table.proposeRangeForRange(range, inheritedRange);
-			decodedRangeMap[index] = (byte) computedRange;
+        if (inheritedBitCount > 0) {
+            int computedRange;
+            computedRange = table.proposeRangeForRange(range, inheritedRange);
+            decodedRangeMap[index] = (byte) computedRange;
 
-			channel.bitCount++;
-			if (computedRange != inheritedRange)
-				// brightness range shrinked
-				bitOutputStream.storeBits(1, 1);
-			else
-				// brightness range stayed the same
-				bitOutputStream.storeBits(0, 1);
-
-			// encode brightness into available amount of bits
-			final int computedBitCount = table
-					.proposeBitcountForRange(computedRange);
-
-			if (computedBitCount > 0) {
-
-				final int differenceToEncode = -(value - averageDecodedValue);
-				final int bitEncodedDifference = encodeValueIntoGivenBits(
-						differenceToEncode, computedRange, computedBitCount);
-
-				channel.bitCount = channel.bitCount + computedBitCount;
-				bitOutputStream.storeBits(bitEncodedDifference,
-						computedBitCount);
+            channel.bitCount++;
+            if (computedRange != inheritedRange)
+                // brightness range shrinked
+                bitOutputStream.storeBits(1, 1);
+            else
+                // brightness range stayed the same
+                bitOutputStream.storeBits(0, 1);
+
+            // encode brightness into available amount of bits
+            final int computedBitCount = table
+                    .proposeBitcountForRange(computedRange);
+
+            if (computedBitCount > 0) {
+
+                final int differenceToEncode = -(value - averageDecodedValue);
+                final int bitEncodedDifference = encodeValueIntoGivenBits(
+                        differenceToEncode, computedRange, computedBitCount);
+
+                channel.bitCount = channel.bitCount + computedBitCount;
+                bitOutputStream.storeBits(bitEncodedDifference,
+                        computedBitCount);
 
-				final int decodedDifference = decodeValueFromGivenBits(
-						bitEncodedDifference, computedRange, computedBitCount);
-				int decodedValue = averageDecodedValue - decodedDifference;
-				if (decodedValue > 255)
-					decodedValue = 255;
-				if (decodedValue < 0)
-					decodedValue = 0;
+                final int decodedDifference = decodeValueFromGivenBits(
+                        bitEncodedDifference, computedRange, computedBitCount);
+                int decodedValue = averageDecodedValue - decodedDifference;
+                if (decodedValue > 255)
+                    decodedValue = 255;
+                if (decodedValue < 0)
+                    decodedValue = 0;
 
-				decodedMap[index] = (byte) decodedValue;
-			} else
-				decodedMap[index] = (byte) averageDecodedValue;
+                decodedMap[index] = (byte) decodedValue;
+            } else
+                decodedMap[index] = (byte) averageDecodedValue;
 
-		} else {
-			decodedRangeMap[index] = (byte) inheritedRange;
-			decodedMap[index] = (byte) averageDecodedValue;
-		}
-	}
+        } else {
+            decodedRangeMap[index] = (byte) inheritedRange;
+            decodedMap[index] = (byte) averageDecodedValue;
+        }
+    }
 
-	public void printStatistics() {
-		System.out.println("Y channel:");
-		yChannel.printStatistics();
+    public void printStatistics() {
+        System.out.println("Y channel:");
+        yChannel.printStatistics();
 
-		System.out.println("U channel:");
-		uChannel.printStatistics();
+        System.out.println("U channel:");
+        uChannel.printStatistics();
 
-		System.out.println("V channel:");
-		vChannel.printStatistics();
-	}
+        System.out.println("V channel:");
+        vChannel.printStatistics();
+    }
 
-	public void rangeGrid(final int step) {
+    private void rangeGrid(final int step) {
 
-		// gridSquare(step / 2, step / 2, step, pixels);
-
-		rangeGridDiagonal(step / 2, step / 2, step);
-		rangeGridSquare(step / 2, 0, step);
-		rangeGridSquare(0, step / 2, step);
+        // gridSquare(step / 2, step / 2, step, pixels);
+
+        rangeGridDiagonal(step / 2, step / 2, step);
+        rangeGridSquare(step / 2, 0, step);
+        rangeGridSquare(0, step / 2, step);
 
-		if (step > 2)
-			rangeGrid(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 x = offsetX; x < width; x = x + step) {
+    private void rangeGridDiagonal(final int offsetX, final int offsetY,
+                                   final int 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;
-				final int halfStep = step / 2;
+                final int index = (y * width) + x;
+                final int halfStep = step / 2;
 
-				context.initialize(image, yChannel.map, uChannel.map,
-						vChannel.map);
+                context.initialize(image, yChannel.map, uChannel.map,
+                        vChannel.map);
 
-				context.measureNeighborEncode(x - halfStep, y - halfStep);
-				context.measureNeighborEncode(x + halfStep, y - halfStep);
-				context.measureNeighborEncode(x - halfStep, y + halfStep);
-				context.measureNeighborEncode(x + halfStep, y + halfStep);
+                context.measureNeighborEncode(x - halfStep, y - halfStep);
+                context.measureNeighborEncode(x + halfStep, y - halfStep);
+                context.measureNeighborEncode(x - halfStep, y + halfStep);
+                context.measureNeighborEncode(x + halfStep, y + halfStep);
 
-				yChannel.rangeMap[index] = (byte) context.getYRange(index);
-				uChannel.rangeMap[index] = (byte) context.getURange(index);
-				vChannel.rangeMap[index] = (byte) context.getVRange(index);
-			}
-	}
+                yChannel.rangeMap[index] = (byte) context.getYRange(index);
+                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 x = offsetX; x < width; x = x + step) {
+    private void rangeGridSquare(final int offsetX, final int offsetY,
+                                 final int 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;
-				final int halfStep = step / 2;
+                final int index = (y * width) + x;
+                final int halfStep = step / 2;
 
-				context.initialize(image, yChannel.map, uChannel.map,
-						vChannel.map);
+                context.initialize(image, yChannel.map, uChannel.map,
+                        vChannel.map);
 
-				context.measureNeighborEncode(x - halfStep, y);
-				context.measureNeighborEncode(x + halfStep, y);
-				context.measureNeighborEncode(x, y - halfStep);
-				context.measureNeighborEncode(x, y + halfStep);
+                context.measureNeighborEncode(x - halfStep, y);
+                context.measureNeighborEncode(x + halfStep, y);
+                context.measureNeighborEncode(x, y - halfStep);
+                context.measureNeighborEncode(x, y + halfStep);
 
-				yChannel.rangeMap[index] = (byte) context.getYRange(index);
-				uChannel.rangeMap[index] = (byte) context.getURange(index);
-				vChannel.rangeMap[index] = (byte) context.getVRange(index);
-			}
-	}
+                yChannel.rangeMap[index] = (byte) context.getYRange(index);
+                uChannel.rangeMap[index] = (byte) context.getURange(index);
+                vChannel.rangeMap[index] = (byte) context.getVRange(index);
+            }
+    }
 
-	public void rangeRoundGrid(final int step) {
+    private void rangeRoundGrid(final int step) {
 
-		rangeRoundGridDiagonal(step / 2, step / 2, step);
-		rangeRoundGridSquare(step / 2, 0, step);
-		rangeRoundGridSquare(0, step / 2, step);
+        rangeRoundGridDiagonal(step / 2, step / 2, step);
+        rangeRoundGridSquare(step / 2, 0, step);
+        rangeRoundGridSquare(0, step / 2, step);
 
-		if (step < 1024)
-			rangeRoundGrid(step * 2);
-	}
+        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 x = offsetX; x < width; x = x + step) {
+    private void rangeRoundGridDiagonal(final int offsetX, final int offsetY,
+                                        final int 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;
+                final int index = (y * width) + x;
 
-				final int yRange = byteToInt(yChannel.rangeMap[index]);
-				final int uRange = byteToInt(uChannel.rangeMap[index]);
-				final int vRange = byteToInt(vChannel.rangeMap[index]);
+                final int yRange = byteToInt(yChannel.rangeMap[index]);
+                final int uRange = byteToInt(uChannel.rangeMap[index]);
+                final int vRange = byteToInt(vChannel.rangeMap[index]);
 
-				final int halfStep = step / 2;
+                final int halfStep = step / 2;
 
-				final int parentIndex = ((y - halfStep) * width)
-						+ (x - halfStep);
+                final int parentIndex = ((y - halfStep) * width)
+                        + (x - halfStep);
 
-				int parentYRange = byteToInt(yChannel.rangeMap[parentIndex]);
+                int parentYRange = byteToInt(yChannel.rangeMap[parentIndex]);
 
-				if (parentYRange < yRange) {
-					parentYRange = yRange;
-					yChannel.rangeMap[parentIndex] = (byte) parentYRange;
-				}
+                if (parentYRange < yRange) {
+                    parentYRange = yRange;
+                    yChannel.rangeMap[parentIndex] = (byte) parentYRange;
+                }
 
-				int parentURange = byteToInt(uChannel.rangeMap[parentIndex]);
+                int parentURange = byteToInt(uChannel.rangeMap[parentIndex]);
 
-				if (parentURange < uRange) {
-					parentURange = uRange;
-					uChannel.rangeMap[parentIndex] = (byte) parentURange;
-				}
+                if (parentURange < uRange) {
+                    parentURange = uRange;
+                    uChannel.rangeMap[parentIndex] = (byte) parentURange;
+                }
 
-				int parentVRange = byteToInt(vChannel.rangeMap[parentIndex]);
+                int parentVRange = byteToInt(vChannel.rangeMap[parentIndex]);
 
-				if (parentVRange < vRange) {
-					parentVRange = vRange;
-					vChannel.rangeMap[parentIndex] = (byte) parentVRange;
-				}
-			}
-	}
+                if (parentVRange < vRange) {
+                    parentVRange = vRange;
+                    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 x = offsetX; x < width; x = x + step) {
+    private void rangeRoundGridSquare(final int offsetX, final int offsetY,
+                                      final int 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;
+                final int index = (y * width) + x;
 
-				final int yRange = byteToInt(yChannel.rangeMap[index]);
-				final int uRange = byteToInt(uChannel.rangeMap[index]);
-				final int vRange = byteToInt(vChannel.rangeMap[index]);
+                final int yRange = byteToInt(yChannel.rangeMap[index]);
+                final int uRange = byteToInt(uChannel.rangeMap[index]);
+                final int vRange = byteToInt(vChannel.rangeMap[index]);
 
-				final int halfStep = step / 2;
+                final int halfStep = step / 2;
 
-				int parentIndex;
-				if (offsetX > 0)
-					parentIndex = (y * width) + (x - halfStep);
-				else
-					parentIndex = ((y - halfStep) * width) + x;
+                int parentIndex;
+                if (offsetX > 0)
+                    parentIndex = (y * width) + (x - halfStep);
+                else
+                    parentIndex = ((y - halfStep) * width) + x;
 
-				int parentYRange = byteToInt(yChannel.rangeMap[parentIndex]);
+                int parentYRange = byteToInt(yChannel.rangeMap[parentIndex]);
 
-				if (parentYRange < yRange) {
-					parentYRange = yRange;
-					yChannel.rangeMap[parentIndex] = (byte) parentYRange;
-				}
+                if (parentYRange < yRange) {
+                    parentYRange = yRange;
+                    yChannel.rangeMap[parentIndex] = (byte) parentYRange;
+                }
 
-				int parentURange = byteToInt(uChannel.rangeMap[parentIndex]);
+                int parentURange = byteToInt(uChannel.rangeMap[parentIndex]);
 
-				if (parentURange < uRange) {
-					parentURange = uRange;
-					uChannel.rangeMap[parentIndex] = (byte) parentURange;
-				}
+                if (parentURange < uRange) {
+                    parentURange = uRange;
+                    uChannel.rangeMap[parentIndex] = (byte) parentURange;
+                }
 
-				int parentVRange = byteToInt(vChannel.rangeMap[parentIndex]);
+                int parentVRange = byteToInt(vChannel.rangeMap[parentIndex]);
 
-				if (parentVRange < vRange) {
-					parentVRange = vRange;
-					vChannel.rangeMap[parentIndex] = (byte) parentVRange;
-				}
+                if (parentVRange < vRange) {
+                    parentVRange = vRange;
+                    vChannel.rangeMap[parentIndex] = (byte) parentVRange;
+                }
 
-			}
-	}
+            }
+    }
 
-	public void saveGrid(final int step) throws IOException {
+    private void saveGrid(final int step) throws IOException {
 
-		saveGridDiagonal(step / 2, step / 2, step);
-		saveGridSquare(step / 2, 0, step);
-		saveGridSquare(0, step / 2, step);
+        saveGridDiagonal(step / 2, step / 2, step);
+        saveGridSquare(step / 2, 0, step);
+        saveGridSquare(0, step / 2, step);
 
-		if (step > 2)
-			saveGrid(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 x = offsetX; x < width; x = x + step) {
+    private void saveGridDiagonal(final int offsetX, final int offsetY,
+                                  final int step) throws IOException {
+        for (int y = offsetY; y < height; y = y + step)
+            for (int x = offsetX; x < width; x = x + step) {
 
-				final int halfStep = step / 2;
+                final int halfStep = step / 2;
 
-				context2.initialize(image, yChannel.decodedMap,
-						uChannel.decodedMap, vChannel.decodedMap);
-				context2.measureNeighborEncode(x - halfStep, y - halfStep);
-				context2.measureNeighborEncode(x + halfStep, y - halfStep);
-				context2.measureNeighborEncode(x - halfStep, y + halfStep);
-				context2.measureNeighborEncode(x + halfStep, y + halfStep);
+                context2.initialize(image, yChannel.decodedMap,
+                        uChannel.decodedMap, vChannel.decodedMap);
+                context2.measureNeighborEncode(x - halfStep, y - halfStep);
+                context2.measureNeighborEncode(x + halfStep, y - halfStep);
+                context2.measureNeighborEncode(x - halfStep, y + halfStep);
+                context2.measureNeighborEncode(x + halfStep, y + halfStep);
 
-				savePixel(step, offsetX, offsetY, x, y,
-						context2.colorStats.getAverageY(),
-						context2.colorStats.getAverageU(),
-						context2.colorStats.getAverageV());
+                savePixel(step, offsetX, offsetY, x, y,
+                        context2.colorStats.getAverageY(),
+                        context2.colorStats.getAverageU(),
+                        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 x = offsetX; x < width; x = x + step) {
+    private void saveGridSquare(final int offsetX, final int offsetY,
+                                final int step) throws IOException {
+        for (int y = offsetY; y < height; y = y + step)
+            for (int x = offsetX; x < width; x = x + step) {
 
-				final int halfStep = step / 2;
+                final int halfStep = step / 2;
 
-				context2.initialize(image, yChannel.decodedMap,
-						uChannel.decodedMap, vChannel.decodedMap);
-				context2.measureNeighborEncode(x - halfStep, y);
-				context2.measureNeighborEncode(x + halfStep, y);
-				context2.measureNeighborEncode(x, y - halfStep);
-				context2.measureNeighborEncode(x, y + halfStep);
+                context2.initialize(image, yChannel.decodedMap,
+                        uChannel.decodedMap, vChannel.decodedMap);
+                context2.measureNeighborEncode(x - halfStep, y);
+                context2.measureNeighborEncode(x + halfStep, y);
+                context2.measureNeighborEncode(x, y - halfStep);
+                context2.measureNeighborEncode(x, y + halfStep);
 
-				savePixel(step, offsetX, offsetY, x, y,
-						context2.colorStats.getAverageY(),
-						context2.colorStats.getAverageU(),
-						context2.colorStats.getAverageV());
+                savePixel(step, offsetX, offsetY, x, y,
+                        context2.colorStats.getAverageY(),
+                        context2.colorStats.getAverageU(),
+                        context2.colorStats.getAverageV());
 
-			}
-	}
+            }
+    }
 
-	public void savePixel(final int step, final int offsetX, final int offsetY,
-			final int x, final int y, final int averageDecodedY,
-			final int averageDecodedU, final int averageDecodedV)
-			throws IOException {
+    private void savePixel(final int step, final int offsetX, final int offsetY,
+                           final int x, final int y, final int averageDecodedY,
+                           final int averageDecodedU, final int averageDecodedV)
+            throws IOException {
 
-		final int index = (y * width) + x;
+        final int index = (y * width) + x;
 
-		final int py = byteToInt(yChannel.map[index]);
-		final int pu = byteToInt(uChannel.map[index]);
-		final int pv = byteToInt(vChannel.map[index]);
+        final int py = byteToInt(yChannel.map[index]);
+        final int pu = byteToInt(uChannel.map[index]);
+        final int pv = byteToInt(vChannel.map[index]);
 
-		final int yRange = byteToInt(yChannel.rangeMap[index]);
-		final int uRange = byteToInt(uChannel.rangeMap[index]);
-		final int vRange = byteToInt(vChannel.rangeMap[index]);
+        final int yRange = byteToInt(yChannel.rangeMap[index]);
+        final int uRange = byteToInt(uChannel.rangeMap[index]);
+        final int vRange = byteToInt(vChannel.rangeMap[index]);
 
-		final int halfStep = step / 2;
+        final int halfStep = step / 2;
 
-		int parentIndex;
-		if (offsetX > 0) {
-			if (offsetY > 0)
-				// diagonal approach
-				parentIndex = ((y - halfStep) * width) + (x - halfStep);
-			else
-				// take left pixel
-				parentIndex = (y * width) + (x - halfStep);
-		} else
-			// take upper pixel
-			parentIndex = ((y - halfStep) * width) + x;
+        int parentIndex;
+        if (offsetX > 0) {
+            if (offsetY > 0)
+                // diagonal approach
+                parentIndex = ((y - halfStep) * width) + (x - halfStep);
+            else
+                // take left pixel
+                parentIndex = (y * width) + (x - halfStep);
+        } else
+            // take upper pixel
+            parentIndex = ((y - halfStep) * width) + x;
 
-		encodeChannel(approximator.yTable, yChannel, averageDecodedY, index,
-				py, yRange, parentIndex);
-
-		encodeChannel(approximator.uTable, uChannel, averageDecodedU, index,
-				pu, uRange, parentIndex);
+        encodeChannel(approximator.yTable, yChannel, averageDecodedY, index,
+                py, yRange, parentIndex);
+
+        encodeChannel(approximator.uTable, uChannel, averageDecodedU, index,
+                pu, uRange, parentIndex);
 
-		encodeChannel(approximator.vTable, vChannel, averageDecodedV, index,
-				pv, vRange, parentIndex);
+        encodeChannel(approximator.vTable, vChannel, averageDecodedV, index,
+                pv, vRange, parentIndex);
 
-	}
+    }
 
 }
diff --git a/src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageMetaData.java b/src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageMetaData.java
index 49e9000..c97bb32 100755
--- a/src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageMetaData.java
+++ b/src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageMetaData.java
@@ -14,27 +14,27 @@ package eu.svjatoslav.imagesqueeze.codec;
  * Like image dimensions, header version, compression quality, etc..
  */
 
-import java.io.IOException;
-
 import eu.svjatoslav.commons.data.BitInputStream;
 import eu.svjatoslav.commons.data.BitOutputStream;
 
+import java.io.IOException;
+
 public class ImageMetaData {
 
-	int version;
-	int width;
-	int height;
-
-	public void load(final BitInputStream inputStream) throws IOException {
-		version = inputStream.readBits(16);
-		width = ImageDecoder.readIntegerCompressed8(inputStream);
-		height = ImageDecoder.readIntegerCompressed8(inputStream);
-	}
-
-	public void save(final BitOutputStream outputStream) throws IOException {
-		outputStream.storeBits(version, 16);
-		ImageEncoder.storeIntegerCompressed8(outputStream, width);
-		ImageEncoder.storeIntegerCompressed8(outputStream, height);
-	}
+    int version;
+    int width;
+    int height;
+
+    public void load(final BitInputStream inputStream) throws IOException {
+        version = inputStream.readBits(16);
+        width = ImageDecoder.readIntegerCompressed8(inputStream);
+        height = ImageDecoder.readIntegerCompressed8(inputStream);
+    }
+
+    public void save(final BitOutputStream outputStream) throws IOException {
+        outputStream.storeBits(version, 16);
+        ImageEncoder.storeIntegerCompressed8(outputStream, width);
+        ImageEncoder.storeIntegerCompressed8(outputStream, height);
+    }
 
 }
diff --git a/src/main/java/eu/svjatoslav/imagesqueeze/codec/OperatingContext.java b/src/main/java/eu/svjatoslav/imagesqueeze/codec/OperatingContext.java
index e96d610..693e25c 100755
--- a/src/main/java/eu/svjatoslav/imagesqueeze/codec/OperatingContext.java
+++ b/src/main/java/eu/svjatoslav/imagesqueeze/codec/OperatingContext.java
@@ -9,56 +9,56 @@
 
 package eu.svjatoslav.imagesqueeze.codec;
 
-public class OperatingContext {
+class OperatingContext {
 
-	Image image;
-	byte[] yMap;
-	byte[] uMap;
-	byte[] vMap;
-	ColorStats colorStats = new ColorStats();
+    final ColorStats colorStats = new ColorStats();
+    private Image image;
+    private byte[] yMap;
+    private byte[] uMap;
+    private byte[] vMap;
 
-	public OperatingContext() {
-	}
+    public OperatingContext() {
+    }
 
-	public int getURange(final int index) {
-		final int colorness = ImageEncoder.byteToInt(uMap[index]);
-		return Math.abs(colorness - colorStats.getAverageU());
-	}
+    public int getURange(final int index) {
+        final int colorness = ImageEncoder.byteToInt(uMap[index]);
+        return Math.abs(colorness - colorStats.getAverageU());
+    }
 
-	public int getVRange(final int index) {
-		final int color = ImageEncoder.byteToInt(vMap[index]);
-		return Math.abs(color - colorStats.getAverageV());
-	}
+    public int getVRange(final int index) {
+        final int color = ImageEncoder.byteToInt(vMap[index]);
+        return Math.abs(color - colorStats.getAverageV());
+    }
 
-	public int getYRange(final int index) {
-		final int brightness = ImageEncoder.byteToInt(yMap[index]);
-		return Math.abs(brightness - colorStats.getAverageY());
-	}
+    public int getYRange(final int index) {
+        final int brightness = ImageEncoder.byteToInt(yMap[index]);
+        return Math.abs(brightness - colorStats.getAverageY());
+    }
 
-	public void initialize(final Image image, final byte[] brightnessMap,
-			final byte[] colornessMap, final byte[] colorMap) {
-		this.image = image;
-		yMap = brightnessMap;
-		uMap = colornessMap;
-		vMap = colorMap;
+    public void initialize(final Image image, final byte[] brightnessMap,
+                           final byte[] colornessMap, final byte[] colorMap) {
+        this.image = image;
+        yMap = brightnessMap;
+        uMap = colornessMap;
+        vMap = colorMap;
 
-		colorStats.reset();
-	}
+        colorStats.reset();
+    }
 
-	public void measureNeighborEncode(final int x, final int y) {
-		if ((y >= 0) && (y < image.metaData.height) && (x >= 0)
-				&& (x < image.metaData.width)) {
+    public void measureNeighborEncode(final int x, final int y) {
+        if ((y >= 0) && (y < image.metaData.height) && (x >= 0)
+                && (x < image.metaData.width)) {
 
-			final int neighborIndex = (y * image.metaData.width) + x;
+            final int neighborIndex = (y * image.metaData.width) + x;
 
-			colorStats.ySum = colorStats.ySum
-					+ ImageEncoder.byteToInt(yMap[neighborIndex]);
-			colorStats.uSum = colorStats.uSum
-					+ ImageEncoder.byteToInt(uMap[neighborIndex]);
-			colorStats.vSum = colorStats.vSum
-					+ ImageEncoder.byteToInt(vMap[neighborIndex]);
-			colorStats.pixelCount++;
-		}
-	}
+            colorStats.ySum = colorStats.ySum
+                    + ImageEncoder.byteToInt(yMap[neighborIndex]);
+            colorStats.uSum = colorStats.uSum
+                    + ImageEncoder.byteToInt(uMap[neighborIndex]);
+            colorStats.vSum = colorStats.vSum
+                    + ImageEncoder.byteToInt(vMap[neighborIndex]);
+            colorStats.pixelCount++;
+        }
+    }
 
 }
diff --git a/src/main/java/eu/svjatoslav/imagesqueeze/codec/Table.java b/src/main/java/eu/svjatoslav/imagesqueeze/codec/Table.java
index 4e6e638..b0ca55f 100755
--- a/src/main/java/eu/svjatoslav/imagesqueeze/codec/Table.java
+++ b/src/main/java/eu/svjatoslav/imagesqueeze/codec/Table.java
@@ -9,195 +9,164 @@
 
 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 = 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;
-		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 {
-		ImageEncoder.storeIntegerCompressed8(outputStream, 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);
+        }
+    }
 
 }
diff --git a/src/main/java/eu/svjatoslav/imagesqueeze/sampleApplication/ImageFrame.java b/src/main/java/eu/svjatoslav/imagesqueeze/sampleApplication/ImageFrame.java
index 2b68ef7..d87b736 100755
--- a/src/main/java/eu/svjatoslav/imagesqueeze/sampleApplication/ImageFrame.java
+++ b/src/main/java/eu/svjatoslav/imagesqueeze/sampleApplication/ImageFrame.java
@@ -9,51 +9,46 @@
 
 package eu.svjatoslav.imagesqueeze.sampleApplication;
 
-import java.awt.BorderLayout;
-
-import javax.swing.SwingUtilities;
-import javax.swing.WindowConstants;
+import javax.swing.*;
+import java.awt.*;
 
 public class ImageFrame extends javax.swing.JFrame {
-	private ImagePanel imagePanel1;
-
-	public ImageFrame(final String title) {
-		super();
-		setTitle(title);
-		initGUI();
-	}
-
-	public ImagePanel getImagePanel() {
-		return imagePanel1;
-	}
-
-	private void initGUI() {
-		try {
-			final BorderLayout thisLayout = new BorderLayout();
-			setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
-			getContentPane().setLayout(thisLayout);
-			{
-				imagePanel1 = new ImagePanel();
-				getContentPane().add(getImagePanel(), BorderLayout.CENTER);
-			}
-			pack();
-		} catch (final Exception e) {
-			e.printStackTrace();
-		}
-	}
-
-	/**
-	 * Auto-generated main method to display this JFrame
-	 */
-	public static void main(final String[] args) {
-		SwingUtilities.invokeLater(new Runnable() {
-			@Override
-			public void run() {
-				final ImageFrame inst = new ImageFrame("test");
-				inst.setLocationRelativeTo(null);
-				inst.setVisible(true);
-			}
-		});
-	}
+    private ImagePanel imagePanel1;
+
+    public ImageFrame(final String title) {
+        super();
+        setTitle(title);
+        initGUI();
+    }
+
+    /**
+     * Auto-generated main method to display this JFrame
+     */
+    public static void main(final String[] args) {
+        SwingUtilities.invokeLater(() -> {
+            final ImageFrame inst = new ImageFrame("test");
+            inst.setLocationRelativeTo(null);
+            inst.setVisible(true);
+        });
+    }
+
+    public ImagePanel getImagePanel() {
+        return imagePanel1;
+    }
+
+    private void initGUI() {
+        try {
+            final BorderLayout thisLayout = new BorderLayout();
+            setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+            getContentPane().setLayout(thisLayout);
+            {
+                imagePanel1 = new ImagePanel();
+                getContentPane().add(getImagePanel(), BorderLayout.CENTER);
+            }
+            pack();
+        } catch (final Exception e) {
+            e.printStackTrace();
+        }
+    }
 
 }
diff --git a/src/main/java/eu/svjatoslav/imagesqueeze/sampleApplication/ImagePanel.java b/src/main/java/eu/svjatoslav/imagesqueeze/sampleApplication/ImagePanel.java
index c2ccead..8bfb903 100755
--- a/src/main/java/eu/svjatoslav/imagesqueeze/sampleApplication/ImagePanel.java
+++ b/src/main/java/eu/svjatoslav/imagesqueeze/sampleApplication/ImagePanel.java
@@ -9,123 +9,115 @@
 
 package eu.svjatoslav.imagesqueeze.sampleApplication;
 
-import java.awt.BorderLayout;
-import java.awt.Dimension;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.swing.ImageIcon;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.WindowConstants;
-
 import eu.svjatoslav.imagesqueeze.codec.Image;
 
+import javax.swing.*;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+
 public class ImagePanel extends javax.swing.JPanel {
-	private JLabel imageLabel;
-
-	public BufferedImage bufferedImage;
-
-	public ImagePanel() {
-		super();
-		initGUI();
-	}
-
-	public void createEmptyImage(final Dimension dimension) {
-
-		bufferedImage = new BufferedImage(dimension.width, dimension.height,
-				BufferedImage.TYPE_3BYTE_BGR);
-
-		final ImageIcon icon = new ImageIcon(bufferedImage);
-
-		imageLabel.setIcon(icon);
-	}
-
-	public JLabel getImageLabel() {
-		return imageLabel;
-	}
-
-	private void initGUI() {
-		try {
-			final BorderLayout thisLayout = new BorderLayout();
-			setLayout(thisLayout);
-			setPreferredSize(new Dimension(660, 500));
-			{
-				imageLabel = new JLabel();
-				this.add(getImageLabel(), BorderLayout.CENTER);
-			}
-		} catch (final Exception e) {
-			e.printStackTrace();
-		}
-	}
-
-	public void loadImage(final File inputFile, final boolean isImgSqz)
-			throws IOException {
-		final FileInputStream fileInputStream = new FileInputStream(inputFile);
-
-		loadImage(fileInputStream, isImgSqz);
-	}
-
-	public void loadImage(final InputStream inputStream, final boolean isImgSqz)
-			throws IOException {
-		if (isImgSqz) {
-			// load ImageSqueeze file
-
-			final Image image = new Image();
-			image.loadImage(inputStream);
-
-			bufferedImage = image.bufferedImage;
-
-			final ImageIcon icon = new ImageIcon(bufferedImage);
-			// ImageIcon icon = new ImageIcon("sample data/original.png");
-
-			imageLabel.setIcon(icon);
-
-		} else {
-			// load JPEG, PNG, GIF file
-			final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-			readLoop: {
-				for (;;) {
-					final int b = inputStream.read();
-					if (b == -1)
-						break readLoop;
-					outputStream.write(b);
-				}
-			}
-
-			final ImageIcon icon = new ImageIcon(outputStream.toByteArray());
-
-			bufferedImage = new BufferedImage(icon.getIconWidth(),
-					icon.getIconHeight(), BufferedImage.TYPE_3BYTE_BGR);
-			bufferedImage.getGraphics().drawImage(icon.getImage(), 0, 0, null);
-
-			final ImageIcon displayIcon = new ImageIcon(bufferedImage);
-			imageLabel.setIcon(displayIcon);
-		}
-	}
-
-	public void saveImage(final File outputFile) {
-		final Image image = new Image(bufferedImage);
-		try {
-			image.saveImage(outputFile);
-		} catch (final Exception e) {
-			System.out.println("Error while saving image: " + e.toString());
-		}
-	}
-
-	/**
-	 * Auto-generated main method to display this JPanel inside a new JFrame.
-	 */
-	public static void main(final String[] args) {
-		final JFrame frame = new JFrame();
-		frame.getContentPane().add(new ImagePanel());
-		frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
-		frame.pack();
-		frame.setVisible(true);
-	}
+    private BufferedImage bufferedImage;
+    private JLabel imageLabel;
+
+    public ImagePanel() {
+        super();
+        initGUI();
+    }
+
+    /**
+     * Auto-generated main method to display this JPanel inside a new JFrame.
+     */
+    public static void main(final String[] args) {
+        final JFrame frame = new JFrame();
+        frame.getContentPane().add(new ImagePanel());
+        frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+        frame.pack();
+        frame.setVisible(true);
+    }
+
+    public void createEmptyImage(final Dimension dimension) {
+
+        bufferedImage = new BufferedImage(dimension.width, dimension.height,
+                BufferedImage.TYPE_3BYTE_BGR);
+
+        final ImageIcon icon = new ImageIcon(bufferedImage);
+
+        imageLabel.setIcon(icon);
+    }
+
+    private JLabel getImageLabel() {
+        return imageLabel;
+    }
+
+    private void initGUI() {
+        try {
+            final BorderLayout thisLayout = new BorderLayout();
+            setLayout(thisLayout);
+            setPreferredSize(new Dimension(660, 500));
+            {
+                imageLabel = new JLabel();
+                this.add(getImageLabel(), BorderLayout.CENTER);
+            }
+        } catch (final Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void loadImage(final File inputFile, final boolean isImgSqz)
+            throws IOException {
+
+        try (final FileInputStream fileInputStream = new FileInputStream(inputFile)) {
+            loadImage(fileInputStream, isImgSqz);
+        }
+    }
+
+    public void loadImage(final InputStream inputStream, final boolean isImgSqz)
+            throws IOException {
+        if (isImgSqz) {
+            // load ImageSqueeze file
+
+            final Image image = new Image();
+            image.loadImage(inputStream);
+
+            bufferedImage = image.bufferedImage;
+
+            final ImageIcon icon = new ImageIcon(bufferedImage);
+            // ImageIcon icon = new ImageIcon("sample data/original.png");
+
+            imageLabel.setIcon(icon);
+
+        } else {
+            // load JPEG, PNG, GIF file
+            final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            readLoop:
+            {
+                for (; ; ) {
+                    final int b = inputStream.read();
+                    if (b == -1)
+                        break readLoop;
+                    outputStream.write(b);
+                }
+            }
+
+            final ImageIcon icon = new ImageIcon(outputStream.toByteArray());
+
+            bufferedImage = new BufferedImage(icon.getIconWidth(),
+                    icon.getIconHeight(), BufferedImage.TYPE_3BYTE_BGR);
+            bufferedImage.getGraphics().drawImage(icon.getImage(), 0, 0, null);
+
+            final ImageIcon displayIcon = new ImageIcon(bufferedImage);
+            imageLabel.setIcon(displayIcon);
+        }
+    }
+
+    public void saveImage(final File outputFile) {
+        final Image image = new Image(bufferedImage);
+        try {
+            image.saveImage(outputFile);
+        } catch (final Exception e) {
+            System.out.println("Error while saving image: " + e.toString());
+        }
+    }
 
 }
diff --git a/src/main/java/eu/svjatoslav/imagesqueeze/sampleApplication/Main.java b/src/main/java/eu/svjatoslav/imagesqueeze/sampleApplication/Main.java
index 0e2ccce..8471a08 100755
--- a/src/main/java/eu/svjatoslav/imagesqueeze/sampleApplication/Main.java
+++ b/src/main/java/eu/svjatoslav/imagesqueeze/sampleApplication/Main.java
@@ -15,36 +15,30 @@ import java.io.InputStream;
 
 public class Main {
 
-	public static void main(final String[] args) {
+    public static void main(final String[] args) throws IOException {
 
-		try {
+        final String image = "colorful photo";
+        final String sourceDirectory = "/eu/svjatoslav/imagesqueeze/sampleApplication/data/";
 
-			final String image = "colorful photo";
-			final String sourceDirectory = "/eu/svjatoslav/imagesqueeze/sampleApplication/data/";
+        // create visible frame
+        // load image into frame
+        final InputStream inputStream = Main.class
+                .getResourceAsStream(sourceDirectory + image + ".png");
 
-			// create visible frame
-			// load image into frame
-			final InputStream inputStream = Main.class
-					.getResourceAsStream(sourceDirectory + image + ".png");
+        final ImageFrame frame = new ImageFrame("Original image");
+        frame.getImagePanel().loadImage(inputStream, false);
+        frame.setVisible(true);
 
-			final ImageFrame frame = new ImageFrame("Original image");
-			frame.getImagePanel().loadImage(inputStream, false);
-			frame.setVisible(true);
+        // encode image into file
+        frame.getImagePanel().saveImage(new File(image + ".ImgSqz"));
 
-			// encode image into file
-			frame.getImagePanel().saveImage(new File(image + ".ImgSqz"));
+        // create second frame for decoded image
+        final ImageFrame frame2 = new ImageFrame("Encoded -> Decoded");
 
-			// create second frame for decoded image
-			final ImageFrame frame2 = new ImageFrame("Encoded -> Decoded");
+        // decode image
+        frame2.getImagePanel().loadImage(new File(image + ".ImgSqz"), true);
+        frame2.setVisible(true);
 
-			// decode image
-			frame2.getImagePanel().loadImage(new File(image + ".ImgSqz"), true);
-			frame2.setVisible(true);
-
-		} catch (final IOException exception) {
-			System.out.println("Error while loading an image: " + exception);
-		}
-
-	}
+    }
 
 }