Save This Page
Home » iText-src-2.1.3 » com.lowagie » text » rtf » graphic » [javadoc | source]
    1   /*
    2    * $Id: RtfImage.java 3433 2008-05-24 19:32:11Z xlv $
    3    *
    4    * Copyright 2001, 2002, 2003, 2004 by Mark Hall
    5    *
    6    * The contents of this file are subject to the Mozilla Public License Version 1.1
    7    * (the "License"); you may not use this file except in compliance with the License.
    8    * You may obtain a copy of the License at http://www.mozilla.org/MPL/
    9    *
   10    * Software distributed under the License is distributed on an "AS IS" basis,
   11    * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
   12    * for the specific language governing rights and limitations under the License.
   13    *
   14    * The Original Code is 'iText, a free JAVA-PDF library'.
   15    *
   16    * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
   17    * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
   18    * All Rights Reserved.
   19    * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
   20    * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
   21    *
   22    * Contributor(s): all the names of the contributors are added in the source code
   23    * where applicable.
   24    *
   25    * Alternatively, the contents of this file may be used under the terms of the
   26    * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
   27    * provisions of LGPL are applicable instead of those above.  If you wish to
   28    * allow use of your version of this file only under the terms of the LGPL
   29    * License and not to allow others to use your version of this file under
   30    * the MPL, indicate your decision by deleting the provisions above and
   31    * replace them with the notice and other provisions required by the LGPL.
   32    * If you do not delete the provisions above, a recipient may use your version
   33    * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
   34    *
   35    * This library is free software; you can redistribute it and/or modify it
   36    * under the terms of the MPL as stated above or under the terms of the GNU
   37    * Library General Public License as published by the Free Software Foundation;
   38    * either version 2 of the License, or any later version.
   39    *
   40    * This library is distributed in the hope that it will be useful, but WITHOUT
   41    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   42    * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
   43    * details.
   44    *
   45    * If you didn't download this code from the following link, you should check if
   46    * you aren't using an obsolete version:
   47    * http://www.lowagie.com/iText/
   48    */
   49   
   50   package com.lowagie.text.rtf.graphic;
   51   
   52   import java.io.EOFException;
   53   import java.io.IOException;
   54   import java.io.InputStream;
   55   import java.io.OutputStream;
   56   
   57   import com.lowagie.text.DocumentException;
   58   import com.lowagie.text.Element;
   59   import com.lowagie.text.Image;
   60   import com.lowagie.text.pdf.codec.wmf.MetaDo;
   61   import com.lowagie.text.rtf.RtfElement;
   62   import com.lowagie.text.rtf.document.RtfDocument;
   63   import com.lowagie.text.rtf.document.output.RtfByteArrayBuffer;
   64   import com.lowagie.text.rtf.style.RtfParagraphStyle;
   65   import com.lowagie.text.rtf.text.RtfParagraph;
   66   
   67   /**
   68    * The RtfImage contains one image. Supported image types are jpeg, png, wmf, bmp.
   69    * 
   70    * @version $Id: RtfImage.java 3433 2008-05-24 19:32:11Z xlv $
   71    * @author Mark Hall (Mark.Hall@mail.room3b.eu)
   72    * @author Paulo Soares
   73    * @author Thomas Bickel (tmb99@inode.at)
   74    */
   75   public class RtfImage extends RtfElement {
   76       
   77       /**
   78        * Constant for the shape/picture group
   79        */
   80       private static final byte[] PICTURE_GROUP = "\\*\\shppict".getBytes();
   81       /**
   82        * Constant for a picture
   83        */
   84       private static final byte[] PICTURE = "\\pict".getBytes();
   85       /**
   86        * Constant for a jpeg image
   87        */
   88       private static final byte[] PICTURE_JPEG = "\\jpegblip".getBytes();
   89       /**
   90        * Constant for a png image
   91        */
   92       private static final byte[] PICTURE_PNG = "\\pngblip".getBytes();
   93       /**
   94        * Constant for a wmf image
   95        */
   96       private static final byte[] PICTURE_WMF = "\\wmetafile8".getBytes();
   97       /**
   98        * Constant for the picture width
   99        */
  100       private static final byte[] PICTURE_WIDTH = "\\picw".getBytes();
  101       /**
  102        * Constant for the picture height
  103        */
  104       private static final byte[] PICTURE_HEIGHT = "\\pich".getBytes();
  105       /**
  106        * Constant for the picture width scale
  107        */
  108       private static final byte[] PICTURE_SCALED_WIDTH = "\\picwgoal".getBytes();
  109       /**
  110        * Constant for the picture height scale
  111        */
  112       private static final byte[] PICTURE_SCALED_HEIGHT = "\\pichgoal".getBytes();
  113       /**
  114        * Constant for horizontal picture scaling
  115        */
  116       private static final byte[] PICTURE_SCALE_X = "\\picscalex".getBytes();
  117       /**
  118        * Constant for vertical picture scaling
  119        */
  120       private static final byte[] PICTURE_SCALE_Y = "\\picscaley".getBytes();
  121       /**
  122        * "\bin" constant
  123        */
  124       private static final byte[] PICTURE_BINARY_DATA = "\\bin".getBytes();
  125       /**
  126        * Constant for converting pixels to twips
  127        */
  128       private static final int PIXEL_TWIPS_FACTOR = 15;
  129       
  130       /**
  131        * The type of image this is.
  132        */
  133       private final int imageType;
  134       /**
  135        * Binary image data.
  136        */
  137       private final byte[][] imageData;
  138       /**
  139        * The alignment of this picture
  140        */
  141       private int alignment = Element.ALIGN_LEFT;
  142       /**
  143        * The width of this picture
  144        */
  145       private float width = 0;
  146       /**
  147        * The height of this picture
  148        */
  149       private float height = 0;
  150       /**
  151        * The intended display width of this picture
  152        */
  153       private float plainWidth = 0;
  154       /**
  155        * The intended display height of this picture
  156        */
  157       private float plainHeight = 0;
  158       /**
  159        * Whether this RtfImage is a top level element and should
  160        * be an extra paragraph.
  161        */
  162       private boolean topLevelElement = false;
  163       
  164       /**
  165        * Constructs a RtfImage for an Image.
  166        * 
  167        * @param doc The RtfDocument this RtfImage belongs to
  168        * @param image The Image that this RtfImage wraps
  169        * @throws DocumentException If an error occurred accessing the image content
  170        */
  171       public RtfImage(RtfDocument doc, Image image) throws DocumentException
  172       {
  173           super(doc);
  174           imageType = image.getOriginalType();
  175           if (!(imageType == Image.ORIGINAL_JPEG || imageType == Image.ORIGINAL_BMP
  176                   || imageType == Image.ORIGINAL_PNG || imageType == Image.ORIGINAL_WMF || imageType == Image.ORIGINAL_GIF)) {
  177               throw new DocumentException("Only BMP, PNG, WMF, GIF and JPEG images are supported by the RTF Writer");
  178           }
  179           alignment = image.getAlignment();
  180           width = image.getWidth();
  181           height = image.getHeight();
  182           plainWidth = image.getPlainWidth();
  183           plainHeight = image.getPlainHeight();
  184           this.imageData = getImageData(image);
  185       }
  186       
  187       /**
  188        * Extracts the image data from the Image.
  189        * 
  190        * @param image The image for which to extract the content
  191        * @return The raw image data, not formated
  192        * @throws DocumentException If an error occurs accessing the image content
  193        */
  194       private byte[][] getImageData(Image image) throws DocumentException 
  195       {
  196       	final int WMF_PLACEABLE_HEADER_SIZE = 22;
  197           final RtfByteArrayBuffer bab = new RtfByteArrayBuffer();
  198           
  199           try {
  200               if(imageType == Image.ORIGINAL_BMP) {
  201               	bab.append(MetaDo.wrapBMP(image));
  202               } else {            	
  203               	final byte[] iod = image.getOriginalData();
  204               	if(iod == null) {
  205               		
  206                   	final InputStream imageIn = image.getUrl().openStream();
  207                       if(imageType == Image.ORIGINAL_WMF) { //remove the placeable header first
  208                       	for(int k = 0; k < WMF_PLACEABLE_HEADER_SIZE; k++) {
  209   							if(imageIn.read() < 0) throw new EOFException("while removing wmf placeable header");
  210   						}
  211                       }
  212                       bab.write(imageIn);
  213                   	imageIn.close();
  214                       
  215                   } else {
  216                   	
  217                   	if(imageType == Image.ORIGINAL_WMF) {
  218                   		//remove the placeable header                		
  219                   		bab.write(iod, WMF_PLACEABLE_HEADER_SIZE, iod.length - WMF_PLACEABLE_HEADER_SIZE);
  220                   	} else {
  221                   		bab.append(iod);
  222                   	}
  223                   	
  224                   }
  225               }
  226               
  227               return bab.toByteArrayArray();
  228               
  229           } catch(IOException ioe) {
  230               throw new DocumentException(ioe.getMessage());
  231           }
  232       }
  233       
  234       
  235       /**
  236        * lookup table used for converting bytes to hex chars.
  237        * TODO Should probably be refactored into a helper class
  238        */
  239       public final static byte[] byte2charLUT = new byte[512]; //'0001020304050607 ... fafbfcfdfeff'
  240       static {
  241       	char c = '0';
  242       	for(int k = 0; k < 16; k++) {
  243       		for(int x = 0; x < 16; x++) {
  244   				byte2charLUT[((k*16)+x)*2] = byte2charLUT[(((x*16)+k)*2)+1] = (byte)c;
  245   			}
  246       		if(++c == ':') c = 'a';
  247   		}
  248       }
  249       
  250       /**
  251        * Writes the image data to the given buffer as hex encoded text.
  252        * 
  253        * @param bab
  254        * @throws IOException
  255        */
  256       private void writeImageDataHexEncoded(final OutputStream bab) throws IOException
  257       {
  258       	int cnt = 0;
  259       	for(int k = 0; k < imageData.length; k++) {
  260       		final byte[] chunk = imageData[k];
  261   			for(int x = 0; x < chunk.length; x++) {
  262   				bab.write(byte2charLUT, (chunk[x]&0xff)*2, 2);
  263   				if(++cnt == 64) {
  264   					bab.write('\n');
  265   					cnt = 0;
  266   				}
  267   			}
  268   		}    	
  269      		if(cnt > 0) bab.write('\n');
  270       }
  271       
  272       /**
  273        * Returns the image raw data size in bytes.
  274        * 
  275        * @return the size in bytes
  276        */
  277       private int imageDataSize()
  278       {
  279   		int size = 0;
  280       	for(int k = 0; k < imageData.length; k++) {
  281       		size += imageData[k].length;
  282       	}   
  283       	return size;
  284       }
  285       
  286       /**
  287        * Writes the RtfImage content
  288        */ 
  289       public void writeContent(final OutputStream result) throws IOException
  290       {
  291       	
  292           if(this.topLevelElement) {
  293               result.write(RtfParagraph.PARAGRAPH_DEFAULTS);
  294               switch(alignment) {
  295                   case Element.ALIGN_LEFT:
  296                       result.write(RtfParagraphStyle.ALIGN_LEFT);
  297                       break;
  298                   case Element.ALIGN_RIGHT:
  299                       result.write(RtfParagraphStyle.ALIGN_RIGHT);
  300                       break;
  301                   case Element.ALIGN_CENTER:
  302                       result.write(RtfParagraphStyle.ALIGN_CENTER);
  303                       break;
  304                   case Element.ALIGN_JUSTIFIED:
  305                       result.write(RtfParagraphStyle.ALIGN_JUSTIFY);
  306                       break;
  307               }
  308           }
  309           result.write(OPEN_GROUP);
  310           result.write(PICTURE_GROUP);
  311           result.write(OPEN_GROUP);
  312           result.write(PICTURE);
  313           switch(imageType) {
  314           	case Image.ORIGINAL_JPEG:
  315           	    result.write(PICTURE_JPEG);
  316           		break;
  317           	case Image.ORIGINAL_PNG:
  318               case Image.ORIGINAL_GIF:
  319           	    result.write(PICTURE_PNG);
  320           		break;
  321           	case Image.ORIGINAL_WMF:
  322           	case Image.ORIGINAL_BMP:
  323           	    result.write(PICTURE_WMF);
  324           		break;
  325           }
  326           result.write(PICTURE_WIDTH);
  327           result.write(intToByteArray((int) width));
  328           result.write(PICTURE_HEIGHT);
  329           result.write(intToByteArray((int) height));
  330           if(this.document.getDocumentSettings().isWriteImageScalingInformation()) {
  331               result.write(PICTURE_SCALE_X);
  332               result.write(intToByteArray((int)(100 * plainWidth / width)));
  333               result.write(PICTURE_SCALE_Y);
  334               result.write(intToByteArray((int)(100 * plainHeight / height)));
  335           }
  336           if(this.document.getDocumentSettings().isImagePDFConformance()) {
  337               result.write(PICTURE_SCALED_WIDTH);
  338               result.write(intToByteArray((int) (plainWidth * RtfElement.TWIPS_FACTOR)));
  339               result.write(PICTURE_SCALED_HEIGHT);
  340               result.write(intToByteArray((int) (plainHeight * RtfElement.TWIPS_FACTOR)));
  341           } else {
  342               if(this.width != this.plainWidth || this.imageType == Image.ORIGINAL_BMP) {
  343                   result.write(PICTURE_SCALED_WIDTH);
  344                   result.write(intToByteArray((int) (plainWidth * PIXEL_TWIPS_FACTOR)));
  345               }
  346               if(this.height != this.plainHeight || this.imageType == Image.ORIGINAL_BMP) {
  347                   result.write(PICTURE_SCALED_HEIGHT);
  348                   result.write(intToByteArray((int) (plainHeight * PIXEL_TWIPS_FACTOR)));
  349               }
  350           }
  351   
  352           if(this.document.getDocumentSettings().isImageWrittenAsBinary()) {
  353           	//binary
  354           	result.write('\n');
  355           	result.write(PICTURE_BINARY_DATA);
  356           	result.write(intToByteArray(imageDataSize()));
  357               result.write(DELIMITER);
  358               if(result instanceof RtfByteArrayBuffer) {
  359               	((RtfByteArrayBuffer)result).append(imageData);
  360               } else {
  361               	for(int k = 0; k < imageData.length; k++) {
  362   					result.write(imageData[k]);
  363   				}
  364               }
  365           } else {
  366           	//hex encoded
  367               result.write(DELIMITER);
  368           	result.write('\n');
  369           	writeImageDataHexEncoded(result);
  370           }
  371           
  372           result.write(CLOSE_GROUP);
  373           result.write(CLOSE_GROUP);
  374           if(this.topLevelElement) {
  375               result.write(RtfParagraph.PARAGRAPH);
  376               result.write(RtfParagraph.PARAGRAPH);
  377           }
  378           result.write('\n');    	
  379       }
  380       
  381       /**
  382        * Sets the alignment of this RtfImage. Uses the alignments from com.lowagie.text.Element.
  383        * 
  384        * @param alignment The alignment to use.
  385        */
  386       public void setAlignment(int alignment) {
  387           this.alignment = alignment;
  388       }
  389       
  390       /**
  391        * Set whether this RtfImage should behave like a top level element
  392        * and enclose itself in a paragraph.
  393        * 
  394        * @param topLevelElement Whether to behave like a top level element.
  395        */
  396       public void setTopLevelElement(boolean topLevelElement) {
  397           this.topLevelElement = topLevelElement;
  398       }
  399       
  400       
  401   }

Save This Page
Home » iText-src-2.1.3 » com.lowagie » text » rtf » graphic » [javadoc | source]