KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > pdf > ASCII85Filter


1 /*
2  * $Id: ASCII85Filter.java,v 1.3.2.3 2003/02/25 14:29:36 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.pdf;
52
53 import java.io.ByteArrayOutputStream JavaDoc;
54 import java.io.UnsupportedEncodingException JavaDoc;
55
56 public class ASCII85Filter extends PDFFilter {
57     private static final char ASCII85_ZERO = 'z';
58     private static final char ASCII85_START = '!';
59     private static final String JavaDoc ASCII85_EOD = "~>";
60
61     private static final long base85_4 = 85;
62 // private static final long base85_3 = base85_4 * base85_4;
63
// private static final long base85_2 = base85_3 * base85_4;
64
// private static final long base85_1 = base85_2 * base85_4;
65

66
67
68     public String JavaDoc getName() {
69         return "/ASCII85Decode";
70     }
71
72     public String JavaDoc getDecodeParms() {
73         return null;
74     }
75
76     public byte[] encode(byte[] data) {
77
78         ByteArrayOutputStream JavaDoc buffer = new ByteArrayOutputStream JavaDoc();
79
80         int i;
81         int total = 0;
82         int diff = 0;
83
84         // first encode the majority of the data
85
// each 4 byte group becomes a 5 byte group
86
for (i = 0; i + 3 < data.length; i += 4) {
87
88             long val = ((data[i] << 24)
89                         & 0xff000000L) // note: must have the L at the
90
+ ((data[i + 1] << 16) & 0xff0000L) // end, otherwise you get into
91
+ ((data[i + 2] << 8) & 0xff00L) // weird signed value problems
92
+ (data[i + 3] & 0xffL); // cause we're using a full 32 bits
93
byte[] conv = convertWord(val);
94
95             buffer.write(conv, 0, conv.length);
96
97         }
98
99         // now take care of the trailing few bytes.
100
// with n leftover bytes, we append 0 bytes to make a full group of 4
101
// then convert like normal (except not applying the special zero rule)
102
// and write out the first n+1 bytes from the result
103
if (i < data.length) {
104             int n = data.length - i;
105             byte[] lastdata = new byte[4];
106             for (int j = 0; j < 4; j++) {
107                 if (j < n) {
108                     lastdata[j] = data[i++];
109                 } else {
110                     lastdata[j] = 0;
111                 }
112             }
113
114             long val = ((lastdata[0] << 24) & 0xff000000L)
115                        + ((lastdata[1] << 16) & 0xff0000L)
116                        + ((lastdata[2] << 8) & 0xff00L)
117                        + (lastdata[3] & 0xffL);
118             byte[] conv = convertWord(val);
119
120             // special rule for handling zeros at the end
121
if (val == 0) {
122                 conv = new byte[5];
123                 for (int j = 0; j < 5; j++) {
124                     conv[j] = (byte)'!';
125                 }
126             }
127             // assert n+1 <= 5
128
buffer.write(conv, 0, n + 1);
129             // System.out.println("ASCII85 end of data was "+n+" bytes long");
130

131         }
132         // finally write the two character end of data marker
133
byte[] eod;
134         try {
135             eod = ASCII85_EOD.getBytes(PDFDocument.ENCODING);
136         } catch (UnsupportedEncodingException JavaDoc ue) {
137             eod = ASCII85_EOD.getBytes();
138         }
139         buffer.write(eod, 0, eod.length);
140         byte[] result = buffer.toByteArray();
141
142         // assert that we have the correct outgoing length
143
/*
144          * int in = (data.length % 4);
145          * int out = (result.length-ASCII85_EOD.getBytes().length) % 5;
146          * if ((in+1 != out) && !(in == 0 && out == 0)) {
147          * System.out.println("ASCII85 assertion failed:");
148          * System.out.println(" inlength = "+data.length+" inlength % 4 = "+(data.length % 4)+" outlength = "+(result.length-ASCII85_EOD.getBytes().length)+" outlength % 5 = "+((result.length-ASCII85_EOD.getBytes().length) % 5));
149          * }
150          */

151         return result;
152
153     }
154
155     /**
156      * This converts a 32 bit value (4 bytes) into 5 bytes using base 85.
157      * each byte in the result starts with zero at the '!' character so
158      * the resulting base85 number fits into printable ascii chars
159      *
160      * @param word the 32 bit unsigned (hence the long datatype) word
161      * @return 5 bytes (or a single byte of the 'z' character for word
162      * values of 0)
163      */

164     private byte[] convertWord(long word) {
165         word = word & 0xffffffff;
166         if (word < 0) {
167             word = -word;
168         }
169
170         if (word == 0) {
171             byte[] result = {
172                 (byte)ASCII85_ZERO
173             };
174             return result;
175         } else {
176 // byte c1 = (byte)((word / base85_1) & 0xFF);
177
// byte c2 = (byte)(((word - (c1 * base85_1)) / base85_2) & 0xFF);
178
// byte c3 =
179
// (byte)(((word - (c1 * base85_1) - (c2 * base85_2)) / base85_3)
180
// & 0xFF);
181
// byte c4 =
182
// (byte)(((word - (c1 * base85_1) - (c2 * base85_2) - (c3 * base85_3)) / base85_4)
183
// & 0xFF);
184
// byte c5 =
185
// (byte)(((word - (c1 * base85_1) - (c2 * base85_2) - (c3 * base85_3) - (c4 * base85_4)))
186
// & 0xFF);
187

188 // byte[] ret = {
189
// (byte)(c1 + ASCII85_START), (byte)(c2 + ASCII85_START),
190
// (byte)(c3 + ASCII85_START), (byte)(c4 + ASCII85_START),
191
// (byte)(c5 + ASCII85_START)
192
byte c5 = (byte)((word % base85_4) + ASCII85_START);
193             word = word / base85_4;
194             byte c4 = (byte)((word % base85_4) + ASCII85_START);
195             word = word / base85_4;
196             byte c3 = (byte)((word % base85_4) + ASCII85_START);
197             word = word / base85_4;
198             byte c2 = (byte)((word % base85_4) + ASCII85_START);
199             word = word / base85_4;
200             byte c1 = (byte)((word % base85_4) + ASCII85_START);
201
202             byte[] ret = {
203               c1 , c2, c3, c4, c5
204             };
205             for (int i = 0; i < ret.length; i++) {
206                 if (ret[i] < 33 || ret[i] > 117) {
207                     System.out.println("illegal char value "
208                                        + new Integer JavaDoc(ret[i]));
209                 }
210             }
211
212             return ret;
213
214
215         }
216     }
217
218 }
219
Popular Tags