1 17 18 19 20 package org.apache.fop.render.rtf.rtflib.rtfdoc; 21 22 28 29 import org.apache.commons.io.IOUtils; 30 import org.apache.fop.render.rtf.rtflib.tools.ImageConstants; 31 import org.apache.fop.render.rtf.rtflib.tools.ImageUtil; 32 35 import java.io.IOException ; 36 import java.io.InputStream ; 37 import java.io.Writer ; 38 39 import java.io.File ; 40 import java.net.URL ; 41 import java.net.MalformedURLException ; 42 43 62 63 public class RtfExternalGraphic extends RtfElement { 64 65 public static class ExternalGraphicException extends IOException { 66 ExternalGraphicException(String reason) { 67 super(reason); 68 } 69 } 70 71 private static class FormatBase { 75 76 85 public static boolean isFormat(byte[] data) { 86 return false; 87 } 88 89 95 public FormatBase convert(FormatBase format, byte[] data) { 96 return format; 97 } 98 99 106 107 public static FormatBase determineFormat(byte[] data) { 108 109 if (FormatPNG.isFormat(data)) { 110 return new FormatPNG(); 111 } else if (FormatJPG.isFormat(data)) { 112 return new FormatJPG(); 113 } else if (FormatEMF.isFormat(data)) { 114 return new FormatEMF(); 115 } else if (FormatGIF.isFormat(data)) { 116 return new FormatGIF(); 117 } else if (FormatBMP.isFormat(data)) { 118 return new FormatBMP(); 119 } else { 120 return null; 121 } 122 } 123 124 129 public int getType() { 130 return ImageConstants.I_NOT_SUPPORTED; 131 } 132 133 138 public String getRtfTag() { 139 return ""; 140 } 141 } 142 143 private static class FormatGIF extends FormatBase { 144 public static boolean isFormat(byte[] data) { 145 byte [] pattern = new byte [] {(byte) 0x47, (byte) 0x49, (byte) 0x46, (byte) 0x38}; 147 148 return ImageUtil.compareHexValues(pattern, data, 0, true); 149 } 150 151 public int getType() { 152 return ImageConstants.I_GIF; 153 } 154 } 155 156 private static class FormatEMF extends FormatBase { 157 public static boolean isFormat(byte[] data) { 158 byte [] pattern = new byte [] {(byte) 0x01, (byte) 0x00, (byte) 0x00}; 160 161 return ImageUtil.compareHexValues(pattern, data, 0, true); 162 } 163 164 public int getType() { 165 return ImageConstants.I_EMF; 166 } 167 168 public String getRtfTag() { 169 return "emfblip"; 170 } 171 } 172 173 private static class FormatBMP extends FormatBase { 174 public static boolean isFormat(byte[] data) { 175 byte [] pattern = new byte [] {(byte) 0x42, (byte) 0x4D}; 176 177 return ImageUtil.compareHexValues(pattern, data, 0, true); 178 } 179 180 public int getType() { 181 return ImageConstants.I_BMP; 182 } 183 } 184 185 private static class FormatJPG extends FormatBase { 186 public static boolean isFormat(byte[] data) { 187 byte [] pattern = new byte [] {(byte) 0xFF, (byte) 0xD8}; 189 190 return ImageUtil.compareHexValues(pattern, data, 0, true); 191 } 192 193 public int getType() { 194 return ImageConstants.I_JPG; 195 } 196 197 public String getRtfTag() { 198 return "jpegblip"; 199 } 200 } 201 202 private static class FormatPNG extends FormatBase { 203 public static boolean isFormat(byte[] data) { 204 byte [] pattern = new byte [] {(byte) 0x50, (byte) 0x4E, (byte) 0x47}; 206 207 return ImageUtil.compareHexValues(pattern, data, 1, true); 208 } 209 210 public int getType() { 211 return ImageConstants.I_PNG; 212 } 213 214 public String getRtfTag() { 215 return "pngblip"; 216 } 217 } 218 219 223 224 227 protected URL url = null; 228 229 232 protected int height = -1; 233 234 237 protected int heightPercent = -1; 238 239 242 protected int heightDesired = -1; 243 244 247 protected boolean perCentH = false; 248 249 252 protected int width = -1; 253 254 257 protected int widthPercent = -1; 258 259 262 protected int widthDesired = -1; 263 264 267 protected boolean perCentW = false; 268 269 272 protected boolean scaleUniform = false; 273 274 277 protected int graphicCompressionRate = 80; 278 279 280 private byte[] imagedata = null; 281 282 283 private FormatBase imageformat; 284 285 289 290 298 public RtfExternalGraphic(RtfContainer container, Writer writer) throws IOException { 299 super (container, writer); 300 } 301 302 310 public RtfExternalGraphic(RtfContainer container, Writer writer, 311 RtfAttributes attributes) throws IOException { 312 super (container, writer, attributes); 313 } 314 315 316 320 325 protected void writeRtfContent() throws IOException { 326 try { 327 writeRtfContentWithException(); 328 } catch (ExternalGraphicException ie) { 329 writeExceptionInRtf(ie); 330 } 331 } 332 333 338 protected void writeRtfContentWithException() throws IOException { 339 340 if (writer == null) { 341 return; 342 } 343 344 345 if (url == null) { 346 throw new ExternalGraphicException("The attribute 'url' of " 347 + "<fo:external-graphic> is null."); 348 } 349 350 String linkToRoot = System.getProperty("jfor_link_to_root"); 351 if (linkToRoot != null) { 352 writer.write("{\\field {\\* \\fldinst { INCLUDEPICTURE \""); 353 writer.write(linkToRoot); 354 File urlFile = new File (url.getFile()); 355 writer.write(urlFile.getName()); 356 writer.write("\" \\\\* MERGEFORMAT \\\\d }}}"); 357 return; 358 } 359 360 362 363 if (imagedata == null) { 364 try { 365 final InputStream in = url.openStream(); 366 try { 367 imagedata = IOUtils.toByteArray(url.openStream()); 368 } finally { 369 IOUtils.closeQuietly(in); 370 } 371 } catch (Exception e) { 372 throw new ExternalGraphicException("The attribute 'src' of " 373 + "<fo:external-graphic> has a invalid value: '" 374 + url + "' (" + e + ")"); 375 } 376 } 377 378 if (imagedata == null) { 379 return; 380 } 381 382 String file = url.getFile (); 384 imageformat = FormatBase.determineFormat(imagedata); 385 if (imageformat != null) { 386 imageformat = imageformat.convert(imageformat, imagedata); 387 } 388 389 if (imageformat == null 390 || imageformat.getType() == ImageConstants.I_NOT_SUPPORTED 391 || "".equals(imageformat.getRtfTag())) { 392 throw new ExternalGraphicException("The tag <fo:external-graphic> " 393 + "does not support " 394 + file.substring(file.lastIndexOf(".") + 1) 395 + " - image type."); 396 } 397 398 400 writeGroupMark(true); 401 writeStarControlWord("shppict"); 402 writeGroupMark(true); 403 writeControlWord("pict"); 404 405 StringBuffer buf = new StringBuffer (imagedata.length * 3); 406 407 writeControlWord(imageformat.getRtfTag()); 408 409 computeImageSize(); 410 writeSizeInfo(); 411 412 for (int i = 0; i < imagedata.length; i++) { 413 int iData = imagedata [i]; 414 415 if (iData < 0) { 417 iData += 256; 418 } 419 420 if (iData < 16) { 421 buf.append('0'); 423 } 424 425 buf.append(Integer.toHexString(iData)); 426 } 427 428 int len = buf.length(); 429 char[] chars = new char[len]; 430 431 buf.getChars(0, len, chars, 0); 432 writer.write(chars); 433 434 436 writeGroupMark(false); 437 writeGroupMark(false); 438 } 439 440 private void computeImageSize () { 441 if (imageformat.getType() == ImageConstants.I_PNG) { 442 width = ImageUtil.getIntFromByteArray(imagedata, 16, 4, true); 443 height = ImageUtil.getIntFromByteArray(imagedata, 20, 4, true); 444 } else if (imageformat.getType() == ImageConstants.I_JPG) { 445 int basis = -1; 446 byte ff = (byte) 0xff; 447 byte c0 = (byte) 0xc0; 448 for (int i = 0; i < imagedata.length; i++) { 449 byte b = imagedata[i]; 450 if (b != ff) { 451 continue; 452 } 453 if (i == imagedata.length - 1) { 454 continue; 455 } 456 b = imagedata[i + 1]; 457 if (b != c0) { 458 continue; 459 } 460 basis = i + 5; 461 break; 462 } 463 464 if (basis != -1) { 465 width = ImageUtil.getIntFromByteArray(imagedata, basis + 2, 2, true); 466 height = ImageUtil.getIntFromByteArray(imagedata, basis, 2, true); 467 } 468 } else if (imageformat.getType() == ImageConstants.I_EMF) { 469 int i = 0; 470 471 i = ImageUtil.getIntFromByteArray(imagedata, 151, 4, false); 472 if (i != 0 ) { 473 width = i; 474 } 475 476 i = ImageUtil.getIntFromByteArray(imagedata, 155, 4, false); 477 if (i != 0 ) { 478 height = i; 479 } 480 481 } 482 } 483 484 private void writeSizeInfo () throws IOException { 485 if (width != -1) { 487 writeControlWord("picw" + width); 488 } 489 if (height != -1) { 490 writeControlWord("pich" + height); 491 } 492 493 if (widthDesired != -1) { 494 if (perCentW) { 495 writeControlWord("picscalex" + widthDesired); 496 } else { 497 writeControlWord("picwgoal" + widthDesired); 499 } 500 501 } else if (scaleUniform && heightDesired != -1) { 502 if (perCentH) { 503 writeControlWord("picscalex" + heightDesired); 504 } else { 505 writeControlWord("picscalex" + heightDesired * 100 / height); 506 } 507 } 508 509 if (heightDesired != -1) { 510 if (perCentH) { 511 writeControlWord("picscaley" + heightDesired); 512 } else { 513 writeControlWord("pichgoal" + heightDesired); 515 } 516 517 } else if (scaleUniform && widthDesired != -1) { 518 if (perCentW) { 519 writeControlWord("picscaley" + widthDesired); 520 } else { 521 writeControlWord("picscaley" + widthDesired * 100 / width); 522 } 523 } 524 } 525 526 530 535 public void setHeight(String theHeight) { 536 this.heightDesired = ImageUtil.getInt(theHeight); 537 this.perCentH = ImageUtil.isPercent(theHeight); 538 } 539 540 545 public void setWidth(String theWidth) { 546 this.widthDesired = ImageUtil.getInt(theWidth); 547 this.perCentW = ImageUtil.isPercent(theWidth); 548 } 549 550 557 public void setScaling(String value) { 558 if (value.equalsIgnoreCase("uniform")) { 559 this.scaleUniform = true; 560 } 561 } 562 563 569 public void setImageData(byte[] data) throws IOException { 570 this.imagedata = data; 571 } 572 573 579 public void setURL(String urlString) throws IOException { 580 URL tmpUrl = null; 581 try { 582 tmpUrl = new URL (urlString); 583 } catch (MalformedURLException e) { 584 try { 585 tmpUrl = new File (urlString).toURL (); 586 } catch (MalformedURLException ee) { 587 throw new ExternalGraphicException("The attribute 'src' of " 588 + "<fo:external-graphic> has a invalid value: '" 589 + urlString + "' (" + ee + ")"); 590 } 591 } 592 this.url = tmpUrl; 593 } 594 595 599 public int getCompressionRate () { 600 return graphicCompressionRate; 601 } 602 603 609 public boolean setCompressionRate (int percent) { 610 if (percent < 1 || percent > 100) { 611 return false; 612 } 613 614 graphicCompressionRate = percent; 615 return true; 616 } 617 618 619 623 626 public boolean isEmpty() { 627 return url == null; 628 } 629 } 630 | Popular Tags |