java 1.7图片压缩_Java 实现Huffman压缩解压缩文件 (使用了1.7新特性)

package com.javahuffman;

import java.io.Closeable;

import java.io.File;

import

java.io.FileInputStream;

import

java.io.FileOutputStream;

import

java.io.IOException;

public class JavaHuffman implements

Closeable {

public static int

fromByteArray(byte[] bytes) {

return bytes != null && bytes.length

>= 4 ? fromBytes(bytes[0],

bytes[1], bytes[2], bytes[3]) : 0;

}

public static int

fromBytes(byte b1, byte b2, byte b3, byte b4) {

return b1 << 24 | (b2

& 0xFF) << 16 | (b3 & 0xFF) << 8 | (b4 &

0xFF);

}

public static byte[]

toByteArray(int value) {

return new byte[] { (byte) (value >> 24), (byte) (value >> 16),

(byte) (value >> 8),

(byte) value };

}

public final static int NodesCount = 2 * 256 -

1;

public final static boolean DEBUG = false;

public class Node {

public Integer Parent = -1;

public Integer Count = 0;

public Integer LeftChild = -1;

public Integer RightChild = -1;

public StringBuilder

Code = new

StringBuilder();

}

protected String

escapeChar(Character character) {

StringBuilder result = new

StringBuilder();

if (character == '\"') {

result.append("\\\"");

} else if (character == '\\') {

result.append("\\\\");

} else if (character == '/') {

result.append("\\/");

} else if (character == '\b') {

result.append("\\b");

} else if (character == '\f') {

result.append("\\f");

} else if (character == '\n') {

result.append("\\n");

} else if (character == '\r') {

result.append("\\r");

} else if (character == '\t') {

result.append("\\t");

} else if (character >= 0 && character <

' ' || character >= 127) {

result.append("0x" +

(Integer.toHexString(character)));

} else {

result.append(character);

}

return result.toString();

}

protected int buildtree(Node[] nodes, int

total) {

int root = -1;

if (nodes != null) {

for (int p = (NodesCount + 1) / 2; p

<= NodesCount; p++) {

// 1. find s1 and s2

int s1 = -1, s2 = -1;

int min =

Integer.MAX_VALUE;

for (int i = 0; i < p; i++) {

if (nodes[i].Count > 0 && nodes[i].Count < min

&& nodes[i].Parent ==

-1) {

min = nodes[i].Count;

s1 = i;

}

}

min = Integer.MAX_VALUE;

for (int i = 0; i < p; i++) {

if (i != s1 &&

nodes[i].Count > 0 &&

nodes[i].Count < min

&& nodes[i].Parent ==

-1) {

min = nodes[i].Count;

s2 = i;

}

}

if (s1 >= 0 && s2

>= 0) {

nodes[s1].Parent = p;

nodes[s2].Parent = p;

nodes[p].LeftChild = s1;

nodes[p].RightChild = s2;

if ((nodes[p].Count = nodes[s1].Count +

nodes[s2].Count) == total) {

root = p;

}

}

}

if (DEBUG) {

for (int i = 0; i < NodesCount;

i++) {

if (nodes[i].Count > 0)

System.out.println("char = " + i +

",\tcount="

+ nodes[i].Count +

",\tparent="

+ nodes[i].Parent +

",\tleft="

+ nodes[i].LeftChild +

",\tright="

+ nodes[i].RightChild);

}

}

for (int t = 0; t < (NodesCount +

1) / 2; t++) {

int k = t;

while (nodes[k].Parent >= 0) {

if (k ==

nodes[nodes[k].Parent].LeftChild) {

nodes[t].Code.append('0');

} else {

nodes[t].Code.append('1');

}

k = nodes[k].Parent;

}

// make reverse!

nodes[t].Code.reverse();

}

if (DEBUG) {

System.out.println("result:");

for (int i = 0; i < (NodesCount +

1) / 2; i++) {

if (nodes[i].Count > 0)

System.out.println("char = ["

+ this.escapeChar(((char) i)) +

"] Count = ["

+ nodes[i].Count +

"] Code = ["

+ nodes[i].Code.toString() +

"]");

}

}

}

return root;

}

public void round(String plainfilepath, String encodefilepath)

{

this.encode(plainfilepath,

encodefilepath);

this.decode(plainfilepath +

".ret", encodefilepath);

}

public void decode(String plainfilepath, String

encodefilepath) {

File encodefile = new

File(encodefilepath);

if (encodefile.exists())

{

File plainfile = new

File(plainfilepath);

boolean outputReady =

false;

if (!plainfile.exists())

{

try {

outputReady = plainfile.createNewFile();

} catch (IOException e) {

}

} else {

outputReady = true;

}

if (outputReady) {

try (FileInputStream

inputStream = new FileInputStream(

encodefile);

FileOutputStream outputStream = new FileOutputStream(

plainfile)) {

if (inputStream.available()

>= 4) {

byte[] values = new byte[4];

inputStream.read(values);

String signatureString = new

String(values);

if

(signatureString.equals("HUFF")) {

int total = 0;

if (inputStream.available()

>= 4)

inputStream.read(values);

total = fromByteArray(values);

Node[] nodes = new

Node[NodesCount];

for (int i = 0; i < nodes.length;

i++) {

nodes[i] = new Node();

if (i < (NodesCount+1)/2) {

if (inputStream.available()

>= 4) {

inputStream.read(values);

nodes[i].Count =

fromByteArray(values);

}

}

}

int root = this.buildtree(nodes, total);

int done = 0;

int val =

inputStream.read();

int c = 0;

while (done < total

&& val != -1) {

int idx = root;

while (idx >=

(NodesCount + 1) / 2) {

if ((val & 0x80) ==

0)

idx = nodes[idx].LeftChild;

else {

idx = nodes[idx].RightChild;

}

val <<= 1;

val &= 0xff;

c++;

if (c == 8) {

c = 0;

val = inputStream.read();

}

if (idx >= 0 &&

idx < (NodesCount + 1) / 2) {

// this is the valid

char!

outputStream.write(idx);

done++;

break;

}

}

}

}

}

} catch (IOException e) {

}

}

}

}

public void encode(String plainfilepath, String

encodefilepath) {

File plainfile = new

File(plainfilepath);

if (plainfile.exists()) {

File encodefile = new

File(encodefilepath);

boolean outputReady =

false;

if (!encodefile.exists())

{

try {

outputReady = encodefile.createNewFile();

} catch (IOException e) {

}

} else {

outputReady = true;

}

if (outputReady) {

try (FileInputStream

inputStream = new FileInputStream(

plainfile);

FileOutputStream outputStream = new FileOutputStream(

encodefile)) {

Node[] nodes = new

Node[NodesCount];

for (int i = 0; i < nodes.length;

i++) {

nodes[i] = new Node();

}

@SuppressWarnings("unused")

int total = 0, finished =

0;

int val = 0;

while ((val =

inputStream.read()) != -1) {

int b = 0xff & val;

nodes[b].Count++;

total++;

}

inputStream.getChannel().position(0);

// save magic

outputStream

.write("HUFF".getBytes());

finished += 4;

// save total length

outputStream.write(toByteArray(total));

finished += 4;

// 1k space

for (int i = 0; i < (NodesCount +

1) / 2; i++) {

outputStream.write(toByteArray(nodes[i].Count));

}

finished += (NodesCount + 1)

/ 2 * 4;

this.buildtree(nodes,

total);

// write others

int v = 0;

int c = 0;

while ((val =

inputStream.read()) != -1) {

int b = 0xff & val;

StringBuilder builder = nodes[b].Code;

for (int z = 0; z< builder.length();z++) {

v <<= 1;

if (builder.charAt(z) ==

'1') {

v |= 1;

} else {

v |= 0;

}

c++;

if (c == 8) {

outputStream.write(v);

finished++;

v = 0;

c = 0;

}

}

}

if (c > 0) {

v <<= (8 - c);

outputStream.write(v);

finished++;

}

if (DEBUG) {

System.out.println("Compress " +

plainfilepath

+ " with " + total +

" bytes" + " into

"

+ encodefilepath + " with " +

finished

+ " bytes; compression ratio

= "

+ (float) finished /

(float) total * 100.0f

+ "%.");

}

} catch (IOException e) {

}

}

}

}

@Override

public void close() throws IOException

{

}

public static void main(String[] args)

{

if (args != null && args.length

<= 1) {

System.out.println("javahuffman

[-e/-d/-r] inputfile encodedfile");

} else {

try (JavaHuffman javaHuffman

= new JavaHuffman()) {

switch (args[0]) {

case "-e":

if (args.length >= 3) {

javaHuffman.encode(args[1], args[2]);

}

break;

case "-d":

if (args.length >= 3) {

javaHuffman.decode(args[1], args[2]);

}

break;

case "-r":

if (args.length >= 3) {

javaHuffman.round(args[1], args[2]);

}

break;

}

} catch (IOException e) {

}

}

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值