Moved to java 1.8. Code cleanup and formatting.
authorSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Sat, 25 Jun 2016 20:02:28 +0000 (22:02 +0200)
committerSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Sat, 25 Jun 2016 20:02:28 +0000 (22:02 +0200)
17 files changed:
.gitignore
doc/index.html
imagesqueeze.iml [new file with mode: 0644]
pom.xml
src/main/java/eu/svjatoslav/imagesqueeze/codec/Approximator.java
src/main/java/eu/svjatoslav/imagesqueeze/codec/Channel.java
src/main/java/eu/svjatoslav/imagesqueeze/codec/Color.java
src/main/java/eu/svjatoslav/imagesqueeze/codec/ColorStats.java
src/main/java/eu/svjatoslav/imagesqueeze/codec/Image.java
src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageDecoder.java
src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageEncoder.java
src/main/java/eu/svjatoslav/imagesqueeze/codec/ImageMetaData.java
src/main/java/eu/svjatoslav/imagesqueeze/codec/OperatingContext.java
src/main/java/eu/svjatoslav/imagesqueeze/codec/Table.java
src/main/java/eu/svjatoslav/imagesqueeze/sampleApplication/ImageFrame.java
src/main/java/eu/svjatoslav/imagesqueeze/sampleApplication/ImagePanel.java
src/main/java/eu/svjatoslav/imagesqueeze/sampleApplication/Main.java

index 637d4dd..c2748b1 100644 (file)
@@ -1,5 +1,6 @@
-bin/
-target/
-.settings/
+/bin/
+/target/
+/.settings/
 /.project
 /.classpath
+/.idea/
index ad87c30..410d44e 100644 (file)
@@ -1,18 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 <html>
 <head>
-<meta
-    http-equiv="Content-Type"
-    content="text/html; charset=UTF-8">
-<title>ImageSqueeze</title>
+    <meta
+            http-equiv="Content-Type"
+            content="text/html; charset=UTF-8">
+    <title>ImageSqueeze</title>
 </head>
 <body>
-    <h1>ImageSqueeze - lossy image codec</h1>
-    <a href="http://php.svjatoslav.eu/gitweb/?p=imagesqueeze.git;a=snapshot;h=HEAD;sf=tgz">Download</a>
-    &nbsp;&nbsp;
-    <a href="http://www2.svjatoslav.eu/gitbrowse/imagesqueeze/doc/index.html">Online homepage</a>
-    &nbsp;&nbsp;
-    <a href="http://svjatoslav.eu/programs.jsp">Other applications hosted on svjatoslav.eu</a>
+<h1>ImageSqueeze - lossy image codec</h1>
+<a href="http://php.svjatoslav.eu/gitweb/?p=imagesqueeze.git;a=snapshot;h=HEAD;sf=tgz">Download</a>
+&nbsp;&nbsp;
+<a href="http://www2.svjatoslav.eu/gitbrowse/imagesqueeze/doc/index.html">Online homepage</a>
+&nbsp;&nbsp;
+<a href="http://svjatoslav.eu/programs.jsp">Other applications hosted on svjatoslav.eu</a>
     <pre>
 <b>Program author:</b>
     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.
-<img src="originalAndCompressed.png" />
+<img src="originalAndCompressed.png"/>
 
 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 (file)
index 0000000..6a36d37
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="Maven: eu.svjatoslav:svjatoslavcommons:1.5-SNAPSHOT" level="project" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 8655494..8705ab2 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -1,7 +1,7 @@
 <project
-    xmlns="http://maven.apache.org/POM/4.0.0"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+        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">
     <modelVersion>4.0.0</modelVersion>
     <groupId>eu.svjatoslav</groupId>
     <artifactId>imagesqueeze</artifactId>
@@ -39,8 +39,8 @@
                 <artifactId>maven-compiler-plugin</artifactId>
                 <version>2.3.1</version>
                 <configuration>
-                    <source>1.6</source>
-                    <target>1.6</target>
+                    <source>1.8</source>
+                    <target>1.8</target>
                     <optimize>true</optimize>
                     <encoding>UTF-8</encoding>
                 </configuration>
@@ -88,8 +88,8 @@
         <extensions>
             <extension>
                 <groupId>org.apache.maven.wagon</groupId>
-                <artifactId>wagon-ssh</artifactId>
-                <version>2.2</version>
+                <artifactId>wagon-ssh-external</artifactId>
+                <version>2.6</version>
             </extension>
         </extensions>
     </build>
         </dependency>
     </dependencies>
 
+    <distributionManagement>
+        <snapshotRepository>
+            <id>svjatoslav.eu</id>
+            <name>svjatoslav.eu</name>
+            <url>scpexe://svjatoslav.eu/var/www/svjatoslav.eu/maven</url>
+        </snapshotRepository>
+        <repository>
+            <id>svjatoslav.eu</id>
+            <name>svjatoslav.eu</name>
+            <url>scpexe://svjatoslav.eu/var/www/svjatoslav.eu/maven</url>
+        </repository>
+    </distributionManagement>
+
     <repositories>
         <repository>
             <id>svjatoslav.eu</id>
         </repository>
     </repositories>
 
-
-    <distributionManagement>
-        <snapshotRepository>
-            <id>svjatoslav.eu</id>
-            <name>svjatoslav.eu</name>
-            <url>scp://svjatoslav.eu:7022/var/www/maven</url>
-        </snapshotRepository>
-    </distributionManagement>
+    <scm>
+        <connection>scm:git:ssh://git@svjatoslav.eu/home/git/repositories/imagesqueeze.git</connection>
+        <developerConnection>scm:git:ssh://git@svjatoslav.eu/home/git/repositories/imagesqueeze.git
+        </developerConnection>
+    </scm>
 
 </project>
index 0f3857b..355cb76 100755 (executable)
@@ -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<Approximator> {
-
-       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);
+    }
 
 }
index a4f01cc..b5f5fcf 100755 (executable)
@@ -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;
+    }
 
 }
index 08535a2..e1963bc 100755 (executable)
@@ -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;
 
-       }
+    }
 
-};
+}
index 8d206cf..5095855 100755 (executable)
@@ -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;
+    }
 
 }
index 6ba0d1b..256ac26 100755 (executable)
 
 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();
+    }
 
 }
index 53f2d91..24c1e27 100755 (executable)
@@ -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;
+
+    }
 
 }
index 5b0e8db..1ee823d 100755 (executable)
@@ -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);
 
-       }
+    }
 
 }
index 49e9000..c97bb32 100755 (executable)
@@ -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);
+    }
 
 }
index e96d610..693e25c 100755 (executable)
@@ -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++;
+        }
+    }
 
 }
index 4e6e638..b0ca55f 100755 (executable)
 
 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<Table> {
-
-       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);
+        }
+    }
 
 }
index 2b68ef7..d87b736 100755 (executable)
@@ -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();
+        }
+    }
 
 }
index c2ccead..8bfb903 100755 (executable)
 
 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());
+        }
+    }
 
 }
index 0e2ccce..8471a08 100755 (executable)
@@ -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);
-               }
-
-       }
+    }
 
 }