KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > render > ps > RunLengthEncodeOutputStream


1 /*
2  * $Id: RunLengthEncodeOutputStream.java,v 1.1.2.2 2003/02/25 14:58:23 jeremias Exp $
3  * ============================================================================
4  * The Apache Software License, Version 1.1
5  * ============================================================================
6  *
7  * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without modifica-
10  * tion, are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * 3. The end-user documentation included with the redistribution, if any, must
20  * include the following acknowledgment: "This product includes software
21  * developed by the Apache Software Foundation (http://www.apache.org/)."
22  * Alternately, this acknowledgment may appear in the software itself, if
23  * and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. The names "FOP" and "Apache Software Foundation" must not be used to
26  * endorse or promote products derived from this software without prior
27  * written permission. For written permission, please contact
28  * apache@apache.org.
29  *
30  * 5. Products derived from this software may not be called "Apache", nor may
31  * "Apache" appear in their name, without prior written permission of the
32  * Apache Software Foundation.
33  *
34  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
35  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
36  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
37  * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
38  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
39  * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
40  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
41  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
43  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44  * ============================================================================
45  *
46  * This software consists of voluntary contributions made by many individuals
47  * on behalf of the Apache Software Foundation and was originally created by
48  * James Tauber <jtauber@jtauber.com>. For more information on the Apache
49  * Software Foundation, please see <http://www.apache.org/>.
50  */

51 package org.apache.fop.render.ps;
52
53 import java.io.FilterOutputStream JavaDoc;
54 import java.io.OutputStream JavaDoc;
55 import java.io.IOException JavaDoc;
56
57 /**
58  * This class applies a RunLengthEncode filter to the stream.
59  *
60  * @author <a HREF="mailto:smwolke@geistig.com">Stephen Wolke</a>
61  * @version $Id: RunLengthEncodeOutputStream.java,v 1.1.2.2 2003/02/25 14:58:23 jeremias Exp $
62  */

63
64 public class RunLengthEncodeOutputStream extends FilterOutputStream JavaDoc
65             implements Finalizable {
66
67     private static final int MAX_SEQUENCE_COUNT = 127;
68     private static final int END_OF_DATA = 128;
69     private static final int BYTE_MAX = 256;
70
71     private static final int NOT_IDENTIFY_SEQUENCE = 0;
72     private static final int START_SEQUENCE = 1;
73     private static final int IN_SEQUENCE = 2;
74     private static final int NOT_IN_SEQUENCE = 3;
75
76     private int runCount = 0;
77     private int isSequence = NOT_IDENTIFY_SEQUENCE;
78     private byte[] runBuffer = new byte[MAX_SEQUENCE_COUNT + 1];
79
80
81     /**
82      * Constructor for the RunLengthEncode Filter.
83      *
84      * @param out The OutputStream to write to
85      */

86     public RunLengthEncodeOutputStream(OutputStream JavaDoc out) {
87         super(out);
88     }
89
90
91     /**
92      * @see java.io.OutputStream#write(int)
93      * @param b the <code>byte</code>.
94      * @exception IOException if an I/O error occurs. In particular,
95      * an <code>IOException</code> may be thrown if the
96      * output stream has been closed.
97      */

98     public void write(byte b)
99         throws java.io.IOException JavaDoc {
100         runBuffer[runCount] = b;
101
102         switch (runCount) {
103         case 0:
104             runCount = 0;
105             isSequence = NOT_IDENTIFY_SEQUENCE;
106             runCount++;
107             break;
108         case 1:
109             if (runBuffer[runCount] != runBuffer[runCount - 1]) {
110                 isSequence = NOT_IN_SEQUENCE;
111             }
112             runCount++;
113             break;
114         case 2:
115             if (runBuffer[runCount] != runBuffer[runCount - 1]) {
116                 isSequence = NOT_IN_SEQUENCE;
117             } else {
118                 if (isSequence == NOT_IN_SEQUENCE) {
119                     isSequence = START_SEQUENCE;
120                 } else {
121                     isSequence = IN_SEQUENCE;
122                 }
123             }
124             runCount++;
125             break;
126         case MAX_SEQUENCE_COUNT:
127             if (isSequence == IN_SEQUENCE) {
128                 out.write(BYTE_MAX - (MAX_SEQUENCE_COUNT - 1));
129                 out.write(runBuffer[runCount - 1]);
130                 runBuffer[0] = runBuffer[runCount];
131                 runCount = 1;
132             } else {
133                 out.write(MAX_SEQUENCE_COUNT);
134                 out.write(runBuffer, 0, runCount + 1);
135                 runCount = 0;
136             }
137             isSequence = NOT_IDENTIFY_SEQUENCE;
138             break;
139         default:
140             switch (isSequence) {
141             case IN_SEQUENCE:
142                 if (runBuffer[runCount] != runBuffer[runCount - 1]) {
143                     out.write(BYTE_MAX - (runCount - 1));
144                     out.write(runBuffer[runCount - 1]);
145                     runBuffer[0] = runBuffer[runCount];
146                     runCount = 1;
147                     isSequence = NOT_IDENTIFY_SEQUENCE;
148                     break;
149                 }
150                 runCount++;
151                 break;
152             case NOT_IN_SEQUENCE:
153                 if (runBuffer[runCount] == runBuffer[runCount - 1]) {
154                     isSequence = START_SEQUENCE;
155                 }
156                 runCount++;
157                 break;
158             case START_SEQUENCE:
159                 if (runBuffer[runCount] == runBuffer[runCount - 1]) {
160                     out.write(runCount - 3);
161                     out.write(runBuffer, 0, runCount - 2);
162                     runBuffer[0] = runBuffer[runCount];
163                     runBuffer[1] = runBuffer[runCount];
164                     runBuffer[2] = runBuffer[runCount];
165                     runCount = 3;
166                     isSequence = IN_SEQUENCE;
167                     break;
168                 } else {
169                     isSequence = NOT_IN_SEQUENCE;
170                     runCount++;
171                     break;
172                 }
173             }
174         }
175     }
176
177
178     /**
179      * @see java.io.OutputStream#write(byte[])
180      * @param b the data.
181      * @exception IOException if an I/O error occurs.
182      */

183     public void write(byte[] b)
184         throws IOException JavaDoc {
185
186         for (int i = 0; i < b.length; i++) {
187             this.write(b[i]);
188         }
189     }
190
191
192     /**
193      * @see java.io.OutputStream#write(byte[], int, int)
194      * @param b the data.
195      * @param off the start offset in the data.
196      * @param len the number of bytes to write.
197      * @exception IOException if an I/O error occurs. In particular,
198      * an <code>IOException</code> is thrown if the output
199      * stream is closed.
200      */

201     public void write(byte[] b, int off, int len)
202         throws IOException JavaDoc {
203
204         for (int i = 0; i < len; i++) {
205             this.write(b[off + i]);
206         }
207     }
208
209
210     /**
211      * Flushes the the stream and writes out the trailer, but, unlike close(),
212      * without closing the stream.
213      *
214      * @exception IOException if an I/O error occurs.
215      */

216     public void finalizeStream()
217         throws IOException JavaDoc {
218         switch (isSequence) {
219         case IN_SEQUENCE:
220             out.write(BYTE_MAX - (runCount - 1));
221             out.write(runBuffer[runCount - 1]);
222             break;
223         default:
224             out.write(runCount - 1);
225             out.write(runBuffer, 0, runCount);
226         }
227
228         out.write(END_OF_DATA);
229
230         flush();
231         if (out instanceof Finalizable) {
232             ((Finalizable) out).finalizeStream();
233         }
234     }
235
236
237     /**
238      * Closes the stream.
239      *
240      * @exception IOException if an I/O error occurs.
241      */

242     public void close()
243         throws IOException JavaDoc {
244         finalizeStream();
245         super.close();
246     }
247
248 }
249
250
Popular Tags