1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.pdfbox.filter; 18 19 import java.io.IOException; 20 import java.io.InputStream; 21 import java.io.OutputStream; 22 23 import org.apache.pdfbox.cos.COSDictionary; 24 25 import org.apache.pdfbox.persistence.util.COSHEXTable; 26 27 /** 28 * This is the used for the ASCIIHexDecode filter. 29 * 30 * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a> 31 * @version $Revision: 1.9 $ 32 */ 33 public class ASCIIHexFilter implements Filter 34 { 35 36 /** 37 * Whitespace. 38 * 0 0x00 Null (NUL) 39 * 9 0x09 Tab (HT) 40 * 10 0x0A Line feed (LF) 41 * 12 0x0C Form feed (FF) 42 * 13 0x0D Carriage return (CR) 43 * 32 0x20 Space (SP) 44 */ 45 46 private boolean isWhitespace(int c) 47 { 48 return c == 0 || c == 9 || c == 10 || c == 12 || c == 13 || c == 32; 49 } 50 51 private boolean isEOD(int c) 52 { 53 return (c == 62); // '>' - EOD 54 } 55 56 /** 57 * {@inheritDoc} 58 */ 59 public void decode( InputStream compressedData, OutputStream result, COSDictionary options, int filterIndex ) 60 throws IOException 61 { 62 int value = 0; 63 int firstByte = 0; 64 int secondByte = 0; 65 while ((firstByte = compressedData.read()) != -1) 66 { 67 // always after first char 68 while(isWhitespace(firstByte)) 69 { 70 firstByte = compressedData.read(); 71 } 72 if(isEOD(firstByte)) 73 { 74 break; 75 } 76 77 if(REVERSE_HEX[firstByte] == -1) 78 { 79 System.out.println("Invalid Hex Code; int: " + firstByte + " char: " + (char) firstByte); 80 } 81 value = REVERSE_HEX[firstByte] * 16; 82 secondByte = compressedData.read(); 83 84 if(isEOD(secondByte)) 85 { 86 // second value behaves like 0 in case of EOD 87 result.write( value ); 88 break; 89 } 90 if(secondByte >= 0) 91 { 92 if(REVERSE_HEX[secondByte] == -1) 93 { 94 System.out.println("Invalid Hex Code; int: " + secondByte + " char: " + (char) secondByte); 95 } 96 value += REVERSE_HEX[secondByte]; 97 } 98 result.write( value ); 99 } 100 result.flush(); 101 } 102 103 private static final int[] REVERSE_HEX = 104 { 105 -1, //0 106 -1, //1 107 -1, //2 108 -1, //3 109 -1, //4 110 -1, //5 111 -1, //6 112 -1, //7 113 -1, //8 114 -1, //9 115 -1, //10 116 -1, //11 117 -1, //12 118 -1, //13 119 -1, //14 120 -1, //15 121 -1, //16 122 -1, //17 123 -1, //18 124 -1, //19 125 -1, //20 126 -1, //21 127 -1, //22 128 -1, //23 129 -1, //24 130 -1, //25 131 -1, //26 132 -1, //27 133 -1, //28 134 -1, //29 135 -1, //30 136 -1, //31 137 -1, //32 138 -1, //33 139 -1, //34 140 -1, //35 141 -1, //36 142 -1, //37 143 -1, //38 144 -1, //39 145 -1, //40 146 -1, //41 147 -1, //42 148 -1, //43 149 -1, //44 150 -1, //45 151 -1, //46 152 -1, //47 153 0, //48 154 1, //49 155 2, //50 156 3, //51 157 4, //52 158 5, //53 159 6, //54 160 7, //55 161 8, //56 162 9, //57 163 -1, //58 164 -1, //59 165 -1, //60 166 -1, //61 167 -1, //62 168 -1, //63 169 -1, //64 170 10, //65 171 11, //66 172 12, //67 173 13, //68 174 14, //69 175 15, //70 176 -1, //71 177 -1, //72 178 -1, //73 179 -1, //74 180 -1, //75 181 -1, //76 182 -1, //77 183 -1, //78 184 -1, //79 185 -1, //80 186 -1, //81 187 -1, //82 188 -1, //83 189 -1, //84 190 -1, //85 191 -1, //86 192 -1, //87 193 -1, //88 194 -1, //89 195 -1, //90 196 -1, //91 197 -1, //92 198 -1, //93 199 -1, //94 200 -1, //95 201 -1, //96 202 10, //97 203 11, //98 204 12, //99 205 13, //100 206 14, //101 207 15, //102 208 }; 209 210 /** 211 * {@inheritDoc} 212 */ 213 public void encode( InputStream rawData, OutputStream result, COSDictionary options, int filterIndex ) 214 throws IOException 215 { 216 int byteRead = 0; 217 while( (byteRead = rawData.read()) != -1 ) 218 { 219 int value = (byteRead+256)%256; 220 result.write( COSHEXTable.TABLE[value] ); 221 } 222 result.flush(); 223 } 224 }