// Copyright 2001, FreeHEP. package org.freehep.util.io; import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; /** * The RunLengthOutputStream encodes data as Run Length encoding. The exact * definition of Run Length encoding can be found in the PostScript Language * Reference (3rd ed.) chapter 3.13.3. * * @author Mark Donszelmann * @version $Id: RunLengthOutputStream.java 8584 2006-08-10 23:06:37Z duns $ */ public class RunLengthOutputStream extends FilterOutputStream implements RunLength, FinishableOutputStream { private boolean end; private int[] buffer = new int[LENGTH]; private int index; private int last; private int count; /** * Create a Run Length output stream * * @param out stream to write */ public RunLengthOutputStream(OutputStream out) { super(out); end = false; index = 0; last = -1; count = 1; } public void write(int a) throws IOException { a &= 0x00FF; if (last > 0) { if (a == last) { // counting writeBuffer(); count++; if (count >= LENGTH) { writeCount(); } } else { // buffering if (count > 1) { writeCount(); } else { buffer[index] = last; index++; if (index >= LENGTH) { writeBuffer(); } } } } last = a; } public void finish() throws IOException { if (!end) { end = true; writeCount(); writeBuffer(); // we may have one character left in "last" (FREEHEP-578) if (last >= 0) { super.write(0); super.write(last); } super.write(EOD); flush(); if (out instanceof FinishableOutputStream) { ((FinishableOutputStream) out).finish(); } } } public void close() throws IOException { finish(); super.close(); } private void writeBuffer() throws IOException { if (index > 0) { super.write(index - 1); for (int i = 0; i < index; i++) { super.write((byte) buffer[i]); } } index = 0; } private void writeCount() throws IOException { if (count > 1) { super.write(257 - count); super.write(last); last = -1; } count = 1; } }