1 50 51 package com.lowagie.text.rtf.graphic; 52 53 import java.io.ByteArrayOutputStream ; 54 import java.io.EOFException ; 55 import java.io.IOException ; 56 import java.io.InputStream ; 57 import java.io.OutputStream ; 58 59 import com.lowagie.text.DocumentException; 60 import com.lowagie.text.Element; 61 import com.lowagie.text.Image; 62 import com.lowagie.text.pdf.codec.wmf.MetaDo; 63 import com.lowagie.text.rtf.RtfElement; 64 import com.lowagie.text.rtf.document.RtfDocument; 65 import com.lowagie.text.rtf.document.output.RtfByteArrayBuffer; 66 import com.lowagie.text.rtf.style.RtfParagraphStyle; 67 import com.lowagie.text.rtf.text.RtfParagraph; 68 69 77 public class RtfImage extends RtfElement { 78 79 82 private static final byte[] PICTURE_GROUP = "\\*\\shppict".getBytes(); 83 86 private static final byte[] PICTURE = "\\pict".getBytes(); 87 90 private static final byte[] PICTURE_JPEG = "\\jpegblip".getBytes(); 91 94 private static final byte[] PICTURE_PNG = "\\pngblip".getBytes(); 95 98 private static final byte[] PICTURE_BMP = "\\dibitmap0".getBytes(); 99 102 private static final byte[] PICTURE_WMF = "\\wmetafile8".getBytes(); 103 106 private static final byte[] PICTURE_WIDTH = "\\picw".getBytes(); 107 110 private static final byte[] PICTURE_HEIGHT = "\\pich".getBytes(); 111 114 private static final byte[] PICTURE_SCALED_WIDTH = "\\picwgoal".getBytes(); 115 118 private static final byte[] PICTURE_SCALED_HEIGHT = "\\pichgoal".getBytes(); 119 122 private static final byte[] PICTURE_SCALE_X = "\\picscalex".getBytes(); 123 126 private static final byte[] PICTURE_SCALE_Y = "\\picscaley".getBytes(); 127 130 private static final byte[] PICTURE_BINARY_DATA = "\\bin".getBytes(); 131 134 private static final int PIXEL_TWIPS_FACTOR = 15; 135 136 139 private final int imageType; 140 143 private final byte[][] imageData; 144 147 private int alignment = Element.ALIGN_LEFT; 148 151 private float width = 0; 152 155 private float height = 0; 156 159 private float plainWidth = 0; 160 163 private float plainHeight = 0; 164 168 private boolean topLevelElement = false; 169 170 177 public RtfImage(RtfDocument doc, Image image) throws DocumentException 178 { 179 super(doc); 180 imageType = image.getOriginalType(); 181 if (!(imageType == Image.ORIGINAL_JPEG || imageType == Image.ORIGINAL_BMP 182 || imageType == Image.ORIGINAL_PNG || imageType == Image.ORIGINAL_WMF || imageType == Image.ORIGINAL_GIF)) { 183 throw new DocumentException("Only BMP, PNG, WMF, GIF and JPEG images are supported by the RTF Writer"); 184 } 185 alignment = image.getAlignment(); 186 width = image.getWidth(); 187 height = image.getHeight(); 188 plainWidth = image.getPlainWidth(); 189 plainHeight = image.getPlainHeight(); 190 this.imageData = getImageData(image); 191 } 192 193 200 private byte[][] getImageData(Image image) throws DocumentException 201 { 202 final int WMF_PLACEABLE_HEADER_SIZE = 22; 203 final RtfByteArrayBuffer bab = new RtfByteArrayBuffer(); 204 205 try { 206 if(imageType == Image.ORIGINAL_BMP) { 207 bab.append(MetaDo.wrapBMP(image)); 208 } else { 209 final byte[] iod = image.getOriginalData(); 210 if(iod == null) { 211 212 final InputStream imageIn = image.getUrl().openStream(); 213 if(imageType == Image.ORIGINAL_WMF) { for(int k = 0; k < WMF_PLACEABLE_HEADER_SIZE; k++) { 215 if(imageIn.read() < 0) throw(new EOFException ("while removing wmf placeable header")); 216 } 217 } 218 bab.write(imageIn); 219 imageIn.close(); 220 221 } else { 222 223 if(imageType == Image.ORIGINAL_WMF) { 224 bab.write(iod, WMF_PLACEABLE_HEADER_SIZE, iod.length - WMF_PLACEABLE_HEADER_SIZE); 226 } else { 227 bab.append(iod); 228 } 229 230 } 231 } 232 233 return(bab.toByteArrayArray()); 234 235 } catch(IOException ioe) { 236 throw new DocumentException(ioe.getMessage()); 237 } 238 } 239 240 241 245 public final static byte[] byte2charLUT = new byte[512]; static { 247 char c = '0'; 248 for(int k = 0; k < 16; k++) { 249 for(int x = 0; x < 16; x++) { 250 byte2charLUT[((k*16)+x)*2] = byte2charLUT[(((x*16)+k)*2)+1] = (byte)c; 251 } 252 if(++c == ':') c = 'a'; 253 } 254 } 255 261 private void writeImageDataHexEncoded(final OutputStream bab) throws IOException 262 { 263 int cnt = 0; 264 for(int k = 0; k < imageData.length; k++) { 265 final byte[] chunk = imageData[k]; 266 for(int x = 0; x < chunk.length; x++) { 267 bab.write(byte2charLUT, (chunk[x]&0xff)*2, 2); 268 if(++cnt == 64) { 269 bab.write('\n'); 270 cnt = 0; 271 } 272 } 273 } 274 if(cnt > 0) bab.write('\n'); 275 } 276 281 private int imageDataSize() 282 { 283 int size = 0; 284 for(int k = 0; k < imageData.length; k++) { 285 size += imageData[k].length; 286 } 287 return(size); 288 } 289 290 296 public byte[] write() 297 { 298 final ByteArrayOutputStream result = new ByteArrayOutputStream (); 299 try { 300 writeContent(result); 301 } catch(Exception ioe) { 302 ioe.printStackTrace(); 303 } 304 305 return(result.toByteArray()); 306 } 307 310 public void writeContent(final OutputStream result) throws IOException 311 { 312 314 if(this.topLevelElement) { 315 result.write(RtfParagraph.PARAGRAPH_DEFAULTS); 316 switch(alignment) { 317 case Element.ALIGN_LEFT: 318 result.write(RtfParagraphStyle.ALIGN_LEFT); 319 break; 320 case Element.ALIGN_RIGHT: 321 result.write(RtfParagraphStyle.ALIGN_RIGHT); 322 break; 323 case Element.ALIGN_CENTER: 324 result.write(RtfParagraphStyle.ALIGN_CENTER); 325 break; 326 case Element.ALIGN_JUSTIFIED: 327 result.write(RtfParagraphStyle.ALIGN_JUSTIFY); 328 break; 329 } 330 } 331 result.write(OPEN_GROUP); 332 result.write(PICTURE_GROUP); 333 result.write(OPEN_GROUP); 334 result.write(PICTURE); 335 switch(imageType) { 336 case Image.ORIGINAL_JPEG: 337 result.write(PICTURE_JPEG); 338 break; 339 case Image.ORIGINAL_PNG: 340 case Image.ORIGINAL_GIF: 341 result.write(PICTURE_PNG); 342 break; 343 case Image.ORIGINAL_WMF: 344 case Image.ORIGINAL_BMP: 345 result.write(PICTURE_WMF); 346 break; 347 } 348 result.write(PICTURE_WIDTH); 349 result.write(intToByteArray((int) width)); 350 result.write(PICTURE_HEIGHT); 351 result.write(intToByteArray((int) height)); 352 if(this.document.getDocumentSettings().isWriteImageScalingInformation()) { 353 result.write(PICTURE_SCALE_X); 354 result.write(intToByteArray((int)(100 * plainWidth / width))); 355 result.write(PICTURE_SCALE_Y); 356 result.write(intToByteArray((int)(100 * plainHeight / height))); 357 } 358 if(this.document.getDocumentSettings().isImagePDFConformance()) { 359 result.write(PICTURE_SCALED_WIDTH); 360 result.write(intToByteArray((int) (plainWidth * RtfElement.TWIPS_FACTOR))); 361 result.write(PICTURE_SCALED_HEIGHT); 362 result.write(intToByteArray((int) (plainHeight * RtfElement.TWIPS_FACTOR))); 363 } else { 364 if(this.width != this.plainWidth || this.imageType == Image.ORIGINAL_BMP) { 365 result.write(PICTURE_SCALED_WIDTH); 366 result.write(intToByteArray((int) (plainWidth * PIXEL_TWIPS_FACTOR))); 367 } 368 if(this.height != this.plainHeight || this.imageType == Image.ORIGINAL_BMP) { 369 result.write(PICTURE_SCALED_HEIGHT); 370 result.write(intToByteArray((int) (plainHeight * PIXEL_TWIPS_FACTOR))); 371 } 372 } 373 374 if(true) { 375 result.write('\n'); 377 result.write(PICTURE_BINARY_DATA); 378 result.write(intToByteArray(imageDataSize())); 379 result.write(DELIMITER); 380 if(result instanceof RtfByteArrayBuffer) { 381 ((RtfByteArrayBuffer)result).append(imageData); 382 } else { 383 for(int k = 0; k < imageData.length; k++) { 384 result.write(imageData[k]); 385 } 386 } 387 } else { 388 result.write(DELIMITER); 390 result.write('\n'); 391 writeImageDataHexEncoded(result); 392 } 393 394 result.write(CLOSE_GROUP); 395 result.write(CLOSE_GROUP); 396 if(this.topLevelElement) { 397 result.write(RtfParagraph.PARAGRAPH); 398 result.write(RtfParagraph.PARAGRAPH); 399 } 400 result.write('\n'); 401 } 402 403 408 public void setAlignment(int alignment) { 409 this.alignment = alignment; 410 } 411 412 418 public void setTopLevelElement(boolean topLevelElement) { 419 this.topLevelElement = topLevelElement; 420 } 421 422 423 } 424 | Popular Tags |