diff --git a/.idea/artifacts/huffman.xml b/.idea/artifacts/huffman.xml
new file mode 100644
index 0000000..b22b960
--- /dev/null
+++ b/.idea/artifacts/huffman.xml
@@ -0,0 +1,20 @@
+
+
+ $PROJECT_DIR$/classes/artifacts/huffman
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..23c53dd
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..15a15b2
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Maven__junit_junit_4_11.xml b/.idea/libraries/Maven__junit_junit_4_11.xml
new file mode 100644
index 0000000..f33320d
--- /dev/null
+++ b/.idea/libraries/Maven__junit_junit_4_11.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml b/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml
new file mode 100644
index 0000000..f58bbc1
--- /dev/null
+++ b/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..ff20635
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..776d85c
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..e96534f
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000..77e1638
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,796 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1552783039293
+
+
+ 1552783039293
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ huffman
+
+
+
+
+
+
+
+
+
+
+
+
+ No facets are configured
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1.7
+
+
+
+
+
+
+
+
+
+
+
+ huffman
+
+
+
+
+
+
+
+
+
+
+
+
+ Maven: junit:junit:4.11
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/HuffmanDecompressSample.gif b/HuffmanDecompressSample.gif
new file mode 100644
index 0000000..f97965f
Binary files /dev/null and b/HuffmanDecompressSample.gif differ
diff --git a/HuffmanSample.gif b/HuffmanSample.gif
new file mode 100644
index 0000000..44cdd1c
Binary files /dev/null and b/HuffmanSample.gif differ
diff --git a/README.md b/README.md
index 2494219..e27012e 100644
--- a/README.md
+++ b/README.md
@@ -1,109 +1,16 @@
-huffman
-=======
-
-This is a huffman encoder, decoder, input and output streams written in java. Nothing special, this project
-has purely educational purpose. Not a rocket science but I hope somebody will find it useful.
-
-Just to remind what huffman coding is: it's an entropy encoding algorithm for loseless data compression.
-
-
-HuffmanDemo
-=======
-HuffmanDemo program demonstrates the basic principles of usage of Huffman input and output streams (see its source code for
-more details):
-
- % mvn clean package
- ...
- % java -jar target/huffman-1.0-SNAPSHOT.jar
- USAGE: HuffmanDemo enc|dec|entropy
- enc : encode input file and save
- the results to output file
- dec : decode input file and save
- the results to output file
- entropy : calculate an entropy of the symbols in input file
-
-I downloaded Charles Dickens book "A tale of two cities" from the project gutenberg (http://www.gutenberg.org/ebooks/98)
-to demonstrate how HuffmanDemo works (Think about it as a little compensation for lack of classic literature in computer science...)
-
-So, as you can see from the program output above, HuffmanDemo can do a few things:
-
-Entropy
--------
-
-It can calculate an entropy rate of the data to be compressed (http://en.wikipedia.org/wiki/Entropy_(information_theory)).
-In other words, the measurement of randomntess of the data or an optimal number of bits required to store one symbol of the data.
-Note that loseless compression algorithm can not compress data into more than entropy rate multiplied by the length of data bits.
-
-Obviously, an english text ("A tale of two cities") has low entropy => it can be compressed very efficiently. According to what
-HuffmanDemo says, it can be compressed almost up to 50% of its original size.
-
- % java -jar target/huffman-1.0-SNAPSHOT.jar entropy pg98.txt
- Entropy: 4.54
-
-On the other hand, digital images and texts which are mostly already compressed have high entropy => very low compression rate:
-
- % java -jar target/huffman-1.0-SNAPSHOT.jar entropy pg98.txt.gz
- Entropy: 8.00
-
- % java -jar target/huffman-1.0-SNAPSHOT.jar entropy photo.jpeg
- Entropy: 7.87
-
-
-Compression and Decompression
------------------------------
-
-Compression:
-
- % java -jar target/huffman-1.0-SNAPSHOT.jar enc pg98.txt pg98.huffman
- Compression: done
- Original file size: 792927
- Compressed file size: 455349
- Compression efficiency: 42.57%
-
-And decompression:
-
- % java -jar target/huffman-1.0-SNAPSHOT.jar dec pg98.huffman pg98.dec.txt
- Decompression: done
- Original file size: 455349
- Decompressed file size: 792927
-
- % diff -Naur pg98.txt pg98.dec.txt
- % echo $?
- 0
-
-Huffman input and output streams
-=======
-
-Huffman input and output streams perform transparent data encoding and decoding using Huffman algorithm. Basically they work in
-almost the same way as ZipInputStream and ZipOutputStream. Easy peasy:
-
-```java
-// Encoding
-InputStream in = new FileInputStream(inFile);
-HuffmanOutputStream hout = new HuffmanOutputStream(new FileOutputStream(outFile));
-byte buf[] = new byte[4096];
-int len;
-
-while ((len = in.read(buf)) != -1)
- hout.write(buf, 0, len);
-
-in.close();
-hout.close();
-```
-
-```java
-// Decoding
-HuffmanInputStream hin = new HuffmanInputStream(new FileInputStream(inFile));
-OutputStream out = new FileOutputStream(outFile);
-byte buf[] = new byte[4096];
-int len;
-
-while ((len = hin.read(buf)) != -1)
- out.write(buf, 0, len);
-
-hin.close();
-out.close();
-```
-
-If you don't need streams or if you want to just encode/decode, say, integers instead of bytes, feel free to use lower level abstractions, namely, HuffmanEncoder and HuffmanDecoder. I not sure how to use them, see the source code of HuffmanOutputStream and HuffmanInputStream
-respectively.
+Huffman Compression UI program based on javafx
+------
+This is a UI program to show how to compress file by Huffman coding algorithm.
+
+How to use it
+------
+Open the jar file,
+When you want to compress file, select the compresssion tab. You can either drag a file to the drag file archive area or click compress button to select the file you want to compress. In the description area, you will find the detail information about compression. At the same time, the compressed file end with .huf is created in the same path of the original file path.
+When you want to decompress file, select the decompression tab. Drag the compressed file end with .huf to the drag file archive area or click decompress button to select the compressed file end with .huf you want. At the same time, the original file will be recovered in the same path of the original compressed file.
+
+Running effect
+------
+### Compression
+
+### Decompression
+
diff --git a/classes/artifacts/huffman/huffman.html b/classes/artifacts/huffman/huffman.html
new file mode 100644
index 0000000..dd4607f
--- /dev/null
+++ b/classes/artifacts/huffman/huffman.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+Test page for huffman
+ Webstart: click to launch this app as webstart
+
+
+
+
diff --git a/classes/artifacts/huffman/huffman.jar b/classes/artifacts/huffman/huffman.jar
new file mode 100644
index 0000000..c8c3b24
Binary files /dev/null and b/classes/artifacts/huffman/huffman.jar differ
diff --git a/classes/artifacts/huffman/huffman.jnlp b/classes/artifacts/huffman/huffman.jnlp
new file mode 100644
index 0000000..bdf2771
--- /dev/null
+++ b/classes/artifacts/huffman/huffman.jnlp
@@ -0,0 +1,15 @@
+
+
+
+ JHufCompression
+ Unknown
+ huffman
+
+
+
+
+
+
+
+
+
diff --git a/huffman.iml b/huffman.iml
new file mode 100644
index 0000000..d2667c3
--- /dev/null
+++ b/huffman.iml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/UiController.fxml b/res/UiController.fxml
new file mode 100755
index 0000000..c478d14
--- /dev/null
+++ b/res/UiController.fxml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/compressPage.fxml b/res/compressPage.fxml
new file mode 100755
index 0000000..66601da
--- /dev/null
+++ b/res/compressPage.fxml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/cry_face.png b/res/cry_face.png
new file mode 100644
index 0000000..011fa09
Binary files /dev/null and b/res/cry_face.png differ
diff --git a/res/decompressPage.fxml b/res/decompressPage.fxml
new file mode 100755
index 0000000..ca25257
--- /dev/null
+++ b/res/decompressPage.fxml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drag_in_cursor.png b/res/drag_in_cursor.png
new file mode 100644
index 0000000..da367e6
Binary files /dev/null and b/res/drag_in_cursor.png differ
diff --git a/res/drop_archive_bg.png b/res/drop_archive_bg.png
new file mode 100644
index 0000000..fc5f3e9
Binary files /dev/null and b/res/drop_archive_bg.png differ
diff --git a/res/smile_face.png b/res/smile_face.png
new file mode 100644
index 0000000..e5eabfb
Binary files /dev/null and b/res/smile_face.png differ
diff --git a/src/main/java/com/group8/project/ui/CompressPage.java b/src/main/java/com/group8/project/ui/CompressPage.java
new file mode 100755
index 0000000..49684cf
--- /dev/null
+++ b/src/main/java/com/group8/project/ui/CompressPage.java
@@ -0,0 +1,135 @@
+package com.group8.project.ui;
+
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.Cursor;
+import javafx.scene.ImageCursor;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.DragEvent;
+import javafx.scene.input.Dragboard;
+import javafx.scene.input.TransferMode;
+import javafx.stage.FileChooser;
+import org.dk.huffman.HuffmanOutputStream;
+
+import java.io.*;
+
+public class CompressPage {
+
+ public static final String HUF_SUFFIX = ".huf";
+
+ @FXML
+ private Button compress_btn;
+
+ @FXML
+ private Label compress_description;
+
+ @FXML
+ private ImageView compress_result_img;
+
+ @FXML
+ void setOnDragEntered(DragEvent event) {
+ Dragboard dragboard = event.getDragboard();
+ if(dragboard.hasFiles()) {
+ Image image = new Image("drag_in_cursor.png");
+
+ Scene scene = compress_btn.getScene();
+ scene.setCursor(new ImageCursor(image,
+ image.getWidth() / 2,
+ image.getHeight() /2));
+ }
+ event.consume();
+ }
+
+ @FXML
+ void setOnDragExited(DragEvent event) {
+ compress_btn.getScene().setCursor(Cursor.DEFAULT);
+ event.consume();
+ }
+
+ @FXML
+ void setOnDragOver(DragEvent event) {
+ Dragboard dragboard = event.getDragboard();
+ if(dragboard.hasFiles()) {
+ event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
+ }
+ event.consume();
+ }
+
+ @FXML
+ void setOnDragDropped(DragEvent event) {
+ compress_btn.getScene().setCursor(Cursor.DEFAULT);
+ Dragboard dragboard = event.getDragboard();
+ boolean success = false;
+ if(dragboard.hasFiles()) {
+ File file = dragboard.getFiles().get(0);
+ if(file.exists() && !file.getName().endsWith(HUF_SUFFIX)) {
+ String oldPath = file.getAbsolutePath();
+ String suffix = oldPath.substring(oldPath.lastIndexOf("."));
+ String newPath = oldPath.replace(suffix, HUF_SUFFIX);
+ try {
+ doCompress(oldPath, newPath);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ success = true;
+ }
+ event.setDropCompleted(success);
+
+ event.consume();
+ }
+
+ @FXML
+ void compress(ActionEvent event) {
+ FileChooser fileChooser = new FileChooser();
+ fileChooser.setTitle("Choose the file you want to compress");
+ File file = fileChooser.showOpenDialog(compress_btn.getScene().getWindow());
+ if(file != null && file.exists() && !file.getName().endsWith(HUF_SUFFIX)) {
+ String oldPath = file.getAbsolutePath();
+ String suffix = oldPath.substring(oldPath.lastIndexOf("."));
+ String newPath = oldPath.replace(suffix, HUF_SUFFIX);
+ try {
+ doCompress(oldPath, newPath);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private void doCompress(String originFile, String compressedFile) throws IOException {
+ File inFile = new File(originFile);
+ File outFile = new File(compressedFile);
+ InputStream in = new FileInputStream(inFile);
+ HuffmanOutputStream hout = new HuffmanOutputStream(
+ new FileOutputStream(outFile), inFile.getName());
+ byte buf[] = new byte[4096];
+ int len;
+
+ while ((len = in.read(buf)) != -1)
+ hout.write(buf, 0, len);
+
+ in.close();
+ hout.close();
+
+ StringBuffer descrpition = new StringBuffer();
+ descrpition.append("Compression: done\n");
+ descrpition.append("Original file size: " + inFile.length() + "\n");
+ descrpition.append("Compressed file size: " + outFile.length() + "\n");
+ descrpition.append("Compression efficiency: ");
+ if (inFile.length() > outFile.length()) {
+ descrpition.append(String.format("%.2f%%\n",
+ (100.0 - (((double) outFile.length() / (double) inFile.length()) * 100))));
+ compress_result_img.setImage(new Image("smile_face.png"));
+ }
+ else {
+ descrpition.append("none");
+ compress_result_img.setImage(new Image("cry_face.png"));
+ }
+ compress_description.setText(descrpition.toString());
+ }
+
+}
diff --git a/src/main/java/com/group8/project/ui/DecompressPage.java b/src/main/java/com/group8/project/ui/DecompressPage.java
new file mode 100755
index 0000000..4304fa1
--- /dev/null
+++ b/src/main/java/com/group8/project/ui/DecompressPage.java
@@ -0,0 +1,140 @@
+package com.group8.project.ui;
+
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.Cursor;
+import javafx.scene.ImageCursor;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.DragEvent;
+import javafx.scene.input.Dragboard;
+import javafx.scene.input.TransferMode;
+import javafx.stage.FileChooser;
+import org.dk.huffman.HuffmanInputStream;
+
+import java.io.*;
+
+public class DecompressPage {
+
+ @FXML
+ private Button decompress_btn;
+
+ @FXML
+ private ImageView compress_result_img;
+
+ @FXML
+ private Label decompress_description;
+
+ @FXML
+ void setOnDragEntered(DragEvent event) {
+ Dragboard dragboard = event.getDragboard();
+ if(dragboard.hasFiles() && dragboard.getFiles().get(0).getName().endsWith(CompressPage.HUF_SUFFIX)) {
+ Image image = new Image("drag_in_cursor.png");
+
+ Scene scene = decompress_btn.getScene();
+ scene.setCursor(new ImageCursor(image,
+ image.getWidth() / 2,
+ image.getHeight() /2));
+ }
+ event.consume();
+ }
+
+ @FXML
+ void setOnDragExited(DragEvent event) {
+ decompress_btn.getScene().setCursor(Cursor.DEFAULT);
+ event.consume();
+ }
+
+ @FXML
+ void setOnDragOver(DragEvent event) {
+ Dragboard dragboard = event.getDragboard();
+ if(dragboard.hasFiles()) {
+ event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
+ }
+ event.consume();
+ }
+
+ @FXML
+ void setOnDragDropped(DragEvent event) {
+ decompress_btn.getScene().setCursor(Cursor.DEFAULT);
+ Dragboard dragboard = event.getDragboard();
+ boolean success = false;
+ if(dragboard.hasFiles()) {
+ File file = dragboard.getFiles().get(0);
+ if (file.exists() && file.getName().endsWith(CompressPage.HUF_SUFFIX)) {
+ String oldPath = file.getAbsolutePath();
+ try {
+ doDecompress(oldPath);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ success = true;
+ }
+ event.setDropCompleted(success);
+
+ event.consume();
+ }
+
+ @FXML
+ void deCompress(ActionEvent event) {
+ FileChooser fileChooser = new FileChooser();
+ fileChooser.setTitle("Choose the file end with .huf");
+ fileChooser.getExtensionFilters().addAll(
+ new FileChooser.ExtensionFilter("HUF", "*.huf")
+ );
+ File file = fileChooser.showOpenDialog(decompress_btn.getScene().getWindow());
+ if (file != null && file.exists() && file.getName().endsWith(CompressPage.HUF_SUFFIX)) {
+ String oldPath = file.getAbsolutePath();
+ try {
+ doDecompress(oldPath);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private void doDecompress(String originFile) throws IOException {
+ File inFile = new File(originFile);
+ HuffmanInputStream hin = new HuffmanInputStream(new FileInputStream(
+ inFile));
+ File outFile = null;
+ OutputStream out = null;
+ byte buf[] = new byte[4096];
+ int len;
+
+ while ((len = hin.read(buf)) != -1) {
+ if(!hin.getFileName().isEmpty() && out == null) {
+ outFile = new File(fixFileName(inFile.getParent() + File.separator + hin.getFileName()));
+ out = new FileOutputStream(outFile);
+ }
+ if(out != null)
+ out.write(buf, 0, len);
+ }
+
+
+ hin.close();
+ out.close();
+
+ StringBuffer descrpition = new StringBuffer();
+ descrpition.append("Decompression: done\n");
+ descrpition.append("Original file size: " + inFile.length() + "\n");
+ descrpition.append("Decompressed file size: " + outFile.length());
+ compress_result_img.setImage(new Image("smile_face.png"));
+ decompress_description.setText(descrpition.toString());
+ }
+
+ private String fixFileName(String fileName) {
+ StringBuilder buff = new StringBuilder();
+ String suffix = fileName.substring(fileName.lastIndexOf("."));
+ StringBuilder prefix = new StringBuilder(fileName.substring(0, fileName.lastIndexOf(".")));
+ prefix.append("_1");
+ buff.append(prefix);
+ buff.append(suffix);
+ return buff.toString();
+ }
+
+}
diff --git a/src/main/java/com/group8/project/ui/UiController.java b/src/main/java/com/group8/project/ui/UiController.java
new file mode 100644
index 0000000..940cb29
--- /dev/null
+++ b/src/main/java/com/group8/project/ui/UiController.java
@@ -0,0 +1,27 @@
+package com.group8.project.ui;
+
+import javafx.application.Application;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+/**
+ * This project was edited by Dong Wang
+ * I add gui to show Huffman Compression by javafx
+ */
+
+public class UiController extends Application {
+
+ public void start(Stage primaryStage) throws Exception {
+ Parent root = FXMLLoader.load(getClass().
+ getResource("/UiController.fxml"));
+ primaryStage.setTitle("Welcome to JHufCompress!");
+ primaryStage.setScene(new Scene(root,700,320));
+ primaryStage.show();
+ }
+
+ public static void main(String[] args) {
+ launch(args);
+ }
+}
diff --git a/src/main/java/org/dk/huffman/BitInputStream.java b/src/main/java/org/dk/huffman/BitInputStream.java
old mode 100644
new mode 100755
diff --git a/src/main/java/org/dk/huffman/BitOutputStream.java b/src/main/java/org/dk/huffman/BitOutputStream.java
old mode 100644
new mode 100755
diff --git a/src/main/java/org/dk/huffman/HFreqTable.java b/src/main/java/org/dk/huffman/HFreqTable.java
old mode 100644
new mode 100755
diff --git a/src/main/java/org/dk/huffman/HuffmanConsts.java b/src/main/java/org/dk/huffman/HuffmanConsts.java
old mode 100644
new mode 100755
diff --git a/src/main/java/org/dk/huffman/HuffmanDecoder.java b/src/main/java/org/dk/huffman/HuffmanDecoder.java
old mode 100644
new mode 100755
diff --git a/src/main/java/org/dk/huffman/HuffmanDemo.java b/src/main/java/org/dk/huffman/HuffmanDemo.java
old mode 100644
new mode 100755
diff --git a/src/main/java/org/dk/huffman/HuffmanEncoder.java b/src/main/java/org/dk/huffman/HuffmanEncoder.java
old mode 100644
new mode 100755
diff --git a/src/main/java/org/dk/huffman/HuffmanInputStream.java b/src/main/java/org/dk/huffman/HuffmanInputStream.java
old mode 100644
new mode 100755
index 1dc5365..12caf81
--- a/src/main/java/org/dk/huffman/HuffmanInputStream.java
+++ b/src/main/java/org/dk/huffman/HuffmanInputStream.java
@@ -16,6 +16,8 @@ public class HuffmanInputStream extends FilterInputStream {
protected byte[] segment;
protected int bytesRead;
protected boolean eof;
+ protected boolean isReadFileName = false;
+ protected String fileName;
/**
* Initialize the huffman input stream.
@@ -26,6 +28,7 @@ public HuffmanInputStream(InputStream in) {
bytesRead = 0;
segment = null;
eof = false;
+ isReadFileName = false;
}
@Override
@@ -61,10 +64,26 @@ public int read(byte[] b, int off, int len) throws IOException {
return rdLen;
}
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ private String readFileName(DataInputStream dataIn) throws IOException {
+ byte length = dataIn.readByte();
+ byte[] data = new byte[length];
+
+ dataIn.read(data);
+ return new String(data);
+ }
// read next huffman segment
protected void readSegment() throws IOException {
DataInputStream dataIn = new DataInputStream(in);
+ if(!isReadFileName) {
+ fileName = readFileName(dataIn);
+ isReadFileName = true;
+ }
try {
// ensure that segment header is valid
diff --git a/src/main/java/org/dk/huffman/HuffmanNode.java b/src/main/java/org/dk/huffman/HuffmanNode.java
old mode 100644
new mode 100755
diff --git a/src/main/java/org/dk/huffman/HuffmanOutputStream.java b/src/main/java/org/dk/huffman/HuffmanOutputStream.java
old mode 100644
new mode 100755
index db5c875..2a964ed
--- a/src/main/java/org/dk/huffman/HuffmanOutputStream.java
+++ b/src/main/java/org/dk/huffman/HuffmanOutputStream.java
@@ -21,6 +21,8 @@
public class HuffmanOutputStream extends FilterOutputStream {
protected byte[] segment;
protected int bytesWritten;
+ protected boolean isWriteFileName = false;
+ protected String fileName;
/**
* Initialize a huffman output stream.
@@ -32,6 +34,22 @@ public class HuffmanOutputStream extends FilterOutputStream {
public HuffmanOutputStream(OutputStream out) {
super(out);
constructHuffman(HuffmanConsts.DEFAULT_SEGMENT_SIZE_KB);
+ isWriteFileName = false;
+ }
+
+ /**
+ * Initialize a huffman output stream.
+ * Note: default segment size will be used for buffer
+ * @param out parent output stream
+ * @param fileName file name of origin file
+ * @see FilterOutputStream
+ * @see HuffmanConsts
+ */
+ public HuffmanOutputStream(OutputStream out, String fileName) {
+ super(out);
+ constructHuffman(HuffmanConsts.DEFAULT_SEGMENT_SIZE_KB);
+ this.fileName = fileName;
+ isWriteFileName = false;
}
/**
@@ -44,11 +62,13 @@ public HuffmanOutputStream(OutputStream out) {
public HuffmanOutputStream(OutputStream out, int bufsizeKB) {
super(out);
constructHuffman(bufsizeKB);
+ isWriteFileName = false;
}
private void constructHuffman(int segmentSizeKb) {
segment = new byte[segmentSizeKb * 1024];
bytesWritten = 0;
+ isWriteFileName = false;
}
/**
@@ -60,6 +80,11 @@ public int getBufSize() {
@Override
public void write(int b) throws IOException {
+ if(!isWriteFileName && !fileName.isEmpty()) {
+ writeFileName(fileName);
+ isWriteFileName = true;
+ }
+
segment[bytesWritten++] = (byte) b;
if (bytesWritten == segment.length)
writeSegment();
@@ -69,8 +94,17 @@ public void write(int b) throws IOException {
public void flush() throws IOException {
writeSegment();
}
+
+ private void writeFileName(String fileName) throws IOException {
+ if(!fileName.isEmpty()) {
+ DataOutputStream dataOut = new DataOutputStream(out);
+ dataOut.writeByte(fileName.getBytes().length);
+ dataOut.write(fileName.getBytes());
+ }
+ }
protected void writeSegment() throws IOException {
+ DataOutputStream dataOut = new DataOutputStream(out);
if (bytesWritten == 0)
return;
@@ -81,7 +115,6 @@ protected void writeSegment() throws IOException {
freqTable.add(segment[i]);
// write segment header at first
- DataOutputStream dataOut = new DataOutputStream(out);
dataOut.writeInt(HuffmanConsts.HUFFMAN_MAGIC1);
dataOut.writeInt(bytesWritten);
freqTable.save(dataOut);
diff --git a/src/main/java/org/dk/huffman/HuffmanTree.java b/src/main/java/org/dk/huffman/HuffmanTree.java
old mode 100644
new mode 100755
diff --git a/src/main/java/org/dk/huffman/Pair.java b/src/main/java/org/dk/huffman/Pair.java
old mode 100644
new mode 100755
diff --git a/target/test-classes/org/dk/huffman/BitStreamsTest.class b/target/test-classes/org/dk/huffman/BitStreamsTest.class
new file mode 100644
index 0000000..6d1c65f
Binary files /dev/null and b/target/test-classes/org/dk/huffman/BitStreamsTest.class differ
diff --git a/target/test-classes/org/dk/huffman/HFreqTableTest.class b/target/test-classes/org/dk/huffman/HFreqTableTest.class
new file mode 100644
index 0000000..179d893
Binary files /dev/null and b/target/test-classes/org/dk/huffman/HFreqTableTest.class differ
diff --git a/target/test-classes/org/dk/huffman/HuffmanEncodeDecodeTest.class b/target/test-classes/org/dk/huffman/HuffmanEncodeDecodeTest.class
new file mode 100644
index 0000000..74e7176
Binary files /dev/null and b/target/test-classes/org/dk/huffman/HuffmanEncodeDecodeTest.class differ
diff --git a/target/test-classes/org/dk/huffman/HuffmanIOTest.class b/target/test-classes/org/dk/huffman/HuffmanIOTest.class
new file mode 100644
index 0000000..58efc1f
Binary files /dev/null and b/target/test-classes/org/dk/huffman/HuffmanIOTest.class differ