Sketcher2 source code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
3.0 KiB

package com.jotuntech.sketcher.client;
import java.io.DataOutput;
import java.io.IOException;
import java.io.OutputStream;
public class PackBitsOutputStream extends OutputStream {
private DataOutput mdo;
private final static int IN_BUFFER_SIZE = 2048;
private final static int IN_BUFFER_MASK = IN_BUFFER_SIZE - 1;
private final static int OUT_BUFFER_SIZE = 4096;
private int[] inBuffer;
private int inBufferWritePos, inBufferReadPos, inBufferMark;
private byte[] outBuffer;
private int outBufferWritePos;
public PackBitsOutputStream(DataOutput mdo) {
this.mdo = mdo;
this.inBuffer = new int[IN_BUFFER_SIZE];
this.inBufferWritePos = 0;
this.inBufferReadPos = 0;
this.inBufferMark = 0;
this.outBuffer = new byte[OUT_BUFFER_SIZE];
this.outBufferWritePos = 0;
}
public void write(int b) throws IOException {
inBuffer[inBufferWritePos++ & IN_BUFFER_MASK] = b;
if(inBufferWritePos - inBufferReadPos == IN_BUFFER_SIZE) {
pack();
}
}
public void write(byte[] b) throws IOException {
for(int i = 0; i < b.length; i++) {
inBuffer[inBufferWritePos++ & IN_BUFFER_MASK] = b[i];
if(inBufferWritePos - inBufferReadPos == IN_BUFFER_SIZE) {
pack();
}
}
}
public void write(byte[] b, int off, int len) throws IOException {
for(int i = off; i < off + len; i++) {
inBuffer[inBufferWritePos++ & IN_BUFFER_MASK] = b[i];
if(inBufferWritePos - inBufferReadPos == IN_BUFFER_SIZE) {
pack();
}
}
}
public void flush() throws IOException {
pack();
}
private void output(int b) {
outBuffer[outBufferWritePos++] = (byte) b;
}
private void pack() throws IOException {
outBufferWritePos = 0;
while(available() > 0) {
int b = read();
int repeat = 1;
while(available() > 0 && peek() == b && repeat < 128) {
++repeat;
skip();
}
if(repeat == 1) {
mark();
int b2 = read();
int literal = 0;
while(available() > 0 && peek() != b2 && literal < 127) {
b2 = read();
++literal;
}
if(available() == 0 && literal < 127) {
++literal;
}
if(literal == 0) {
reset();
output(0);
output(b);
} else {
reset();
output(literal);
output(b);
for(int i = 0; i < literal; i++) {
output(read());
}
}
} else if(repeat == 2) {
output(1);
output(b);
output(b);
} else {
output(1 - repeat);
output(b);
}
}
mdo.write(outBuffer, 0, outBufferWritePos);
}
public void close() throws IOException {
pack();
}
private int available() {
return inBufferWritePos - inBufferReadPos;
}
private int peek() {
return inBuffer[inBufferReadPos & IN_BUFFER_MASK];
}
private int read() {
return inBuffer[inBufferReadPos++ & IN_BUFFER_MASK];
}
private void skip() {
++inBufferReadPos;
}
private void mark() {
inBufferMark = inBufferReadPos;
}
private void reset() {
inBufferReadPos = inBufferMark;
}
}