1 package com.etymon.pj.object; 2 3 import java.io.*; 4 import java.util.*; 5 import java.util.zip.*; 6 import com.etymon.pj.*; 7 import com.etymon.pj.exception.*; 8 9 13 public class PjStream 14 extends PjObject { 15 16 20 public PjStream(byte[] s) { 21 _d = new PjStreamDictionary(); 22 _s = s; 23 } 24 25 31 public PjStream(PjStreamDictionary d, byte[] s) { 32 _d = d; 33 _s = s; 34 } 35 36 42 public PjStreamDictionary getStreamDictionary() { 43 return _d; 44 } 45 46 52 public byte[] getBuffer() { 53 return _s; 54 } 55 56 65 public PjStream flateDecompress() throws InvalidPdfObjectException { 66 Hashtable ht = _d.getHashtable(); 70 Object obj = ht.get(PjName.FILTER); 71 if (obj == null) { 72 return this; 73 } 74 if ( (obj instanceof PjName) || (obj instanceof PjArray) ) { 75 PjStreamDictionary newPjd = null; 76 Hashtable newHt; 77 if (obj instanceof PjName) { 78 PjName pjn = (PjName)obj; 79 if ( ! pjn.equals(PjName.FLATEDECODE) ) { 80 return this; 81 } else { 82 try { 84 newPjd = (PjStreamDictionary)(_d.clone()); 85 } 86 catch (CloneNotSupportedException e) { 87 throw new InvalidPdfObjectException(e.getMessage()); 88 } 89 newHt = newPjd.getHashtable(); 90 newHt.remove(PjName.FILTER); 91 } 92 } 93 else if (obj instanceof PjArray) { 94 PjArray pja = (PjArray)obj; 95 Vector v = pja.getVector(); 96 int x; 97 if ( (x = v.indexOf(PjName.FLATEDECODE)) == -1) { 98 return this; 99 } else { 100 try { 102 newPjd = (PjStreamDictionary)(_d.clone()); 103 } 104 catch (CloneNotSupportedException e) { 105 throw new InvalidPdfObjectException(e.getMessage()); 106 } 107 newHt = newPjd.getHashtable(); 108 pja = (PjArray)(newHt.get(PjName.FILTER)); 109 v = pja.getVector(); 110 v.removeElementAt(x); 111 } 112 } 113 InflaterInputStream in = new InflaterInputStream(new ByteArrayInputStream(_s)); 115 ByteArrayOutputStream out = new ByteArrayOutputStream(); 116 int length; 117 byte[] buffer = new byte[PjConst.FLATE_BUFFER_SIZE]; 118 try { 119 while ((length = in.read(buffer, 0, buffer.length)) != -1) { 120 out.write(buffer, 0, length); 121 } 122 out.close(); 123 in.close(); 124 } 125 catch (IOException e) { 126 return this; 128 } 129 return new PjStream(newPjd, out.toByteArray()); 130 } else { 131 throw new InvalidPdfObjectException("Stream filter is not a name or array."); 132 } 133 } 134 135 143 public PjStream flateCompress() throws InvalidPdfObjectException { 144 Hashtable ht = _d.getHashtable(); 148 Object filter = ht.get(PjName.FILTER); 149 if (filter != null) { 150 if ( ( ! (filter instanceof PjName) ) && ( ! (filter instanceof PjArray) ) ) { 151 throw new InvalidPdfObjectException("Stream filter is not a name or array."); 152 } 153 Vector v = null; 155 if (filter instanceof PjName) { 156 v = new Vector(); 157 v.addElement(filter); 158 } 159 else if (filter instanceof PjArray) { 160 v = ((PjArray)filter).getVector(); 161 } 162 PjName name; 164 Enumeration m = v.elements(); 165 Object obj; 166 while (m.hasMoreElements()) { 167 obj = m.nextElement(); 168 if ( ! (obj instanceof PjName) ) { 169 throw new InvalidPdfObjectException( 170 "Stream filter array contins an object that is not a name."); 171 } 172 name = (PjName)obj; 173 if ( (name.equals(PjName.LZWDECODE)) || 174 (name.equals(PjName.RUNLENGTHDECODE)) || 175 (name.equals(PjName.CCITTFAXDECODE)) || 176 (name.equals(PjName.DCTDECODE)) || 177 (name.equals(PjName.FLATEDECODE)) ) { 178 return this; 179 } 180 } 181 } 182 PjStreamDictionary newPjd; 184 try { 185 newPjd = (PjStreamDictionary)(_d.clone()); 186 } 187 catch (CloneNotSupportedException e) { 188 throw new InvalidPdfObjectException(e.getMessage()); 189 } 190 Hashtable newHt = newPjd.getHashtable(); 191 if (filter == null) { 192 newHt.put(PjName.FILTER, PjName.FLATEDECODE); 193 } else { 194 if (filter instanceof PjArray) { 195 Vector v = ((PjArray)filter).getVector(); 196 v.addElement(PjName.FLATEDECODE); 197 } else { 198 Vector v = new Vector(); 200 v.addElement(filter); 201 v.addElement(PjName.FLATEDECODE); 202 newHt.put(PjName.FILTER, new PjArray(v)); 203 } 204 } 205 ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); 207 DeflaterOutputStream out = new DeflaterOutputStream(byteArrayOut); 208 ByteArrayInputStream in = new ByteArrayInputStream(_s); 209 int length; 210 byte[] buffer = new byte[PjConst.FLATE_BUFFER_SIZE]; 211 try { 212 while ((length = in.read(buffer, 0, buffer.length)) != -1) { 213 out.write(buffer, 0, length); 214 } 215 out.close(); 216 in.close(); 217 } 218 catch (IOException e) { 219 return this; 221 } 222 return new PjStream(newPjd, byteArrayOut.toByteArray()); 223 } 224 225 232 public void setLength() { 233 _d.getHashtable().put(new PjName("Length"), 234 new PjNumber(_s.length)); 235 } 236 237 243 public long writePdf(OutputStream os) throws IOException { 244 setLength(); 245 long z = _d.writePdf(os); 246 z = z + writeln(os, ""); 247 z = z + write(os, "stream\n"); 248 z = z + write(os, _s); 249 z = z + write(os, "endstream"); 250 return z; 251 } 252 253 258 public Object clone() throws CloneNotSupportedException { 259 return new PjStream((PjStreamDictionary)(_d.clone()), (byte[])(_s.clone())); 260 } 261 262 272 public void renumber(Hashtable map) { 273 _d.renumber(map); 274 } 275 276 285 public PjStream ascii85Decode() throws InvalidPdfObjectException { 286 Hashtable ht = _d.getHashtable(); 290 Object obj = ht.get(PjName.FILTER); 291 if (obj == null) { 292 return this; 293 } 294 if ( (obj instanceof PjName) || (obj instanceof PjArray) ) { 295 PjStreamDictionary newPjd = null; 296 Hashtable newHt; 297 if (obj instanceof PjName) { 298 PjName pjn = (PjName)obj; 299 if ( ! pjn.equals(PjName.ASCII85DECODE) ) { 300 return this; 301 } else { 302 try { 304 newPjd = (PjStreamDictionary)(_d.clone()); 305 } 306 catch (CloneNotSupportedException e) { 307 throw new InvalidPdfObjectException(e.getMessage()); 308 } 309 newHt = newPjd.getHashtable(); 310 newHt.remove(PjName.FILTER); 311 } 312 } 313 else if (obj instanceof PjArray) { 314 PjArray pja = (PjArray)obj; 315 Vector v = pja.getVector(); 316 int x; 317 if ( (x=v.indexOf(PjName.ASCII85DECODE))==-1) { 318 return this; 319 } else { 320 try { 322 newPjd = (PjStreamDictionary)(_d.clone()); 323 } 324 catch (CloneNotSupportedException e) { 325 throw new InvalidPdfObjectException(e.getMessage()); 326 } 327 newHt = newPjd.getHashtable(); 328 pja = (PjArray)(newHt.get(PjName.FILTER)); 329 v = pja.getVector(); 330 v.removeElementAt(x); 331 } 332 } 333 byte [] decodedBuf = ascii85Decode(_s); 336 if(decodedBuf == null) 337 return this; 338 return new PjStream(newPjd, decodedBuf); 339 } else { 340 throw new InvalidPdfObjectException("Stream filter is not a name or array."); 341 } 342 } 343 344 protected PjStreamDictionary _d; 345 protected byte[] _s; 346 347 static long bytesToLong(byte [] b, int offset, int len) { 348 long val = 0, exp = 0; 349 for(int i=offset+len-1;i >= offset;i--) { 350 for(int j=7;j >= 0;j--) { 351 byte mask = (byte)(128 >> j); 352 if((b[i] & mask) == mask) { 353 val += Math.pow(2, exp); 354 } 355 exp++; 356 } 357 } 358 return val; 359 } 360 361 static char [] ascii85EncodeWord(long word) { 362 long v1, v2, v3, v4, v5; 363 long p4 = (long)Math.pow(85,4); 364 long p3 = (long)Math.pow(85,3); 365 long p2 = (long)Math.pow(85,2); 366 v1 = word/p4; 367 word = word - (v1*p4); 368 v2 = word/p3; 369 word = word - (v2*p3); 370 v3 = word/p2; 371 word = word - (v3*p2); 372 v4 = word/85; 373 word = word - (v4*85); 374 v5 = word; 375 char [] c = new char[5]; 376 c[0] = (char)(v1 + '!'); 377 c[1] = (char)(v2 + '!'); 378 c[2] = (char)(v3 + '!'); 379 c[3] = (char)(v4 + '!'); 380 c[4] = (char)(v5 + '!'); 381 382 return c; 383 } 384 385 public static byte[] ascii85Encode(byte [] src) { 386 ByteArrayOutputStream out = new ByteArrayOutputStream(); 387 try { 388 int groupCount = src.length/4; 389 int extraCount = src.length%4; 390 int i; 391 for(i=0;i<groupCount;i++) { 392 long word = bytesToLong(src, i*4, 4); 393 if(word == 0) { 394 out.write('z'); 395 continue; 396 } 397 char [] c = ascii85EncodeWord(word); 398 out.write(c[0]); 399 out.write(c[1]); 400 out.write(c[2]); 401 out.write(c[3]); 402 out.write(c[4]); 403 } 404 if(extraCount > 0) { 405 byte [] buf = new byte[4]; 406 if(extraCount == 1) { 407 buf[3] = src[i*4]; 408 buf[2] = 0; 409 buf[1] = 0; 410 buf[0] = 0; 411 } else if(extraCount ==2 ) { 412 buf[3] = src[i*4+1]; 413 buf[2] = src[i*4]; 414 buf[1] = 0; 415 buf[0] = 0; 416 } else { 417 buf[3] = src[i*4+2]; 418 buf[2] = src[i*4+1]; 419 buf[1] = src[i*4]; 420 buf[0] = 0; 421 } 422 long word = bytesToLong(buf, 0, 4); 423 char [] c = ascii85EncodeWord(word); 424 for(i=5-(extraCount+1);i<5;i++) { 425 out.write(c[i]); 426 } 427 } 428 out.write('~'); 429 out.write('>'); 430 out.close(); 431 } catch(IOException e) { 432 System.out.println(e); 433 } 434 return out.toByteArray(); 435 } 436 437 static long toWord(byte [] b, int offset, int sigDigits) { 438 long v1, v2, v3, v4, v5; 439 long p4 = (long)Math.pow(85,4); 440 long p3 = (long)Math.pow(85,3); 441 long p2 = (long)Math.pow(85,2); 442 v1 = (b[offset]-'!') * p4; 443 v2 = (b[offset+1]-'!') * p3; 444 v3 = (b[offset+2]-'!') * p2; 445 v4 = (b[offset+3]-'!') * 85; 446 v5 = (b[offset+4]-'!'); 447 if(sigDigits == 5) 448 return v1 + v2 + v3 + v4 + v5; 449 else if (sigDigits == 4) 450 return v2 + v3 + v4 + v5; 451 else if (sigDigits == 3) 452 return v3 + v4 + v5; 453 else if (sigDigits == 2) 454 return v4 + v5; 455 else return v5; 456 } 457 458 public static byte[] ascii85Decode(byte [] src) { 459 ByteArrayOutputStream out = new ByteArrayOutputStream(); 460 try { 461 int ptr = 0; 462 int len = src.length - 2; 465 for(;;) { 466 if(((len - ptr) < 5)&&(src[ptr] != 'z')) { 467 break; 468 } 469 long word = 0; 470 if(src[ptr] == 'z') { 471 ptr++; 472 } else { 473 word = toWord(src, ptr, 5); 474 ptr+=5; 475 } 476 byte b4 = (byte)(word & 255); 477 byte b3 = (byte)((word>>>8) & 255); 478 byte b2 = (byte)((word>>>16) & 255); 479 byte b1 = (byte)((word>>>24) & 255); 480 out.write(b1); 481 out.write(b2); 482 out.write(b3); 483 out.write(b4); 484 } 485 if((len-ptr) > 0) { 486 int count = len-ptr; 488 byte [] buf = new byte[5]; 491 492 int pad = 5-count; 493 int j = 0; 494 for(int i=0;i<5;i++) { 495 if(i<pad) { 496 buf[j++] = 0; 497 } else { 498 buf[j++] = src[ptr]; 499 ptr++; 500 } 501 } 502 long word = toWord(buf, 0, count); 503 byte b4 = (byte)(word & 255); 504 byte b3 = (byte)((word>>>8) & 255); 505 byte b2 = (byte)((word>>>16) & 255); 506 byte b1 = (byte)((word>>>24) & 255); 507 count -= 1; 508 if(count == 1) { 509 out.write(b4); 510 } else if(count == 2) { 511 out.write(b3); 512 out.write(b4); 513 } else if(count == 3) { 514 out.write(b2); 515 out.write(b3); 516 out.write(b4); 517 } 518 } 519 out.close(); 520 } catch(IOException e) { 521 System.out.println(e); 522 } 523 return out.toByteArray(); 524 } 525 } 526 | Popular Tags |