]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Move here from org.apache.fop.render.ps
authorJeremias Maerki <jeremias@apache.org>
Fri, 4 Jul 2003 20:01:07 +0000 (20:01 +0000)
committerJeremias Maerki <jeremias@apache.org>
Fri, 4 Jul 2003 20:01:07 +0000 (20:01 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@196599 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/util/ASCII85Constants.java [new file with mode: 0644]
src/java/org/apache/fop/util/ASCII85InputStream.java [new file with mode: 0644]
src/java/org/apache/fop/util/ASCII85OutputStream.java [new file with mode: 0644]
src/java/org/apache/fop/util/ASCIIHexOutputStream.java [new file with mode: 0644]
src/java/org/apache/fop/util/Finalizable.java [new file with mode: 0644]
src/java/org/apache/fop/util/FlateEncodeOutputStream.java [new file with mode: 0644]
src/java/org/apache/fop/util/RunLengthEncodeOutputStream.java [new file with mode: 0644]

diff --git a/src/java/org/apache/fop/util/ASCII85Constants.java b/src/java/org/apache/fop/util/ASCII85Constants.java
new file mode 100644 (file)
index 0000000..e36f686
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * $Id$
+ * ============================================================================
+ *                    The Apache Software License, Version 1.1
+ * ============================================================================
+ * 
+ * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment: "This product includes software
+ *    developed by the Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ * 
+ * 4. The names "FOP" and "Apache Software Foundation" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    apache@apache.org.
+ * 
+ * 5. Products derived from this software may not be called "Apache", nor may
+ *    "Apache" appear in their name, without prior written permission of the
+ *    Apache Software Foundation.
+ * 
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ * 
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation and was originally created by
+ * James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ * Software Foundation, please see <http://www.apache.org/>.
+ */ 
+package org.apache.fop.util;
+
+/**
+ * This interface defines constants used by the ASCII85 filters.
+ *
+ * @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a>
+ * @version $Id$
+ */
+public interface ASCII85Constants {
+
+    /** Special character "z" stands for four NULL bytes (short-cut for !!!!!) */
+    public static final int ZERO          = 0x7A; //"z"
+    /** ZERO as a byte array */
+    public static final byte[] ZERO_ARRAY = {(byte)ZERO};
+    /** The start index for ASCII85 characters (!) */
+    public static final int START         = 0x21; //"!"
+    /** The end index for ASCII85 characters (u) */
+    public static final int END           = 0x75; //"u"
+    /** The EOL indicator (LF) */
+    public static final int EOL           = 0x0A; //"\n"
+    /** The EOD (end of data) indicator */
+    public static final byte[] EOD        = {0x7E, 0x3E}; //"~>"
+
+    /** Array of powers of 85 (4, 3, 2, 1, 0) */
+    public static final long POW85[] = new long[] {85 * 85 * 85 * 85, 
+                                                    85 * 85 * 85,
+                                                    85 * 85,
+                                                    85,
+                                                    1};
+
+    /*
+    public static final long BASE85_4 = 85;
+    public static final long BASE85_3 = BASE85_4 * BASE85_4;
+    public static final long BASE85_2 = BASE85_3 * BASE85_4;
+    public static final long BASE85_1 = BASE85_2 * BASE85_4;
+    */
+
+}
+
+
diff --git a/src/java/org/apache/fop/util/ASCII85InputStream.java b/src/java/org/apache/fop/util/ASCII85InputStream.java
new file mode 100644 (file)
index 0000000..983f97e
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * $Id$
+ * ============================================================================
+ *                    The Apache Software License, Version 1.1
+ * ============================================================================
+ * 
+ * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment: "This product includes software
+ *    developed by the Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ * 
+ * 4. The names "FOP" and "Apache Software Foundation" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    apache@apache.org.
+ * 
+ * 5. Products derived from this software may not be called "Apache", nor may
+ *    "Apache" appear in their name, without prior written permission of the
+ *    Apache Software Foundation.
+ * 
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ * 
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation and was originally created by
+ * James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ * Software Foundation, please see <http://www.apache.org/>.
+ */ 
+package org.apache.fop.util;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * This class applies a ASCII85 decoding to the stream.
+ * <p>
+ * The class is derived from InputStream instead of FilteredInputStream because
+ * we can use the read(byte[], int, int) method from InputStream which simply
+ * delegates to read(). This makes the implementation easier.
+ * <p>
+ * The filter is described in chapter 3.13.3 of the PostScript Language 
+ * Reference (third edition).
+ *
+ * @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a>
+ * @version $Id$
+ */
+public class ASCII85InputStream extends InputStream
+            implements ASCII85Constants {
+
+    private InputStream in;
+    private boolean eodReached = false;
+    private int[] b = new int[4]; //decoded
+    private int bSize = 0;
+    private int bIndex = 0; 
+
+    /** @see java.io.FilterInputStream **/
+    public ASCII85InputStream(InputStream in) {
+        super();
+        this.in = in;
+    }
+
+    /** @see java.io.FilterInputStream **/
+    public int read() throws IOException {
+        //Check if we need to read the next tuple
+        if (bIndex >= bSize) {
+            if (eodReached) {
+                return -1;
+            } 
+            readNextTuple();
+            if (bSize == 0) {
+                if (!eodReached) {
+                    throw new IllegalStateException("Internal error");
+                }
+                return -1;
+            }
+        }
+        int result = b[bIndex];
+        result = (result < 0 ? 256 + result : result);
+        bIndex++;
+        return result;
+    }
+    
+    private int filteredRead() throws IOException {
+        int buf;
+        while (true) {
+            buf = in.read();
+            switch (buf) {
+                case 0: //null
+                case 9: //tab
+                case 10: //LF
+                case 12: //FF
+                case 13: //CR
+                case 32: //space
+                    continue; //ignore
+                case ZERO:
+                case 126: //= EOD[0] = '~'
+                    return buf;
+                default:
+                    if ((buf >= START) && (buf <= END)) {
+                        return buf;
+                    } else {
+                        throw new IOException("Illegal character detected: " + buf);
+                    }
+            }
+        }
+    }
+    
+    private void handleEOD() throws IOException {
+        final int buf = in.read();
+        if (buf != EOD[1]) {
+            throw new IOException("'>' expected after '~' (EOD)");
+        }
+        eodReached = true;
+        bSize = 0;
+        bIndex = 0;
+    }
+    
+    private void readNextTuple() throws IOException {
+        int buf;
+        long tuple = 0;
+        //Read ahead and check for special "z"
+        buf = filteredRead();
+        if (buf == ZERO) {
+            java.util.Arrays.fill(b, 0);
+            bSize = 4;
+            bIndex = 0;
+        } else if (buf == EOD[0]) {
+            handleEOD();
+        } else {
+            int cIndex = 0;
+            tuple = (buf - START) * POW85[cIndex];
+            //System.out.println(cIndex + ": " + Long.toHexString(tuple));
+            cIndex++;
+            while (cIndex < 5) {
+                buf = filteredRead();
+                if (buf == EOD[0]) {
+                    handleEOD();
+                    break;
+                } else if (buf == ZERO) {
+                    //Violation 2
+                    throw new IOException("Illegal 'z' within tuple");
+                } else {
+                    tuple += (buf - START) * POW85[cIndex];
+                    //System.out.println(cIndex + ": " + Long.toHexString(tuple));
+                    cIndex++;
+                }
+            }
+            int cSize = cIndex;
+            if (cSize == 1) {
+                //Violation 3
+                throw new IOException("Only one character in tuple");
+            }
+            //Handle optional, trailing, incomplete tuple 
+            while (cIndex < 5) {
+                tuple += POW85[cIndex - 1];
+                cIndex++;
+            }
+            if (tuple > (2L << 31) - 1) {
+                //Violation 1
+                throw new IOException("Illegal tuple (> 2^32 - 1)");
+            }
+            //Convert tuple
+            b[0] = (byte)((tuple >> 24) & 0xFF);
+            b[1] = (byte)((tuple >> 16) & 0xFF);
+            b[2] = (byte)((tuple >> 8) & 0xFF);
+            b[3] = (byte)((tuple) & 0xFF);
+            bSize = cSize - 1;
+            bIndex = 0;
+        }
+    }
+
+}
+
+
diff --git a/src/java/org/apache/fop/util/ASCII85OutputStream.java b/src/java/org/apache/fop/util/ASCII85OutputStream.java
new file mode 100644 (file)
index 0000000..942690d
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * $Id$
+ * ============================================================================
+ *                    The Apache Software License, Version 1.1
+ * ============================================================================
+ * 
+ * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment: "This product includes software
+ *    developed by the Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ * 
+ * 4. The names "FOP" and "Apache Software Foundation" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    apache@apache.org.
+ * 
+ * 5. Products derived from this software may not be called "Apache", nor may
+ *    "Apache" appear in their name, without prior written permission of the
+ *    Apache Software Foundation.
+ * 
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ * 
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation and was originally created by
+ * James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ * Software Foundation, please see <http://www.apache.org/>.
+ */ 
+package org.apache.fop.util;
+
+import java.io.OutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+
+/**
+ * This class applies a ASCII85 encoding to the stream.
+ *
+ * @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a>
+ * @version $Id$
+ */
+public class ASCII85OutputStream extends FilterOutputStream
+            implements ASCII85Constants, Finalizable {
+
+    private static final boolean DEBUG = false;
+
+    private int pos = 0;
+    private long buffer = 0;
+    private int posinline = 0;
+    private int bw = 0;
+
+    /** @see java.io.FilterOutputStream **/
+    public ASCII85OutputStream(OutputStream out) {
+        super(out);
+    }
+
+    /** @see java.io.FilterOutputStream **/
+    public void write(int b) throws IOException {
+        if (pos == 0) {
+            buffer += (b << 24) & 0xff000000L;
+        } else if (pos == 1) {
+            buffer += (b << 16) & 0xff0000L;
+        } else if (pos == 2) {
+            buffer += (b << 8) & 0xff00L;
+        } else {
+            buffer += b & 0xffL;
+        }
+        pos++;
+
+        if (pos > 3) {
+            checkedWrite(convertWord(buffer));
+            buffer = 0;
+            pos = 0;
+        }
+    }
+
+    /* UNUSED ATM
+    private void checkedWrite(int b) throws IOException {
+        if (posinline == 80) {
+            out.write(EOL); bw++;
+            posinline = 0;
+        }
+        checkedWrite(b);
+        posinline++;
+        bw++;
+    }*/
+
+    private void checkedWrite(byte[] buf) throws IOException {
+        checkedWrite(buf, buf.length, false);
+    }
+        
+    private void checkedWrite(byte[] buf, boolean nosplit) throws IOException {
+        checkedWrite(buf, buf.length, nosplit);
+    }
+
+    private void checkedWrite(byte[] buf , int len) throws IOException {
+        checkedWrite(buf, len, false);
+    }
+        
+    private void checkedWrite(byte[] buf , int len, boolean nosplit) throws IOException {
+        if (posinline + len > 80) {
+            int firstpart = (nosplit ? 0 : len - (posinline + len - 80));
+            if (firstpart > 0) {
+                out.write(buf, 0, firstpart);
+            }
+            out.write(EOL); bw++;
+            int rest = len - firstpart;
+            if (rest > 0) {
+                out.write(buf, firstpart, rest);
+            }
+            posinline = rest;
+        } else {
+            out.write(buf, 0, len);
+            posinline += len;
+        }
+        bw += len;
+    }
+
+    /**
+     * This converts a 32 bit value (4 bytes) into 5 bytes using base 85.
+     * each byte in the result starts with zero at the '!' character so
+     * the resulting base85 number fits into printable ascii chars
+     *
+     * @param word the 32 bit unsigned (hence the long datatype) word
+     * @return 5 bytes (or a single byte of the 'z' character for word
+     * values of 0)
+     */
+    private byte[] convertWord(long word) {
+        word = word & 0xffffffff;
+
+        if (word == 0) {
+            return ZERO_ARRAY;
+        } else {
+            if (word < 0) {
+                word = -word;
+            }
+            byte c1 = 
+                (byte)((word 
+                        / POW85[0]) & 0xFF);
+            byte c2 = 
+                (byte)(((word - (c1 * POW85[0])) 
+                        / POW85[1]) & 0xFF);
+            byte c3 =
+                (byte)(((word - (c1 * POW85[0]) 
+                              - (c2 * POW85[1]))
+                        / POW85[2]) & 0xFF);
+            byte c4 =
+                (byte)(((word - (c1 * POW85[0]) 
+                              - (c2 * POW85[1]) 
+                              - (c3 * POW85[2]))
+                        / POW85[3]) & 0xFF);
+            byte c5 =
+                (byte)(((word - (c1 * POW85[0]) 
+                              - (c2 * POW85[1]) 
+                              - (c3 * POW85[2])
+                              - (c4 * POW85[3])))
+                        & 0xFF);
+
+            byte[] ret = {
+                (byte)(c1 + START), (byte)(c2 + START),
+                (byte)(c3 + START), (byte)(c4 + START),
+                (byte)(c5 + START)
+            };
+
+            if (DEBUG) {
+                for (int i = 0; i < ret.length; i++) {
+                    if (ret[i] < 33 || ret[i] > 117) {
+                        System.out.println("Illegal char value "
+                                        + new Integer(ret[i]));
+                    }
+                }
+            }
+            return ret;
+        }
+    }
+
+    /** @see org.apache.fop.render.ps.Finalizable **/
+    public void finalizeStream() throws IOException {
+        // now take care of the trailing few bytes.
+        // with n leftover bytes, we append 0 bytes to make a full group of 4
+        // then convert like normal (except not applying the special zero rule)
+        // and write out the first n+1 bytes from the result
+        if (pos > 0) {
+            int rest = pos;
+            /*
+            byte[] lastdata = new byte[4];
+            int i = 0;
+            for (int j = 0; j < 4; j++) {
+                if (j < rest) {
+                    lastdata[j] = data[i++];
+                } else {
+                    lastdata[j] = 0;
+                }
+            }
+
+            long val = ((lastdata[0] << 24) & 0xff000000L)
+                       + ((lastdata[1] << 16) & 0xff0000L)
+                       + ((lastdata[2] << 8) & 0xff00L)
+                       + (lastdata[3] & 0xffL);
+            */
+
+            byte[] conv;
+            // special rule for handling zeros at the end
+            if (buffer != 0) {
+                conv = convertWord(buffer);
+            } else {
+                conv = new byte[5];
+                for (int j = 0; j < 5; j++) {
+                    conv[j] = (byte)'!';
+                }
+            }
+            // assert rest+1 <= 5
+            checkedWrite(conv, rest + 1);
+        }
+        // finally write the two character end of data marker
+        checkedWrite(EOD, true);
+
+        flush();
+        if (out instanceof Finalizable) {
+            ((Finalizable)out).finalizeStream();
+        }
+    }
+
+    /** @see java.io.FilterOutputStream **/
+    public void close() throws IOException {
+        finalizeStream();
+        super.close();
+    }
+
+}
+
+
diff --git a/src/java/org/apache/fop/util/ASCIIHexOutputStream.java b/src/java/org/apache/fop/util/ASCIIHexOutputStream.java
new file mode 100644 (file)
index 0000000..dadca8f
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * $Id$
+ * ============================================================================
+ *                    The Apache Software License, Version 1.1
+ * ============================================================================
+ * 
+ * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment: "This product includes software
+ *    developed by the Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ * 
+ * 4. The names "FOP" and "Apache Software Foundation" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    apache@apache.org.
+ * 
+ * 5. Products derived from this software may not be called "Apache", nor may
+ *    "Apache" appear in their name, without prior written permission of the
+ *    Apache Software Foundation.
+ * 
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ * 
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation and was originally created by
+ * James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ * Software Foundation, please see <http://www.apache.org/>.
+ */ 
+package org.apache.fop.util;
+
+import java.io.OutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+
+/**
+ * This class applies a ASCII Hex encoding to the stream.
+ *
+ * @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a>
+ * @version $Id$
+ */
+public class ASCIIHexOutputStream extends FilterOutputStream
+        implements Finalizable {
+
+    private static final int EOL   = 0x0A; //"\n"
+    private static final int EOD   = 0x3E; //">"
+    private static final int ZERO  = 0x30; //"0"
+    private static final int NINE  = 0x39; //"9"
+    private static final int A     = 0x41; //"A"
+    private static final int ADIFF = A - NINE - 1;
+
+    private int posinline = 0;
+
+
+    /** @see java.io.FilterOutputStream **/
+    public ASCIIHexOutputStream(OutputStream out) {
+        super(out);
+    }
+
+
+    /** @see java.io.FilterOutputStream **/
+    public void write(int b) throws IOException {
+        b &= 0xFF;
+
+        int digit1 = ((b & 0xF0) >> 4) + ZERO;
+        if (digit1 > NINE) {
+            digit1 += ADIFF;
+        }
+        out.write(digit1);
+
+        int digit2 = (b & 0x0F) + ZERO;
+        if (digit2 > NINE) {
+            digit2 += ADIFF;
+        }
+        out.write(digit2);
+
+        posinline++;
+        checkLineWrap();
+    }
+
+
+    private void checkLineWrap() throws IOException {
+        //Maximum line length is 80 characters
+        if (posinline >= 40) {
+            out.write(EOL);
+            posinline = 0;
+        }
+    }
+
+
+    /** @see org.apache.fop.render.ps.Finalizable **/
+    public void finalizeStream() throws IOException {
+        checkLineWrap();
+        //Write closing character ">"
+        super.write(EOD);
+
+        flush();
+        if (out instanceof Finalizable) {
+            ((Finalizable) out).finalizeStream();
+        }
+    }
+
+
+    /** @see java.io.FilterOutputStream **/
+    public void close() throws IOException {
+        finalizeStream();
+        super.close();
+    }
+
+
+}
+
+
diff --git a/src/java/org/apache/fop/util/Finalizable.java b/src/java/org/apache/fop/util/Finalizable.java
new file mode 100644 (file)
index 0000000..c780634
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * $Id$
+ * ============================================================================
+ *                    The Apache Software License, Version 1.1
+ * ============================================================================
+ * 
+ * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment: "This product includes software
+ *    developed by the Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ * 
+ * 4. The names "FOP" and "Apache Software Foundation" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    apache@apache.org.
+ * 
+ * 5. Products derived from this software may not be called "Apache", nor may
+ *    "Apache" appear in their name, without prior written permission of the
+ *    Apache Software Foundation.
+ * 
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ * 
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation and was originally created by
+ * James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ * Software Foundation, please see <http://www.apache.org/>.
+ */ 
+package org.apache.fop.util;
+
+/**
+ * This interface is used for special FilteredOutputStream classes that won't
+ * be closed (since this causes the target OutputStream to be closed, too) but
+ * where flush() is not enough, for example because a final marker has to be
+ * written to the target stream.
+ *
+ * @author    <a href="mailto:jeremias@apache.org">Jeremias Maerki</a>
+ * @version   $Id$
+ */
+public interface Finalizable {
+
+    /**
+     * This method can be called instead of close() on a subclass of
+     * FilteredOutputStream when a final marker has to be written to the target
+     * stream, but close() cannot be called.
+     *
+     * @exception java.io.IOException  In case of an IO problem
+     */
+    void finalizeStream()
+        throws java.io.IOException;
+
+}
diff --git a/src/java/org/apache/fop/util/FlateEncodeOutputStream.java b/src/java/org/apache/fop/util/FlateEncodeOutputStream.java
new file mode 100644 (file)
index 0000000..f008b3d
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * $Id$
+ * ============================================================================
+ *                    The Apache Software License, Version 1.1
+ * ============================================================================
+ * 
+ * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment: "This product includes software
+ *    developed by the Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ * 
+ * 4. The names "FOP" and "Apache Software Foundation" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    apache@apache.org.
+ * 
+ * 5. Products derived from this software may not be called "Apache", nor may
+ *    "Apache" appear in their name, without prior written permission of the
+ *    Apache Software Foundation.
+ * 
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ * 
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation and was originally created by
+ * James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ * Software Foundation, please see <http://www.apache.org/>.
+ */ 
+package org.apache.fop.util;
+
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * This class applies a FlateEncode filter to the stream. It is basically the
+ * normal DeflaterOutputStream except now also implementing the Finalizable
+ * interface.
+ *
+ * @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a>
+ * @version $Id$
+ */
+public class FlateEncodeOutputStream extends java.util.zip.DeflaterOutputStream
+            implements Finalizable {
+
+
+    /** @see java.util.zip.DeflaterOutputStream **/
+    public FlateEncodeOutputStream(OutputStream out) {
+        super(out);
+    }
+
+
+    /** @see org.apache.fop.render.ps.Finalizable **/
+    public void finalizeStream() throws IOException {
+        finish();
+        flush();
+        if (out instanceof Finalizable) {
+            ((Finalizable)out).finalizeStream();
+        }
+    }
+
+}
+
+
diff --git a/src/java/org/apache/fop/util/RunLengthEncodeOutputStream.java b/src/java/org/apache/fop/util/RunLengthEncodeOutputStream.java
new file mode 100644 (file)
index 0000000..b5ec142
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * $Id$
+ * ============================================================================
+ *                    The Apache Software License, Version 1.1
+ * ============================================================================
+ * 
+ * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment: "This product includes software
+ *    developed by the Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ * 
+ * 4. The names "FOP" and "Apache Software Foundation" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    apache@apache.org.
+ * 
+ * 5. Products derived from this software may not be called "Apache", nor may
+ *    "Apache" appear in their name, without prior written permission of the
+ *    Apache Software Foundation.
+ * 
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ * 
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation and was originally created by
+ * James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ * Software Foundation, please see <http://www.apache.org/>.
+ */ 
+package org.apache.fop.util;
+
+import java.io.FilterOutputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+
+
+/**
+ * This class applies a RunLengthEncode filter to the stream.
+ *
+ * @author   <a href="mailto:smwolke@geistig.com">Stephen Wolke</a>
+ * @version  $Id$
+ */
+public class RunLengthEncodeOutputStream extends FilterOutputStream
+            implements Finalizable {
+
+    private static final int MAX_SEQUENCE_COUNT    = 127;
+    private static final int END_OF_DATA           = 128;
+    private static final int BYTE_MAX              = 256;
+
+    private static final int NOT_IDENTIFY_SEQUENCE = 0;
+    private static final int START_SEQUENCE        = 1;
+    private static final int IN_SEQUENCE           = 2;
+    private static final int NOT_IN_SEQUENCE       = 3;
+
+    private int runCount = 0;
+    private int isSequence = NOT_IDENTIFY_SEQUENCE;
+    private byte[] runBuffer = new byte[MAX_SEQUENCE_COUNT + 1];
+
+
+    /** @see java.io.FilterOutputStream **/
+    public RunLengthEncodeOutputStream(OutputStream out) {
+        super(out);
+    }
+
+
+    /** @see java.io.FilterOutputStream **/
+    public void write(byte b)
+        throws java.io.IOException {
+        runBuffer[runCount] = b;
+
+        switch (runCount) {
+        case 0:
+            runCount = 0;
+            isSequence = NOT_IDENTIFY_SEQUENCE;
+            runCount++;
+            break;
+        case 1:
+            if (runBuffer[runCount] != runBuffer[runCount - 1]) {
+                isSequence = NOT_IN_SEQUENCE;
+            }
+            runCount++;
+            break;
+        case 2:
+            if (runBuffer[runCount] != runBuffer[runCount - 1]) {
+                isSequence = NOT_IN_SEQUENCE;
+            } else {
+                if (isSequence == NOT_IN_SEQUENCE) {
+                    isSequence = START_SEQUENCE;
+                } else {
+                    isSequence = IN_SEQUENCE;
+                }
+            }
+            runCount++;
+            break;
+        case MAX_SEQUENCE_COUNT:
+            if (isSequence == IN_SEQUENCE) {
+                out.write(BYTE_MAX - (MAX_SEQUENCE_COUNT - 1));
+                out.write(runBuffer[runCount - 1]);
+                runBuffer[0] = runBuffer[runCount];
+                runCount = 1;
+            } else {
+                out.write(MAX_SEQUENCE_COUNT);
+                out.write(runBuffer, 0, runCount + 1);
+                runCount = 0;
+            }
+            isSequence = NOT_IDENTIFY_SEQUENCE;
+            break;
+        default:
+            switch (isSequence) {
+            case IN_SEQUENCE:
+                if (runBuffer[runCount] != runBuffer[runCount - 1]) {
+                    out.write(BYTE_MAX - (runCount - 1));
+                    out.write(runBuffer[runCount - 1]);
+                    runBuffer[0] = runBuffer[runCount];
+                    runCount = 1;
+                    isSequence = NOT_IDENTIFY_SEQUENCE;
+                    break;
+                }
+                runCount++;
+                break;
+            case NOT_IN_SEQUENCE:
+                if (runBuffer[runCount] == runBuffer[runCount - 1]) {
+                    isSequence = START_SEQUENCE;
+                }
+                runCount++;
+                break;
+            case START_SEQUENCE:
+                if (runBuffer[runCount] == runBuffer[runCount - 1]) {
+                    out.write(runCount - 3);
+                    out.write(runBuffer, 0, runCount - 2);
+                    runBuffer[0] = runBuffer[runCount];
+                    runBuffer[1] = runBuffer[runCount];
+                    runBuffer[2] = runBuffer[runCount];
+                    runCount = 3;
+                    isSequence = IN_SEQUENCE;
+                    break;
+                } else {
+                    isSequence = NOT_IN_SEQUENCE;
+                    runCount++;
+                    break;
+                }
+            }
+        }
+    }
+
+
+    /** @see java.io.FilterOutputStream **/
+    public void write(byte[] b)
+        throws IOException {
+
+        for (int i = 0; i < b.length; i++) {
+            this.write(b[i]);
+        }
+    }
+
+
+    /** @see java.io.FilterOutputStream **/
+    public void write(byte[] b, int off, int len)
+        throws IOException {
+
+        for (int i = 0; i < len; i++) {
+            this.write(b[off + i]);
+        }
+    }
+
+
+    /** @see org.apache.fop.render.ps.Finalizable **/
+    public void finalizeStream()
+        throws IOException {
+        switch (isSequence) {
+        case IN_SEQUENCE:
+            out.write(BYTE_MAX - (runCount - 1));
+            out.write(runBuffer[runCount - 1]);
+            break;
+        default:
+            out.write(runCount - 1);
+            out.write(runBuffer, 0, runCount);
+        }
+
+        out.write(END_OF_DATA);
+
+        flush();
+        if (out instanceof Finalizable) {
+            ((Finalizable) out).finalizeStream();
+        }
+    }
+
+
+    /** @see java.io.FilterOutputStream **/
+    public void close()
+        throws IOException {
+        finalizeStream();
+        super.close();
+    }
+
+}
+