Analisis Perbandingan Kompresi Citra Menggunakan Algoritma Deflate Dan Algoritma Arithmetic Coding

A-1

Lampiran A. SOURCE CODE PROGRAM

Frame Utama
package FrameDesign;
import
import
import
import
import
import
import
import
import
import

ArithmeticSkripsi.ArithmeticCompress;
ArithmeticSkripsi.ArithmeticDecompress;
Deflate.DeflateContoh;
java.io.File;

java.io.IOException;
java.util.Date;
java.util.logging.Level;
java.util.logging.Logger;
javax.swing.JFileChooser;
javax.swing.JOptionPane;

public class MainFrame extends javax.swing.JFrame {
public MainFrame() {
initComponents();
}
private void jButton4ActionPerformed(
java.awt.event.ActionEvent evt) {
jFileChooser1 = new JFileChooser();
jFileChooser1.showOpenDialog(this);
if(jFileChooser1.getSelectedFile() != null){
jTextField1.setText(
jFileChooser1.getSelectedFile().getAbsolutePath());
jTextField1.repaint();
if((jComboBox1.getSelectedIndex()==0) &&

(jComboBox2.getSelectedIndex()==0)){
if(!jTextField1.getText().endsWith(".dft")){
jTextField2.setText(
jFileChooser1.getSelectedFile().getAbsolutePath()+".dft");
}
} else if((jComboBox1.getSelectedIndex()==1) &&
(jComboBox2.getSelectedIndex()==0)){
if(!jTextField1.getText().endsWith(".arm")){
jTextField2.setText(
jFileChooser1.getSelectedFile().getAbsolutePath()+".arm");

A-2

}
}
jFileChooser1 = null;
}
private void jTextField1ActionPerformed(
java.awt.event.ActionEvent evt) {
// TODO add your handling code here:

}
private void jButton5ActionPerformed(
java.awt.event.ActionEvent evt) {
jFileChooser2.showOpenDialog(this);
jTextField2.setText(
jFileChooser2.getSelectedFile().getAbsolutePath());
jTextField2.repaint();
}
private void jButton1ActionPerformed(
java.awt.event.ActionEvent evt) {
Date mulai = new Date();
String input = jTextField1.getText();
String output = jTextField2.getText();
if(jComboBox2.getSelectedIndex() == 0){
if(jComboBox1.getSelectedIndex() == 0) {
DeflateContoh dc = new DeflateContoh();
try {
dc.compress(input, output);
Date selesai = new Date();
File temp = new File(input);

Long inputLength = temp.length();
temp = null;
temp = new File(output);
long outputLength = temp.length();
double rasio = ((((inputLength-outputLength)
*10000)/inputLength)/100F);
long waktu = (selesai.getTime()-mulai.getTime());
jTextArea1.setText("Input File: "+inputLength+"\n"+"Output
File:" +outputLength+"\n"+"Rasio: "+ rasio+"%\nwaktu kompresi:"
+waktu+"ms");
jTextArea1.repaint();
JOptionPane.showMessageDialog(this, "Selesai");
}
catch (IOException ex) {
ex.printStackTrace();
}
} else if(jComboBox1.getSelectedIndex() == 1){
try {
ArithmeticCompress.compress(input, output);
Date selesai = new Date();

File temp = new File(input);
Long inputLength = temp.length();
temp = null;
temp = new File(output);
long outputLength = temp.length();
double rasio = ((((inputLength-outputLength)
*10000)/inputLength)/100F);

A-3

long waktu = (selesai.getTime()-mulai.getTime());
jTextArea1.setText("Input File: "+inputLength+"\n"+"Output
File:" +outputLength+"\n"+"Rasio: "+ rasio+"%\nwaktu kompresi:"
+waktu+"ms");
jTextArea1.repaint();
JOptionPane.showMessageDialog(this, "Selesai");
} catch (IOException ex) {
ex.printStackTrace();
}
}

} else if(jComboBox2.getSelectedIndex() == 1){
if(jComboBox1.getSelectedIndex() == 0) {
DeflateContoh dc = new DeflateContoh();
try {
dc.decompress(input, output);
Date selesai = new Date();
File temp = new File(input);
Long inputLength = temp.length();
temp = null;
temp = new File(output);
long outputLength = temp.length();
double rasio = ((((inputLength-outputLength)
*10000)/inputLength)/100F);
long waktu=(selesai.getTime()-mulai.getTime());
jTextArea1.setText("Input File: "+inputLength+"\n"+"Output
File:" +outputLength+"\n"+"Rasio: "+ rasio+"%\nwaktu kompresi:"
+waktu+"ms");
jTextArea1.repaint();
JOptionPane.showMessageDialog(this, "Selesai");
} catch (IOException ex) {

ex.printStackTrace();
}
} else if(jComboBox1.getSelectedIndex() == 1){
try {
ArithmeticDecompress.decompress(input, output);
Date selesai = new Date();
File temp = new File(input);
Long inputLength = temp.length();
temp = null;
temp = new File(output);
long outputLength = temp.length();
double rasio = ((((inputLength-outputLength)
*10000)/inputLength)/100F);
long waktu=(selesai.getTime()-mulai.getTime());
jTextArea1.setText("Input File: "+inputLength+"\n"+"Output
File:" +outputLength+"\n"+"Rasio: "+ rasio+"%\nwaktu kompresi:"
+waktu+"ms");
jTextArea1.repaint();
JOptionPane.showMessageDialog(this, "Selesai");
} catch (IOException ex) {

ex.printStackTrace();
}
}
}
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt)

A-4

{
jTextField1.setText("");
jTextField1.repaint();
jTextField2.setText("");
jTextField2.repaint();
}
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt)
{
this.dispose();
System.exit(0);
}

private void jComboBox1PropertyChange(
java.beans.PropertyChangeEvent evt) {
}
private void jComboBox1ItemStateChanged(
java.awt.event.ItemEvent evt) {
Object item = evt.getItem();
if(item.equals(jComboBox1.getItemAt(0)) &&
jComboBox2.getSelectedIndex()==0){
if("".equals(jTextField2.getText())){
return;
} else if(!jTextField2.getText().endsWith(".dft")){
jTextField2.setText(jTextField2.getText().replaceAll(
".arm", ".dft"));
jTextField2.repaint();
}
} else if(item.equals(jComboBox1.getItemAt(1)) &&
jComboBox2.getSelectedIndex()==0){
if("".equals(jTextField2.getText())){
return;
} else if(!jTextField2.getText().endsWith(".arm")){

jTextField2.setText(jTextField2.getText().replaceAll(
".dft", ".arm"));
jTextField2.repaint();
}
}
}
private void jComboBox1MouseClicked(
java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
if(jComboBox1.getSelectedIndex()==0 &&
jComboBox2.getSelectedIndex()==0){
if("".equals(jTextField2.getText())){
return;
} else if(!jTextField2.getText().endsWith(".dft")){
String replaceAll =
jTextField2.getText().replaceAll(".arm", ".dft");
jTextField2.setText(replaceAll);
jTextField2.repaint();
}
} else if(jComboBox1.getSelectedIndex()==1 &&

jComboBox2.getSelectedIndex()==0){

A-5

if("".equals(jTextField2.getText())){
return;
} else if(!jTextField2.getText().endsWith(".arm")){
String replaceAll =
jTextField2.getText().replaceAll(".dft", ".arm");
jTextField2.setText(replaceAll);
jTextField2.repaint();
}
}
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MainFrame().setVisible(true);
}
});
}
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private

javax.swing.JButton jButton1;
javax.swing.JButton jButton2;
javax.swing.JButton jButton3;
javax.swing.JButton jButton4;
javax.swing.JButton jButton5;
javax.swing.JComboBox jComboBox1;
javax.swing.JComboBox jComboBox2;
javax.swing.JFileChooser jFileChooser1;
javax.swing.JFileChooser jFileChooser2;
javax.swing.JLabel jLabel1;
javax.swing.JLabel jLabel2;
javax.swing.JLabel jLabel3;
javax.swing.JLabel jLabel4;
javax.swing.JLabel jLabel5;
javax.swing.JLabel jLabel6;
javax.swing.JPanel jPanel1;
javax.swing.JScrollPane jScrollPane1;
javax.swing.JTextArea jTextArea1;
javax.swing.JTextField jTextField1;
javax.swing.JTextField jTextField2;

}

ARITHMETIC CODING
Kompresi Arithmetic Coding
package ArithmeticSkripsi;
import
import
import
import
import
import
import
import

java.io.BufferedInputStream;
java.io.BufferedOutputStream;
java.io.File;
java.io.FileInputStream;
java.io.FileOutputStream;
java.io.IOException;
java.io.InputStream;
javax.swing.JFileChooser;

A-6

public class ArithmeticCompress {
public static void compress(String input, String output) throws
IOException {
File inputFile = new File(input);
File outputFile = new File(output);
FrequencyTable freq = getFrequencies(inputFile);
freq.increment(256);
InputStream in = new BufferedInputStream(
new FileInputStream(inputFile));
BitOutputStream out = new BitOutputStream(
new BufferedOutputStream(new FileOutputStream(outputFile)));
try {
writeFrequencies(out, freq);
compress(freq, in, out);
} finally {
out.close();
in.close();
}
}
private static FrequencyTable getFrequencies(File file) throws
IOException {
FrequencyTable freq = new SimpleFrequencyTable(
new int[257]);
InputStream input = new BufferedInputStream(
new FileInputStream(file));
try {
while (true) {
int b = input.read();
if (b == -1)
break;
freq.increment(b);
}
} finally {
input.close();
}
return freq;
}
static void writeFrequencies(
BitOutputStream out, FrequencyTable freq) throws IOException {
for (int i = 0; i < 256; i++)
writeInt(out, 32, freq.get(i));
}

static void compress(
FrequencyTable freq, InputStream in, BitOutputStream out) throws
IOException {
ArithmeticEncoder enc = new ArithmeticEncoder(out);
while (true) {
int b = in.read();
if (b == -1)
break;
enc.write(freq, b);
}
enc.write(freq, 256);

A-7

enc.finish();
private static void writeInt(BitOutputStream out, int numBits, int
value) throws IOException {
if (numBits < 0 || numBits > 32)
throw new IllegalArgumentException();
for (int i = 0; i < numBits; i++)
out.write(value >>> i & 1);
}
public final class ArithmeticEncoder {
public final long STATE_SIZE = 32;
public final long MASK
= (1L = high || (low & MASK) != low || (high & MASK) != high)
throw new AssertionError("Low or high out of
range");
long range = high - low + 1;
if (range < MIN_RANGE || range > MAX_RANGE)
throw new AssertionError("Range out of range");
long total = freq.getTotal();
long symLow = freq.getLow(symbol);
long symHigh = freq.getHigh(symbol);
if (symLow == symHigh)
throw new IllegalArgumentException("Symbol has zero
frequency");
if (total > MAX_TOTAL)
throw new IllegalArgumentException("Cannot code
symbol because total is too large");
long newLow = low + symLow * range / total;
long newHigh = low + symHigh * range / total - 1;
low = newLow;
high = newHigh;
while (((low ^ high) & TOP_MASK) == 0) {
shift();
low = (low 1);
high = ((high >> 1)) | TOP_MASK | 1;
}
}
}

Dekompresi Arithmetic
package ArithmeticSkripsi;
import
import
import
import
import
import
import

java.io.BufferedInputStream;
java.io.BufferedOutputStream;
java.io.File;
java.io.FileInputStream;
java.io.FileOutputStream;
java.io.IOException;
java.io.OutputStream;

public class ArithmeticDecompress {
public static void decompress(String input, String output) throws
IOException {
File inputFile = new File(input);
File outputFile = new File(output);
BitInputStream in = new BitInputStream(new
BufferedInputStream(new FileInputStream(inputFile)));
OutputStream out = new BufferedOutputStream(new
FileOutputStream(outputFile));
try {
FrequencyTable freq = readFrequencies(in);
decompress(freq, in, out);

A-9

} finally {
out.close();
in.close();
}
}

static FrequencyTable readFrequencies(BitInputStream in) throws
IOException {
int[] freqs = new int[257];
for (int i = 0; i < 256; i++)
freqs[i] = readInt(in, 32);
freqs[256] = 1; // EOF symbol
return new SimpleFrequencyTable(freqs);
}

static void decompress(FrequencyTable freq, BitInputStream in,
OutputStream out) throws IOException {
ArithmeticDecoder dec = new ArithmeticDecoder(in);
while (true) {
int symbol = dec.read(freq);
if (symbol == 256)
break;
out.write(symbol);
}
}

private static int readInt(BitInputStream in, int numBits) throws
IOException {
if (numBits < 0 || numBits > 32)
throw new IllegalArgumentException();
int result = 0;
for (int i = 0; i < numBits; i++)
result |= in.readNoEof() 1;
if (freq.getLow(middle) > value)
end = middle;
else
start = middle;
}
if (start == end)
throw new AssertionError();
int symbol = start;
if (freq.getLow(symbol) * range / total > offset ||
freq.getHigh(symbol) * range / total high)
throw new AssertionError("Code out of range");
return symbol;
}

public void shift() throws IOException {
code = ((code >
1)) | readCodeBit();
}

private int readCodeBit() throws IOException {

A-11

int temp = input.read();
if (temp != -1)
return temp;
else
return 0;
}
public void update(CheckedFrequencyTable freq, int symbol) throws
IOException {
if (low >= high || (low & MASK) != low || (
high & MASK) != high)
throw new AssertionError("Low or high out of range");
long range = high - low + 1;
if (range < MIN_RANGE || range > MAX_RANGE)
throw new AssertionError("Range out of range");

long total = freq.getTotal();
long symLow = freq.getLow(symbol);
long symHigh = freq.getHigh(symbol);
if (symLow == symHigh)
throw new IllegalArgumentException("Symbol has zero
frequency");
if (total > MAX_TOTAL)
throw new IllegalArgumentException(
"Cannot code symbol because total is too large");
long newLow = low + symLow * range / total;
long newHigh = low + symHigh * range / total - 1;
low = newLow;
high = newHigh;

while (((low ^ high) & TOP_MASK) == 0) {
shift();
low = (low 1);
high = ((high >> 1)) | TOP_MASK | 1;
}
}
}

File Reader/BitInputStream
package ArithmeticSkripsi;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;

public final class BitInputStream {

A-12

private InputStream input;
or is -1 if the end of stream is reached.
private int nextBits;

private int numBitsRemaining;
private boolean isEndOfStream;

stream.
public BitInputStream(InputStream in) {
if (in == null)
throw new NullPointerException(
"Argument is null");
input = in;
numBitsRemaining = 0;
isEndOfStream = false;
}

available, or -1 if the end of stream is reached. The end of stream
always occurs on a byte boundary.
public int read() throws IOException {
if (isEndOfStream)
return -1;
if (numBitsRemaining == 0) {
nextBits = input.read();
if (nextBits == -1) {
isEndOfStream = true;
return -1;
}
numBitsRemaining = 8;
}
numBitsRemaining--;
return (nextBits >>> numBitsRemaining) & 1;
}

available, or throws an EOFException if the end of stream is reached.
public int readNoEof() throws IOException {
int result = read();
if (result != -1)
return result;
else
throw new EOFException("End of stream reached");
}

public void close() throws IOException {
input.close();
}
}

A-13

BitOutputstream
package ArithmeticSkripsi;
import java.io.IOException;
import java.io.OutputStream;

public final class BitOutputStream {
private OutputStream output;
private int currentByte;
private int numBitsInCurrentByte;

public BitOutputStream(OutputStream out) {
if (out == null)
throw new NullPointerException(
"Argument is null");
output = out;
currentByte = 0;
numBitsInCurrentByte = 0;
}

public void write(int b) throws IOException {
if (!(b == 0 || b == 1))
throw new IllegalArgumentException(
"Argument must be 0 or 1");
currentByte = currentByte