From 6025b6016517c6d898d8957d1d7e03ba71431912 Mon Sep 17 00:00:00 2001 From: tknall Date: Fri, 1 Dec 2006 12:20:24 +0000 Subject: Initial import of release 2.2. git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@4 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- .../pdmodel/graphics/PDExtendedGraphicsState.java | 724 +++++++++++++++++++++ .../org/pdfbox/pdmodel/graphics/PDFontSetting.java | 133 ++++ .../pdfbox/pdmodel/graphics/PDGraphicsState.java | 438 +++++++++++++ .../pdfbox/pdmodel/graphics/PDLineDashPattern.java | 135 ++++ .../pdfbox/pdmodel/graphics/color/PDCalGray.java | 240 +++++++ .../pdfbox/pdmodel/graphics/color/PDCalRGB.java | 289 ++++++++ .../pdmodel/graphics/color/PDColorSpace.java | 97 +++ .../graphics/color/PDColorSpaceFactory.java | 218 +++++++ .../graphics/color/PDColorSpaceInstance.java | 130 ++++ .../pdmodel/graphics/color/PDDeviceCMYK.java | 137 ++++ .../pdmodel/graphics/color/PDDeviceGray.java | 112 ++++ .../pdfbox/pdmodel/graphics/color/PDDeviceN.java | 244 +++++++ .../graphics/color/PDDeviceNAttributes.java | 126 ++++ .../pdfbox/pdmodel/graphics/color/PDDeviceRGB.java | 130 ++++ .../org/pdfbox/pdmodel/graphics/color/PDGamma.java | 151 +++++ .../pdfbox/pdmodel/graphics/color/PDICCBased.java | 343 ++++++++++ .../pdfbox/pdmodel/graphics/color/PDIndexed.java | 271 ++++++++ .../org/pdfbox/pdmodel/graphics/color/PDLab.java | 300 +++++++++ .../pdfbox/pdmodel/graphics/color/PDPattern.java | 122 ++++ .../pdmodel/graphics/color/PDSeparation.java | 198 ++++++ .../pdmodel/graphics/color/PDTristimulus.java | 155 +++++ .../org/pdfbox/pdmodel/graphics/color/package.html | 9 + .../java/org/pdfbox/pdmodel/graphics/package.html | 9 + .../pdfbox/pdmodel/graphics/predictor/Average.java | 81 +++ .../pdfbox/pdmodel/graphics/predictor/None.java | 104 +++ .../pdfbox/pdmodel/graphics/predictor/Paeth.java | 121 ++++ .../graphics/predictor/PredictorAlgorithm.java | 336 ++++++++++ .../org/pdfbox/pdmodel/graphics/predictor/Sub.java | 86 +++ .../org/pdfbox/pdmodel/graphics/predictor/Up.java | 100 +++ .../pdfbox/pdmodel/graphics/predictor/Uptimum.java | 153 +++++ .../pdfbox/pdmodel/graphics/predictor/package.html | 10 + .../pdfbox/pdmodel/graphics/xobject/PDCcitt.java | 598 +++++++++++++++++ .../pdmodel/graphics/xobject/PDInlinedImage.java | 201 ++++++ .../pdfbox/pdmodel/graphics/xobject/PDJpeg.java | 156 +++++ .../pdmodel/graphics/xobject/PDPixelMap.java | 236 +++++++ .../pdfbox/pdmodel/graphics/xobject/PDXObject.java | 207 ++++++ .../pdmodel/graphics/xobject/PDXObjectForm.java | 120 ++++ .../pdmodel/graphics/xobject/PDXObjectImage.java | 244 +++++++ .../pdfbox/pdmodel/graphics/xobject/package.html | 9 + 39 files changed, 7473 insertions(+) create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/PDExtendedGraphicsState.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/PDFontSetting.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/PDGraphicsState.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/PDLineDashPattern.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/color/PDCalGray.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/color/PDCalRGB.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/color/PDColorSpace.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/color/PDColorSpaceFactory.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/color/PDColorSpaceInstance.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceCMYK.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceGray.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceN.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceNAttributes.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceRGB.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/color/PDGamma.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/color/PDICCBased.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/color/PDIndexed.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/color/PDLab.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/color/PDPattern.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/color/PDSeparation.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/color/PDTristimulus.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/color/package.html create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/package.html create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/predictor/Average.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/predictor/None.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/predictor/Paeth.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/predictor/PredictorAlgorithm.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/predictor/Sub.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/predictor/Up.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/predictor/Uptimum.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/predictor/package.html create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDCcitt.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDInlinedImage.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDJpeg.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDPixelMap.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDXObject.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDXObjectForm.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDXObjectImage.java create mode 100644 src/main/java/org/pdfbox/pdmodel/graphics/xobject/package.html (limited to 'src/main/java/org/pdfbox/pdmodel/graphics') diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/PDExtendedGraphicsState.java b/src/main/java/org/pdfbox/pdmodel/graphics/PDExtendedGraphicsState.java new file mode 100644 index 0000000..3fe9c40 --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/PDExtendedGraphicsState.java @@ -0,0 +1,724 @@ +/** + * Copyright (c) 2003, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.pdmodel.graphics; + +import org.pdfbox.cos.COSArray; +import org.pdfbox.cos.COSBase; +import org.pdfbox.cos.COSBoolean; +import org.pdfbox.cos.COSDictionary; +import org.pdfbox.cos.COSFloat; +import org.pdfbox.cos.COSInteger; +import org.pdfbox.cos.COSName; +import org.pdfbox.cos.COSNumber; + +import org.pdfbox.pdmodel.common.COSObjectable; + +import java.io.IOException; + +import java.util.Iterator; + +/** + * This class represents the graphics state dictionary that is stored in the PDF document. + * The PDGraphicsStateValue holds the current runtime values as a stream is being executed. + * + * @author Ben Litchfield (ben@csh.rit.edu) + * @version $Revision: 1.4 $ + */ +public class PDExtendedGraphicsState implements COSObjectable +{ + private static final COSName LW = COSName.getPDFName( "LW" ); + private static final COSName LC = COSName.getPDFName( "LC" ); + private static final COSName LJ = COSName.getPDFName( "LJ" ); + private static final COSName ML = COSName.getPDFName( "ML" ); + private static final COSName D = COSName.getPDFName( "D" ); + private static final COSName RI = COSName.getPDFName( "RI" ); + private static final COSName OP = COSName.getPDFName( "OP" ); + private static final COSName OP_NS = COSName.getPDFName( "op" ); + private static final COSName OPM = COSName.getPDFName( "OPM" ); + private static final COSName FONT = COSName.getPDFName( "Font" ); + private static final COSName FL = COSName.getPDFName( "FL" ); + private static final COSName SM = COSName.getPDFName( "SM" ); + private static final COSName SA = COSName.getPDFName( "SA" ); + private static final COSName CA = COSName.getPDFName( "CA" ); + private static final COSName CA_NS = COSName.getPDFName( "ca" ); + private static final COSName AIS = COSName.getPDFName( "AIS" ); + private static final COSName TK = COSName.getPDFName( "TK" ); + + /** + * Rendering intent constants, see PDF Reference 1.5 Section 4.5.4 Rendering Intents. + */ + public static final String RENDERING_INTENT_ABSOLUTE_COLORIMETRIC = "AbsoluteColorimetric"; + /** + * Rendering intent constants, see PDF Reference 1.5 Section 4.5.4 Rendering Intents. + */ + public static final String RENDERING_INTENT_RELATIVE_COLORIMETRIC = "RelativeColorimetric"; + /** + * Rendering intent constants, see PDF Reference 1.5 Section 4.5.4 Rendering Intents. + */ + public static final String RENDERING_INTENT_SATURATION = "Saturation"; + /** + * Rendering intent constants, see PDF Reference 1.5 Section 4.5.4 Rendering Intents. + */ + public static final String RENDERING_INTENT_PERCEPTUAL = "Perceptual"; + + + private COSDictionary graphicsState; + + /** + * Default constructor, creates blank graphics state. + */ + public PDExtendedGraphicsState() + { + graphicsState = new COSDictionary(); + graphicsState.setItem( COSName.TYPE, COSName.getPDFName( "ExtGState" ) ); + } + + /** + * Create a graphics state from an existing dictionary. + * + * @param dictionary The existing graphics state. + */ + public PDExtendedGraphicsState( COSDictionary dictionary ) + { + graphicsState = dictionary; + } + + /** + * This will implement the gs operator. + * + * @param gs The state to copy this dictionaries values into. + * + * @throws IOException If there is an error copying font information. + */ + public void copyIntoGraphicsState( PDGraphicsState gs ) throws IOException + { + Iterator keys = graphicsState.keyList().iterator(); + while( keys.hasNext() ) + { + COSName key = (COSName)keys.next(); + if( key.equals( LW ) ) + { + gs.setLineWidth( getLineWidth().doubleValue() ); + } + else if( key.equals( LC ) ) + { + gs.setLineCap( getLineCapStyle().intValue() ); + } + else if( key.equals( LJ ) ) + { + gs.setLineJoin( getLineJoinStyle().intValue() ); + } + else if( key.equals( ML ) ) + { + gs.setMiterLimit( getMiterLimit().doubleValue() ); + } + else if( key.equals( D ) ) + { + gs.setLineDashPattern( getLineDashPattern() ); + } + else if( key.equals( RI ) ) + { + gs.setRenderingIntent( getRenderingIntent() ); + } + else if( key.equals( OPM ) ) + { + gs.setOverprintMode( getOverprintMode().doubleValue() ); + } + else if( key.equals( FONT ) ) + { + PDFontSetting setting = getFontSetting(); + gs.getTextState().setFont( setting.getFont() ); + gs.getTextState().setFontSize( setting.getFontSize() ); + } + else if( key.equals( FL ) ) + { + gs.setFlatness( getFlatnessTolerance().floatValue() ); + } + else if( key.equals( SM ) ) + { + gs.setSmoothness( getSmoothnessTolerance().floatValue() ); + } + else if( key.equals( SA ) ) + { + gs.setStrokeAdjustment( getAutomaticStrokeAdjustment().booleanValue() ); + } + else if( key.equals( CA ) ) + { + gs.setAlphaConstants( getStrokingAlpaConstant().floatValue() ); + }/** + else if( key.equals( CA_NS ) ) + { + }**/ + else if( key.equals( AIS ) ) + { + gs.setAlphaSource( getAlpaSourceFlag().booleanValue() ); + } + else if( key.equals( TK ) ) + { + gs.getTextState().setKnockoutFlag( getTextKnockoutFlag().booleanValue() ); + } + } + } + + /** + * This will get the underlying dictionary that this class acts on. + * + * @return The underlying dictionary for this class. + */ + public COSDictionary getCOSDictionary() + { + return graphicsState; + } + + /** + * Convert this standard java object to a COS object. + * + * @return The cos object that matches this Java object. + */ + public COSBase getCOSObject() + { + return graphicsState; + } + + /** + * This will get the line width. This will return null if there is no line width + * + * @return null or the LW value of the dictionary. + */ + public Float getLineWidth() + { + return getFloatItem( LW ); + } + + /** + * This will set the line width. + * + * @param width The line width for the object. + */ + public void setLineWidth( Float width ) + { + setFloatItem( LW, width ); + } + + /** + * This will get the line cap style. + * + * @return null or the LC value of the dictionary. + */ + public Long getLineCapStyle() + { + return getLongItem( LC ); + } + + /** + * This will set the line cap style for the graphics state. + * + * @param style The new line cap style to set. + */ + public void setLineCapStyle( Long style ) + { + setLongItem( LC, style ); + } + + /** + * This will get the line join style. + * + * @return null or the LJ value in the dictionary. + */ + public Long getLineJoinStyle() + { + return getLongItem( LJ ); + } + + /** + * This will set the line join style. + * + * @param style The new line join style. + */ + public void setLineJoinStyle( Long style ) + { + setLongItem( LJ, style ); + } + + + /** + * This will get the miter limit. + * + * @return null or the ML value in the dictionary. + */ + public Float getMiterLimit() + { + return getFloatItem( ML ); + } + + /** + * This will set the miter limit for the graphics state. + * + * @param miterLimit The new miter limit value + */ + public void setMiterLimit( Float miterLimit ) + { + setFloatItem( ML, miterLimit ); + } + + /** + * This will get the dash pattern. + * + * @return null or the D value in the dictionary. + */ + public PDLineDashPattern getLineDashPattern() + { + PDLineDashPattern retval = null; + COSArray dp = (COSArray)graphicsState.getDictionaryObject( D ); + if( dp != null ) + { + retval = new PDLineDashPattern( dp ); + } + return retval; + } + + /** + * This will set the dash pattern for the graphics state. + * + * @param dashPattern The dash pattern + */ + public void setLineDashPattern( PDLineDashPattern dashPattern ) + { + graphicsState.setItem( D, dashPattern.getCOSObject() ); + } + + /** + * This will get the rendering intent. + * + * @return null or the RI value in the dictionary. + */ + public String getRenderingIntent() + { + String retval = null; + COSName ri = (COSName)graphicsState.getDictionaryObject( RI ); + if( ri != null ) + { + retval = ((COSName)ri).getName(); + } + return retval; + } + + /** + * This will set the rendering intent for the graphics state. + * + * @param ri The new rendering intent + */ + public void setRenderingIntent( String ri ) + { + COSName intent = null; + if( ri != null ) + { + intent = COSName.getPDFName( ri ); + } + graphicsState.setItem( RI, intent ); + } + + /** + * This will get the overprint control. + * + * @return The overprint control or null if one has not been set. + */ + public Boolean getStrokingOverprintControl() + { + return getBooleanItem( OP ); + } + + /** + * This will get the overprint control(OP). + * + * @param op The overprint control. + */ + public void setStrokingOverprintControl( Boolean op ) + { + setBooleanItem( OP, op ); + } + + /** + * This will get the overprint control for non stroking operations. If this + * value is null then the regular overprint control value will be returned. + * + * @return The overprint control or null if one has not been set. + */ + public Boolean getNonStrokingOverprintControl() + { + Boolean retval = getBooleanItem( OP_NS ); + if( retval == null ) + { + retval = getStrokingOverprintControl(); + } + return retval; + } + + /** + * This will get the overprint control(OP). + * + * @param op The overprint control. + */ + public void setNonStrokingOverprintControl( Boolean op ) + { + setBooleanItem( OP_NS, op ); + } + + /** + * This will get the overprint control mode. + * + * @return The overprint control mode or null if one has not been set. + */ + public Float getOverprintMode() + { + return getFloatItem( OPM ); + } + + /** + * This will get the overprint mode(OPM). + * + * @param overprintMode The overprint mode + */ + public void setOverprintMode( Float overprintMode ) + { + setFloatItem( OPM, overprintMode ); + } + + /** + * This will get the font setting of the graphics state. + * + * @return The font setting. + */ + public PDFontSetting getFontSetting() + { + PDFontSetting setting = null; + COSArray font = (COSArray)graphicsState.getDictionaryObject( FONT ); + if( font != null ) + { + setting = new PDFontSetting( font ); + } + return setting; + } + + /** + * This will set the font setting for this graphics state. + * + * @param fs The new font setting. + */ + public void setFontSetting( PDFontSetting fs ) + { + graphicsState.setItem( FONT, fs ); + } + + /** + * This will get the flatness tolerance. + * + * @return The flatness tolerance or null if one has not been set. + */ + public Float getFlatnessTolerance() + { + return getFloatItem( FL ); + } + + /** + * This will get the flatness tolerance. + * + * @param flatness The new flatness tolerance + */ + public void setFlatnessTolerance( Float flatness ) + { + setFloatItem( FL, flatness ); + } + + /** + * This will get the smothness tolerance. + * + * @return The smothness tolerance or null if one has not been set. + */ + public Float getSmoothnessTolerance() + { + return getFloatItem( SM ); + } + + /** + * This will get the smoothness tolerance. + * + * @param smoothness The new smoothness tolerance + */ + public void setSmoothnessTolerance( Float smoothness ) + { + setFloatItem( SM, smoothness ); + } + + /** + * This will get the automatic stroke adjustment flag. + * + * @return The automatic stroke adjustment flag or null if one has not been set. + */ + public Boolean getAutomaticStrokeAdjustment() + { + return getBooleanItem( SA ); + } + + /** + * This will get the automatic stroke adjustment flag. + * + * @param sa The new automatic stroke adjustment flag. + */ + public void setAutomaticStrokeAdjustment( Boolean sa ) + { + setBooleanItem( SA, sa ); + } + + /** + * This will get the stroking alpha constant. + * + * @return The stroking alpha constant or null if one has not been set. + */ + public Float getStrokingAlpaConstant() + { + return getFloatItem( CA ); + } + + /** + * This will get the stroking alpha constant. + * + * @param alpha The new stroking alpha constant. + */ + public void setStrokingAlphaConstant( Float alpha ) + { + setFloatItem( CA, alpha ); + } + + /** + * This will get the non stroking alpha constant. + * + * @return The non stroking alpha constant or null if one has not been set. + */ + public Float getNonStrokingAlpaConstant() + { + return getFloatItem( CA_NS ); + } + + /** + * This will get the non stroking alpha constant. + * + * @param alpha The new non stroking alpha constant. + */ + public void setNonStrokingAlphaConstant( Float alpha ) + { + setFloatItem( CA_NS, alpha ); + } + + /** + * This will get the alpha source flag. + * + * @return The alpha source flag. + */ + public Boolean getAlpaSourceFlag() + { + return getBooleanItem( AIS ); + } + + /** + * This will get the alpha source flag. + * + * @param alpha The alpha source flag. + */ + public void setAlphaSourceFlag( Boolean alpha ) + { + setBooleanItem( AIS, alpha ); + } + + /** + * This will get the text knockout flag. + * + * @return The text knockout flag. + */ + public Boolean getTextKnockoutFlag() + { + return getBooleanItem( TK ); + } + + /** + * This will get the text knockout flag. + * + * @param tk The text knockout flag. + */ + public void setTextKnockoutFlag( Boolean tk ) + { + setBooleanItem( TK, tk ); + } + + /** + * This will get a float item from the dictionary. + * + * @param key The key to the item. + * + * @return The value for that item. + */ + private Float getFloatItem( COSName key ) + { + Float retval = null; + COSNumber value = (COSNumber)graphicsState.getDictionaryObject( key ); + if( value != null ) + { + retval = new Float( value.floatValue() ); + } + return retval; + } + + /** + * This will set a float object. + * + * @param key The key to the data that we are setting. + * @param value The value that we are setting. + */ + private void setFloatItem( COSName key, Float value ) + { + if( value == null ) + { + graphicsState.removeItem( key ); + } + else + { + graphicsState.setItem( key, new COSFloat( value.floatValue() ) ); + } + } + + /** + * This will get a integer item from the dictionary. + * + * @param key The key to the item. + * + * @return The value for that item. + */ + private Integer getIntegerItem( COSName key ) + { + Integer retval = null; + COSNumber value = (COSNumber)graphicsState.getDictionaryObject( key ); + if( value != null ) + { + retval = new Integer( value.intValue() ); + } + return retval; + } + + /** + * This will set a integer object. + * + * @param key The key to the data that we are setting. + * @param value The value that we are setting. + */ + private void setIntegerItem( COSName key, Integer value ) + { + if( value == null ) + { + graphicsState.removeItem( key ); + } + else + { + graphicsState.setItem( key, new COSInteger( value.intValue() ) ); + } + } + + /** + * This will get an int item from the dictionary. + * + * @param key The key to the item. + * + * @return The value for that item. + */ + private Long getLongItem( COSName key ) + { + Long retval = null; + COSNumber value = (COSNumber)graphicsState.getDictionaryObject( key ); + if( value != null ) + { + retval = new Long( value.intValue() ); + } + return retval; + } + + /** + * This will set an integer object. + * + * @param key The key to the data that we are setting. + * @param value The value that we are setting. + */ + private void setLongItem( COSName key, Long value ) + { + if( value == null ) + { + graphicsState.removeItem( key ); + } + else + { + graphicsState.setItem( key, new COSInteger( value.longValue() ) ); + } + } + + /** + * This will get a boolean item from the dictionary. + * + * @param key The key to the item. + * + * @return The value for that item. + */ + private Boolean getBooleanItem( COSName key ) + { + Boolean retval = null; + COSBoolean value = (COSBoolean)graphicsState.getDictionaryObject( key ); + if( value != null ) + { + retval = value.getValueAsObject(); + } + return retval; + } + + /** + * This will set an boolean object. + * + * @param key The key to the data that we are setting. + * @param value The value that we are setting. + */ + private void setBooleanItem( COSName key, Boolean value ) + { + if( value == null ) + { + graphicsState.removeItem( key ); + } + else + { + graphicsState.setItem( key, COSBoolean.getBoolean( value ) ); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/PDFontSetting.java b/src/main/java/org/pdfbox/pdmodel/graphics/PDFontSetting.java new file mode 100644 index 0000000..039609f --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/PDFontSetting.java @@ -0,0 +1,133 @@ +/** + * Copyright (c) 2003, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.pdmodel.graphics; + +import org.pdfbox.cos.COSArray; +import org.pdfbox.cos.COSBase; +import org.pdfbox.cos.COSDictionary; +import org.pdfbox.cos.COSFloat; +import org.pdfbox.cos.COSNumber; + +import org.pdfbox.pdmodel.common.COSObjectable; + +import org.pdfbox.pdmodel.font.PDFont; +import org.pdfbox.pdmodel.font.PDFontFactory; + +import java.io.IOException; + +/** + * This class represents a font setting used for the graphics state. A font setting is a font and a + * font size. Maybe there is a better name for this? + * + * @author Ben Litchfield (ben@csh.rit.edu) + * @version $Revision: 1.3 $ + */ +public class PDFontSetting implements COSObjectable +{ + private COSArray fontSetting = null; + + /** + * Creates a blank font setting, font will be null, size will be 1. + */ + public PDFontSetting() + { + fontSetting = new COSArray(); + fontSetting.add( null ); + fontSetting.add( new COSFloat( 1 ) ); + } + + /** + * Constructs a font setting from an existing array. + * + * @param fs The new font setting value. + */ + public PDFontSetting( COSArray fs ) + { + fontSetting = fs; + } + + /** + * @see COSObjectable#getCOSObject() + */ + public COSBase getCOSObject() + { + return fontSetting; + } + + /** + * This will get the font for this font setting. + * + * @return The font for this setting of null if one was not found. + * + * @throws IOException If there is an error getting the font. + */ + public PDFont getFont() throws IOException + { + PDFont retval = null; + COSBase font = fontSetting.get( 0 ); + if( font instanceof COSDictionary ) + { + retval = PDFontFactory.createFont( (COSDictionary)font ); + } + return retval; + } + + /** + * This will set the font for this font setting. + * + * @param font The new font. + */ + public void setFont( PDFont font ) + { + fontSetting.set( 0, font ); + } + + /** + * This will get the size of the font. + * + * @return The size of the font. + */ + public float getFontSize() + { + COSNumber size = (COSNumber)fontSetting.get( 1 ); + return size.floatValue(); + } + + /** + * This will set the size of the font. + * + * @param size The new size of the font. + */ + public void setFontSize( float size ) + { + fontSetting.set( 1, new COSFloat( size ) ); + } +} \ No newline at end of file diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/PDGraphicsState.java b/src/main/java/org/pdfbox/pdmodel/graphics/PDGraphicsState.java new file mode 100644 index 0000000..4115198 --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/PDGraphicsState.java @@ -0,0 +1,438 @@ +/** + * Copyright (c) 2003, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.pdmodel.graphics; + +import org.pdfbox.util.Matrix; + +import org.pdfbox.pdmodel.text.PDTextState; + +import org.pdfbox.pdmodel.graphics.color.PDColorSpaceInstance; + +/** + * This class will hold the current state of the graphics parameters when executing a + * content stream. + * + * @author Ben Litchfield (ben@csh.rit.edu) + * @version $Revision: 1.3 $ + */ +public class PDGraphicsState implements Cloneable +{ + private Matrix currentTransformationMatrix = new Matrix(); + + //Here are some attributes of the Graphics state, but have not been created yet. + // + //clippingPath + private PDColorSpaceInstance strokingColorSpace = new PDColorSpaceInstance(); + private PDColorSpaceInstance nonStrokingColorSpace = new PDColorSpaceInstance(); + private PDTextState textState = new PDTextState(); + private double lineWidth = 0; + private int lineCap = 0; + private int lineJoin = 0; + private double miterLimit = 0; + private PDLineDashPattern lineDashPattern; + private String renderingIntent; + private boolean strokeAdjustment = false; + //blend mode + //soft mask + private double alphaConstants = 0; + private boolean alphaSource = false; + + //DEVICE DEPENDENT parameters + private boolean overprint = false; + private double overprintMode = 0; + //black generation + //undercolor removal + //transfer + //halftone + private double flatness = 1.0; + private double smoothness = 0; + + /** + * Get the value of the CTM. + * + * @return The current transformation matrix. + */ + public Matrix getCurrentTransformationMatrix() + { + return currentTransformationMatrix; + } + + /** + * Set the value of the CTM. + * + * @param value The current transformation matrix. + */ + public void setCurrentTransformationMatrix(Matrix value) + { + currentTransformationMatrix = value; + } + + /** + * Get the value of the line width. + * + * @return The current line width. + */ + public double getLineWidth() + { + return lineWidth; + } + + /** + * set the value of the line width. + * + * @param value The current line width. + */ + public void setLineWidth(double value) + { + lineWidth = value; + } + + /** + * Get the value of the line cap. + * + * @return The current line cap. + */ + public int getLineCap() + { + return lineCap; + } + + /** + * set the value of the line cap. + * + * @param value The current line cap. + */ + public void setLineCap(int value) + { + lineCap = value; + } + + /** + * Get the value of the line join. + * + * @return The current line join value. + */ + public int getLineJoin() + { + return lineJoin; + } + + /** + * Get the value of the line join. + * + * @param value The current line join + */ + public void setLineJoin(int value) + { + lineJoin = value; + } + + /** + * Get the value of the miter limit. + * + * @return The current miter limit. + */ + public double getMiterLimit() + { + return miterLimit; + } + + /** + * set the value of the miter limit. + * + * @param value The current miter limit. + */ + public void setMiterLimit(double value) + { + miterLimit = value; + } + + /** + * Get the value of the stroke adjustment parameter. + * + * @return The current stroke adjustment. + */ + public boolean isStrokeAdjustment() + { + return strokeAdjustment; + } + + /** + * set the value of the stroke adjustment. + * + * @param value The value of the stroke adjustment parameter. + */ + public void setStrokeAdjustment(boolean value) + { + strokeAdjustment = value; + } + + /** + * Get the value of the alpha constants property. + * + * @return The value of the alpha constants parameter. + */ + public double getAlphaConstants() + { + return alphaConstants; + } + + /** + * set the value of the alpha constants property. + * + * @param value The value of the alpha constants parameter. + */ + public void setAlphaConstants(double value) + { + alphaConstants = value; + } + + /** + * get the value of the alpha source property. + * + * @return The value of the alpha source parameter. + */ + public boolean isAlphaSource() + { + return alphaSource; + } + + /** + * set the value of the alpha source property. + * + * @param value The value of the alpha source parameter. + */ + public void setAlphaSource(boolean value) + { + alphaSource = value; + } + + /** + * get the value of the overprint property. + * + * @return The value of the overprint parameter. + */ + public boolean isOverprint() + { + return overprint; + } + + /** + * set the value of the overprint property. + * + * @param value The value of the overprint parameter. + */ + public void setOverprint(boolean value) + { + overprint = value; + } + + /** + * get the value of the overprint mode property. + * + * @return The value of the overprint mode parameter. + */ + public double getOverprintMode() + { + return overprintMode; + } + + /** + * set the value of the overprint mode property. + * + * @param value The value of the overprint mode parameter. + */ + public void setOverprintMode(double value) + { + overprintMode = value; + } + + /** + * get the value of the flatness property. + * + * @return The value of the flatness parameter. + */ + public double getFlatness() + { + return flatness; + } + + /** + * set the value of the flatness property. + * + * @param value The value of the flatness parameter. + */ + public void setFlatness(double value) + { + flatness = value; + } + + /** + * get the value of the smoothness property. + * + * @return The value of the smoothness parameter. + */ + public double getSmoothness() + { + return smoothness; + } + + /** + * set the value of the smoothness property. + * + * @param value The value of the smoothness parameter. + */ + public void setSmoothness(double value) + { + smoothness = value; + } + + /** + * This will get the graphics text state. + * + * @return The graphics text state. + */ + public PDTextState getTextState() + { + return textState; + } + + /** + * This will set the graphics text state. + * + * @param value The graphics text state. + */ + public void setTextState(PDTextState value) + { + textState = value; + } + + /** + * This will get the current line dash pattern. + * + * @return The line dash pattern. + */ + public PDLineDashPattern getLineDashPattern() + { + return lineDashPattern; + } + + /** + * This will set the current line dash pattern. + * + * @param value The new line dash pattern. + */ + public void setLineDashPattern(PDLineDashPattern value) + { + lineDashPattern = value; + } + + /** + * This will get the rendering intent. + * + * @see PDExtendedGraphicsState + * + * @return The rendering intent + */ + public String getRenderingIntent() + { + return renderingIntent; + } + + /** + * This will set the rendering intent. + * + * @param value The new rendering intent. + */ + public void setRenderingIntent(String value) + { + renderingIntent = value; + } + + /** + * @see Object#clone() + */ + public Object clone() + { + PDGraphicsState clone = null; + try + { + clone = (PDGraphicsState)super.clone(); + clone.setTextState( (PDTextState)textState.clone() ); + clone.setCurrentTransformationMatrix( currentTransformationMatrix.copy() ); + } + catch( CloneNotSupportedException e ) + { + e.printStackTrace(); + } + return clone; + } + + /** + * This will get the current stroking colorspace. + * + * @return The current stroking colorspace. + */ + public PDColorSpaceInstance getStrokingColorSpace() + { + return strokingColorSpace; + } + + /** + * This will set the current stroking colorspace. + * + * @param value The new stroking colorspace instance. + */ + public void setStrokingColorSpace(PDColorSpaceInstance value) + { + strokingColorSpace = value; + } + + /** + * This will get the nonstroking color space instance. + * + * @return The colorspace instance. + */ + public PDColorSpaceInstance getNonStrokingColorSpace() + { + return nonStrokingColorSpace; + } + + /** + * This will set the non-stroking colorspace instance. + * + * @param value The non-stroking colorspace instance. + */ + public void setNonStrokingColorSpace(PDColorSpaceInstance value) + { + nonStrokingColorSpace = value; + } +} \ No newline at end of file diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/PDLineDashPattern.java b/src/main/java/org/pdfbox/pdmodel/graphics/PDLineDashPattern.java new file mode 100644 index 0000000..a67d5e4 --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/PDLineDashPattern.java @@ -0,0 +1,135 @@ +/** + * Copyright (c) 2003-2005, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.pdmodel.graphics; + +import org.pdfbox.cos.COSArray; +import org.pdfbox.cos.COSBase; +import org.pdfbox.cos.COSInteger; +import org.pdfbox.cos.COSNumber; + +import org.pdfbox.pdmodel.common.COSArrayList; +import org.pdfbox.pdmodel.common.COSObjectable; + +import java.util.List; + +/** + * This class represents the line dash pattern for a graphics state. See PDF + * Reference 1.5 section 4.3.2 + * + * @author Ben Litchfield (ben@benlitchfield.com) + * @version $Revision: 1.4 $ + */ +public class PDLineDashPattern implements COSObjectable +{ + private COSArray lineDashPattern = null; + + /** + * Creates a blank line dash pattern. With no dashes and a phase of 0. + */ + public PDLineDashPattern() + { + lineDashPattern = new COSArray(); + lineDashPattern.add( new COSArray() ); + lineDashPattern.add( new COSInteger( 0 ) ); + } + + /** + * Constructs a line dash pattern from an existing array. + * + * @param ldp The existing line dash pattern. + */ + public PDLineDashPattern( COSArray ldp ) + { + lineDashPattern = ldp; + } + + /** + * @see COSObjectable#getCOSObject() + */ + public COSBase getCOSObject() + { + return lineDashPattern; + } + + /** + * This will get the line dash pattern phase. The dash phase specifies the + * distance into the dash pattern at which to start the dash. + * + * @return The line dash pattern phase. + */ + public int getPhaseStart() + { + COSNumber phase = (COSNumber)lineDashPattern.get( 1 ); + return phase.intValue(); + } + + /** + * This will set the line dash pattern phase. + * + * @param phase The new line dash patter phase. + */ + public void setPhaseStart( int phase ) + { + lineDashPattern.set( 1, new COSInteger( phase ) ); + } + + /** + * This will return a list of java.lang.Integer objects that represent the line + * dash pattern appearance. + * + * @return The line dash pattern. + */ + public List getDashPattern() + { + COSArray dashPatterns = (COSArray)lineDashPattern.get( 0 ); + return COSArrayList.convertIntegerCOSArrayToList( dashPatterns ); + } + + /** + * Get the line dash pattern as a COS object. + * + * @return The cos array line dash pattern. + */ + public COSArray getCOSDashPattern() + { + return (COSArray)lineDashPattern.get( 0 ); + } + + /** + * This will replace the existing line dash pattern. + * + * @param dashPattern A list of java.lang.Integer objects. + */ + public void setDashPattern( List dashPattern ) + { + lineDashPattern.set( 0, COSArrayList.converterToCOSArray( dashPattern ) ); + } +} \ No newline at end of file diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/color/PDCalGray.java b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDCalGray.java new file mode 100644 index 0000000..fc6f84e --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDCalGray.java @@ -0,0 +1,240 @@ +/** + * Copyright (c) 2004, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.pdmodel.graphics.color; + +import org.pdfbox.cos.COSArray; +import org.pdfbox.cos.COSBase; +import org.pdfbox.cos.COSDictionary; +import org.pdfbox.cos.COSFloat; +import org.pdfbox.cos.COSName; +import org.pdfbox.cos.COSNumber; + +import java.awt.color.ColorSpace; +import java.awt.image.ColorModel; + +import java.io.IOException; + +/** + * This class represents a Cal Gray color space. + * + * @author Ben Litchfield (ben@csh.rit.edu) + * @version $Revision: 1.4 $ + */ +public class PDCalGray extends PDColorSpace +{ + /** + * The name of this color space. + */ + public static final String NAME = "CalGray"; + + private COSArray array; + private COSDictionary dictionary; + + /** + * Constructor. + */ + public PDCalGray() + { + array = new COSArray(); + dictionary = new COSDictionary(); + array.add( COSName.getPDFName( NAME ) ); + array.add( dictionary ); + } + + /** + * Constructor with array. + * + * @param gray The underlying color space. + */ + public PDCalGray( COSArray gray ) + { + array = gray; + dictionary = (COSDictionary)array.getObject( 1 ); + } + + /** + * This will get the number of components that this color space is made up of. + * + * @return The number of components in this color space. + * + * @throws IOException If there is an error getting the number of color components. + */ + public int getNumberOfComponents() throws IOException + { + return 1; + } + + /** + * This will return the name of the color space. + * + * @return The name of the color space. + */ + public String getName() + { + return NAME; + } + + /** + * Create a Java colorspace for this colorspace. + * + * @return A color space that can be used for Java AWT operations. + * + * @throws IOException If there is an error creating the color space. + */ + public ColorSpace createColorSpace() throws IOException + { + throw new IOException( "Not implemented" ); + } + + /** + * Create a Java color model for this colorspace. + * + * @param bpc The number of bits per component. + * + * @return A color model that can be used for Java AWT operations. + * + * @throws IOException If there is an error creating the color model. + */ + public ColorModel createColorModel( int bpc ) throws IOException + { + throw new IOException( "Not implemented" ); + } + + /** + * Convert this standard java object to a COS object. + * + * @return The cos object that matches this Java object. + */ + public COSBase getCOSObject() + { + return array; + } + + /** + * This will get the gamma value. If none is present then the default of 1 + * will be returned. + * + * @return The gamma value. + */ + public float getGamma() + { + float retval = 1.0f; + COSNumber gamma = (COSNumber)dictionary.getDictionaryObject( COSName.getPDFName( "Gamma" ) ); + if( gamma != null ) + { + retval = gamma.floatValue(); + } + return retval; + } + + /** + * Set the gamma value. + * + * @param value The new gamma value. + */ + public void setGamma( float value ) + { + dictionary.setItem( COSName.getPDFName( "Gamma" ), new COSFloat( value ) ); + } + + /** + * This will return the whitepoint tristimulus. As this is a required field + * this will never return null. A default of 1,1,1 will be returned if the + * pdf does not have any values yet. + * + * @return The whitepoint tristimulus. + */ + public PDTristimulus getWhitepoint() + { + PDTristimulus retval = null; + COSArray wp = (COSArray)dictionary.getDictionaryObject( COSName.getPDFName( "WhitePoint" ) ); + if( wp == null ) + { + wp.add( new COSFloat( 1.0f ) ); + wp.add( new COSFloat( 1.0f ) ); + wp.add( new COSFloat( 1.0f ) ); + dictionary.setItem( COSName.getPDFName( "WhitePoint" ), wp ); + } + return new PDTristimulus( wp ); + } + + /** + * This will set the whitepoint tristimulus. As this is a required field + * this null should not be passed into this function. + * + * @param wp The whitepoint tristimulus. + */ + public void setWhitepoint( PDTristimulus wp ) + { + COSBase wpArray = wp.getCOSObject(); + if( wpArray != null ) + { + dictionary.setItem( COSName.getPDFName( "WhitePoint" ), wpArray ); + } + } + + /** + * This will return the BlackPoint tristimulus. This is an optional field but + * has defaults so this will never return null. + * A default of 0,0,0 will be returned if the pdf does not have any values yet. + * + * @return The blackpoint tristimulus. + */ + public PDTristimulus getBlackPoint() + { + PDTristimulus retval = null; + COSArray bp = (COSArray)dictionary.getDictionaryObject( COSName.getPDFName( "BlackPoint" ) ); + if( bp == null ) + { + bp.add( new COSFloat( 0.0f ) ); + bp.add( new COSFloat( 0.0f ) ); + bp.add( new COSFloat( 0.0f ) ); + dictionary.setItem( COSName.getPDFName( "BlackPoint" ), bp ); + } + return new PDTristimulus( bp ); + } + + /** + * This will set the BlackPoint tristimulus. As this is a required field + * this null should not be passed into this function. + * + * @param bp The BlackPoint tristimulus. + */ + public void setBlackPoint( PDTristimulus bp ) + { + COSBase bpArray = null; + if( bp != null ) + { + bpArray = bp.getCOSObject(); + } + dictionary.setItem( COSName.getPDFName( "BlackPoint" ), bpArray ); + } +} \ No newline at end of file diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/color/PDCalRGB.java b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDCalRGB.java new file mode 100644 index 0000000..6aa4eb1 --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDCalRGB.java @@ -0,0 +1,289 @@ +/** + * Copyright (c) 2004, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.pdmodel.graphics.color; + +import org.pdfbox.cos.COSArray; +import org.pdfbox.cos.COSBase; +import org.pdfbox.cos.COSDictionary; +import org.pdfbox.cos.COSFloat; +import org.pdfbox.cos.COSName; + +import org.pdfbox.pdmodel.common.PDMatrix; + +import java.awt.color.ColorSpace; +import java.awt.image.ColorModel; + +import java.io.IOException; + +/** + * This class represents a Cal RGB color space. + * + * @author Ben Litchfield (ben@csh.rit.edu) + * @version $Revision: 1.2 $ + */ +public class PDCalRGB extends PDColorSpace +{ + /** + * The name of this color space. + */ + public static final String NAME = "CalRGB"; + + private COSArray array; + private COSDictionary dictionary; + + /** + * Constructor. + */ + public PDCalRGB() + { + array = new COSArray(); + dictionary = new COSDictionary(); + array.add( COSName.getPDFName( NAME ) ); + array.add( dictionary ); + } + + /** + * Constructor with array. + * + * @param rgb The underlying color space. + */ + public PDCalRGB( COSArray rgb ) + { + array = rgb; + dictionary = (COSDictionary)array.getObject( 1 ); + } + + /** + * This will get the number of components that this color space is made up of. + * + * @return The number of components in this color space. + * + * @throws IOException If there is an error getting the number of color components. + */ + public int getNumberOfComponents() throws IOException + { + return 3; + } + + /** + * This will return the name of the color space. + * + * @return The name of the color space. + */ + public String getName() + { + return NAME; + } + + /** + * Create a Java colorspace for this colorspace. + * + * @return A color space that can be used for Java AWT operations. + * + * @throws IOException If there is an error creating the color space. + */ + public ColorSpace createColorSpace() throws IOException + { + throw new IOException( "Not implemented" ); + } + + /** + * Create a Java color model for this colorspace. + * + * @param bpc The number of bits per component. + * + * @return A color model that can be used for Java AWT operations. + * + * @throws IOException If there is an error creating the color model. + */ + public ColorModel createColorModel( int bpc ) throws IOException + { + throw new IOException( "Not implemented" ); + } + + /** + * Convert this standard java object to a COS object. + * + * @return The cos object that matches this Java object. + */ + public COSBase getCOSObject() + { + return array; + } + + /** + * This will return the whitepoint tristimulus. As this is a required field + * this will never return null. A default of 1,1,1 will be returned if the + * pdf does not have any values yet. + * + * @return The whitepoint tristimulus. + */ + public PDTristimulus getWhitepoint() + { + PDTristimulus retval = null; + COSArray wp = (COSArray)dictionary.getDictionaryObject( COSName.getPDFName( "WhitePoint" ) ); + if( wp == null ) + { + wp.add( new COSFloat( 1.0f ) ); + wp.add( new COSFloat( 1.0f ) ); + wp.add( new COSFloat( 1.0f ) ); + dictionary.setItem( COSName.getPDFName( "WhitePoint" ), wp ); + } + return new PDTristimulus( wp ); + } + + /** + * This will set the whitepoint tristimulus. As this is a required field + * this null should not be passed into this function. + * + * @param wp The whitepoint tristimulus. + */ + public void setWhitepoint( PDTristimulus wp ) + { + COSBase wpArray = wp.getCOSObject(); + if( wpArray != null ) + { + dictionary.setItem( COSName.getPDFName( "WhitePoint" ), wpArray ); + } + } + + /** + * This will return the BlackPoint tristimulus. This is an optional field but + * has defaults so this will never return null. + * A default of 0,0,0 will be returned if the pdf does not have any values yet. + * + * @return The blackpoint tristimulus. + */ + public PDTristimulus getBlackPoint() + { + PDTristimulus retval = null; + COSArray bp = (COSArray)dictionary.getDictionaryObject( COSName.getPDFName( "BlackPoint" ) ); + if( bp == null ) + { + bp.add( new COSFloat( 0.0f ) ); + bp.add( new COSFloat( 0.0f ) ); + bp.add( new COSFloat( 0.0f ) ); + dictionary.setItem( COSName.getPDFName( "BlackPoint" ), bp ); + } + return new PDTristimulus( bp ); + } + + /** + * This will set the BlackPoint tristimulus. As this is a required field + * this null should not be passed into this function. + * + * @param bp The BlackPoint tristimulus. + */ + public void setBlackPoint( PDTristimulus bp ) + { + + COSBase bpArray = null; + if( bp != null ) + { + bpArray = bp.getCOSObject(); + } + dictionary.setItem( COSName.getPDFName( "BlackPoint" ), bpArray ); + } + + /** + * This will get the gamma value. If none is present then the default of 1,1,1 + * will be returned. + * + * @return The gamma value. + */ + public PDGamma getGamma() + { + COSArray gamma = (COSArray)dictionary.getDictionaryObject( COSName.getPDFName( "Gamma" ) ); + if( gamma == null ) + { + gamma = new COSArray(); + gamma.add( new COSFloat( 1.0f ) ); + gamma.add( new COSFloat( 1.0f ) ); + gamma.add( new COSFloat( 1.0f ) ); + dictionary.setItem( COSName.getPDFName( "Gamma" ), gamma ); + } + return new PDGamma( gamma ); + } + + /** + * Set the gamma value. + * + * @param value The new gamma value. + */ + public void setGamma( PDGamma value ) + { + COSArray gamma = null; + if( value != null ) + { + gamma = (COSArray)value.getCOSArray(); + } + dictionary.setItem( COSName.getPDFName( "Gamma" ), gamma ); + } + + /** + * This will get the linear interpretation array. This is guaranteed to not + * return null. If the underlying dictionary contains null then the identity + * matrix will be returned. + * + * @return The linear interpretation matrix. + */ + public PDMatrix getLinearInterpretation() + { + PDMatrix retval = null; + COSArray matrix = (COSArray)dictionary.getDictionaryObject( COSName.getPDFName( "Matrix" ) ); + if( matrix == null ) + { + retval = new PDMatrix(); + setLinearInterpretation( retval ); + } + else + { + retval = new PDMatrix( matrix ); + } + return retval; + } + + /** + * This will set the linear interpretation matrix. Passing in null will + * clear the matrix. + * + * @param matrix The new linear interpretation matrix. + */ + public void setLinearInterpretation( PDMatrix matrix ) + { + COSArray matrixArray = null; + if( matrix != null ) + { + matrixArray = matrix.getCOSArray(); + } + dictionary.setItem( COSName.getPDFName( "Matrix" ), matrixArray ); + } +} \ No newline at end of file diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/color/PDColorSpace.java b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDColorSpace.java new file mode 100644 index 0000000..33ac0a1 --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDColorSpace.java @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2004, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.pdmodel.graphics.color; + +import org.pdfbox.cos.COSBase; +import org.pdfbox.cos.COSName; + +import org.pdfbox.pdmodel.common.COSObjectable; + +import java.io.IOException; + +import java.awt.color.ColorSpace; +import java.awt.image.ColorModel; + + +/** + * This class represents a color space in a pdf document. + * + * @author Ben Litchfield (ben@csh.rit.edu) + * @version $Revision: 1.4 $ + */ +public abstract class PDColorSpace implements COSObjectable +{ + /** + * This will return the name of the color space. + * + * @return The name of the color space. + */ + public abstract String getName(); + + /** + * This will get the number of components that this color space is made up of. + * + * @return The number of components in this color space. + * + * @throws IOException If there is an error getting the number of color components. + */ + public abstract int getNumberOfComponents() throws IOException; + + /** + * Convert this standard java object to a COS object. + * + * @return The cos object that matches this Java object. + */ + public COSBase getCOSObject() + { + return COSName.getPDFName( getName() ); + } + + /** + * Create a Java colorspace for this colorspace. + * + * @return A color space that can be used for Java AWT operations. + * + * @throws IOException If there is an error creating the color space. + */ + public abstract ColorSpace createColorSpace() throws IOException; + + /** + * Create a Java color model for this colorspace. + * + * @param bpc The number of bits per component. + * + * @return A color model that can be used for Java AWT operations. + * + * @throws IOException If there is an error creating the color model. + */ + public abstract ColorModel createColorModel( int bpc ) throws IOException; +} \ No newline at end of file diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/color/PDColorSpaceFactory.java b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDColorSpaceFactory.java new file mode 100644 index 0000000..8c9aad5 --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDColorSpaceFactory.java @@ -0,0 +1,218 @@ +/** + * Copyright (c) 2004, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.pdmodel.graphics.color; + +import java.awt.color.ColorSpace; +import java.awt.color.ICC_ColorSpace; +import java.io.IOException; +import java.io.OutputStream; + +import org.pdfbox.cos.COSArray; +import org.pdfbox.cos.COSBase; +import org.pdfbox.cos.COSFloat; +import org.pdfbox.cos.COSName; +import org.pdfbox.pdmodel.PDDocument; +import org.pdfbox.pdmodel.common.PDStream; + +/** + * This class represents a color space in a pdf document. + * + * @author Ben Litchfield (ben@csh.rit.edu) + * @version $Revision: 1.10 $ + */ +public final class PDColorSpaceFactory +{ + /** + * Private constructor for utility classes. + */ + private PDColorSpaceFactory() + { + //utility class should not be implemented + } + + /** + * This will create the correct color space given the name. + * + * @param colorSpace The color space object. + * + * @return The color space. + * + * @throws IOException If the color space name is unknown. + */ + public static PDColorSpace createColorSpace( COSBase colorSpace ) throws IOException + { + PDColorSpace retval = null; + if( colorSpace instanceof COSName ) + { + retval = createColorSpace( ((COSName)colorSpace).getName() ); + } + else if( colorSpace instanceof COSArray ) + { + COSArray array = (COSArray)colorSpace; + COSName type = (COSName)array.getObject( 0 ); + if( type.getName().equals( PDCalGray.NAME ) ) + { + retval = new PDCalGray( array ); + } + else if( type.getName().equals( PDCalRGB.NAME ) ) + { + retval = new PDCalRGB( array ); + } + else if( type.getName().equals( PDDeviceN.NAME ) ) + { + retval = new PDDeviceN( array ); + } + else if( type.getName().equals( PDIndexed.NAME ) || + type.getName().equals( PDIndexed.ABBREVIATED_NAME )) + { + retval = new PDIndexed( array ); + } + else if( type.getName().equals( PDLab.NAME ) ) + { + retval = new PDLab( array ); + } + else if( type.getName().equals( PDSeparation.NAME ) ) + { + retval = new PDSeparation( array ); + } + else if( type.getName().equals( PDICCBased.NAME ) ) + { + retval = new PDICCBased( array ); + } + else if( type.getName().equals( PDPattern.NAME ) ) + { + retval = new PDPattern( array ); + } + else + { + throw new IOException( "Unknown colorspace array type:" + type ); + } + } + else + { + throw new IOException( "Unknown colorspace type:" + colorSpace ); + } + return retval; + } + + /** + * This will create the correct color space given the name. + * + * @param colorSpaceName The name of the colorspace. + * + * @return The color space. + * + * @throws IOException If the color space name is unknown. + */ + public static PDColorSpace createColorSpace( String colorSpaceName ) throws IOException + { + PDColorSpace cs = null; + if( colorSpaceName.equals( PDDeviceCMYK.NAME ) || + colorSpaceName.equals( PDDeviceCMYK.ABBREVIATED_NAME ) ) + { + cs = PDDeviceCMYK.INSTANCE; + } + else if( colorSpaceName.equals( PDDeviceRGB.NAME ) || + colorSpaceName.equals( PDDeviceRGB.ABBREVIATED_NAME ) ) + { + cs = PDDeviceRGB.INSTANCE; + } + else if( colorSpaceName.equals( PDDeviceGray.NAME ) || + colorSpaceName.equals( PDDeviceGray.ABBREVIATED_NAME )) + { + cs = new PDDeviceGray(); + } + else if( colorSpaceName.equals( PDLab.NAME ) ) + { + cs = new PDLab(); + } + else if( colorSpaceName.equals( PDPattern.NAME ) ) + { + cs = new PDPattern(); + } + else + { + throw new IOException( "Error: Unknown colorspace '" + colorSpaceName + "'" ); + } + return cs; + } + + /** + * This will create the correct color space from a java colorspace. + * + * @param doc The doc to potentiall write information to. + * @param cs The awt colorspace. + * + * @return The color space. + * + * @throws IOException If the color space name is unknown. + */ + public static PDColorSpace createColorSpace( PDDocument doc, ColorSpace cs ) throws IOException + { + PDColorSpace retval = null; + if( cs.isCS_sRGB() ) + { + retval = PDDeviceRGB.INSTANCE; + } + else if( cs instanceof ICC_ColorSpace ) + { + ICC_ColorSpace ics = (ICC_ColorSpace)cs; + PDICCBased pdCS = new PDICCBased( doc ); + retval = pdCS; + COSArray ranges = new COSArray(); + for( int i=0; i + + + + + +This package deals with colors that are stored in a PDF document. + + \ No newline at end of file diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/package.html b/src/main/java/org/pdfbox/pdmodel/graphics/package.html new file mode 100644 index 0000000..3c1f7ca --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/package.html @@ -0,0 +1,9 @@ + + + + + + +The PDModel graphics package deals with graphics states, operations, and parameters within the PDF document. + + diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/predictor/Average.java b/src/main/java/org/pdfbox/pdmodel/graphics/predictor/Average.java new file mode 100644 index 0000000..46e65dc --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/predictor/Average.java @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2005, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.pdmodel.graphics.predictor; + +/** + * We can use raw on the right hand side of + * the decoding formula because it is already decoded. + * + * average(i,j) = raw(i,j) + (raw(i-1,j)+raw(i,j-1)/2 + * + * decoding + * + * raw(i,j) = avarage(i,j) - (raw(i-1,j)+raw(i,j-1)/2 + * + * @author xylifyx@yahoo.co.uk + * @version $Revision: 1.2 $ + */ +public class Average extends PredictorAlgorithm +{ + /** + * Not an optimal version, but close to the def. + * + * @see org.pdfbox.pdmodel.graphics.predictor.PredictorAlgorithm#encodeLine(byte[], byte[], + * int, int, int, int) + */ + public void encodeLine(byte[] src, byte[] dest, int srcDy, int srcOffset, + int destDy, int destOffset) + { + int bpl = getWidth() * getBpp(); + for (int x = 0; x < bpl; x++) + { + dest[x + destOffset] = (byte) (src[x + srcOffset] - ((leftPixel( + src, srcOffset, srcDy, x) + abovePixel(src, srcOffset, + srcDy, x)) >>> 2)); + } + } + + /** + * @see org.pdfbox.pdmodel.graphics.predictor.PredictorAlgorithm#decodeLine(byte[], byte[], + * int, int, int, int) + */ + public void decodeLine(byte[] src, byte[] dest, int srcDy, int srcOffset, + int destDy, int destOffset) + { + int bpl = getWidth() * getBpp(); + for (int x = 0; x < bpl; x++) + { + dest[x + destOffset] = (byte) (src[x + srcOffset] + ((leftPixel( + dest, destOffset, destDy, x) + abovePixel(dest, + destOffset, destDy, x)) >>> 2)); + } + } +} diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/predictor/None.java b/src/main/java/org/pdfbox/pdmodel/graphics/predictor/None.java new file mode 100644 index 0000000..20ec815 --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/predictor/None.java @@ -0,0 +1,104 @@ +/** + * Copyright (c) 2005, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.pdmodel.graphics.predictor; + +/** + * The none algorithm. + * + * None(i,j) = Raw(i,j) + * + * Raw(i,j) = None(i,j) + * + * @author xylifyx@yahoo.co.uk + * @version $Revision: 1.2 $ + */ +public class None extends PredictorAlgorithm +{ + /** + * encode a byte array full of image data using the filter that this object + * implements. + * + * @param src + * buffer + * @param dest + * buffer + */ + public void encode(byte[] src, byte[] dest) + { + checkBufsiz(dest, src); + System.arraycopy(src,0,dest,0,src.length); + } + + /** + * decode a byte array full of image data using the filter that this object + * implements. + * + * @param src + * buffer + * @param dest + * buffer + */ + public void decode(byte[] src, byte[] dest) + { + System.arraycopy(src,0,dest,0,src.length); + } + + + + /** + * @see org.pdfbox.pdmodel.graphics.predictor.PredictorAlgorithm#encodeLine(byte[], byte[], + * int, int, int, int) + */ + public void encodeLine(byte[] src, byte[] dest, int srcDy, int srcOffset, + int destDy, int destOffset) + { + int bpl = getWidth() * getBpp(); + for (int x = 0; x < bpl; x++) + { + dest[destOffset + x] = src[srcOffset + x]; + } + } + + /** + * @see org.pdfbox.pdmodel.graphics.predictor.PredictorAlgorithm#decodeLine(byte[], byte[], + * int, int, int, int) + */ + public void decodeLine(byte[] src, byte[] dest, int srcDy, int srcOffset, + int destDy, int destOffset) + { + int bpl = getWidth() * getBpp(); + for (int x = 0; x < bpl; x++) + { + dest[destOffset + x] = src[srcOffset + x]; + } + } + +} diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/predictor/Paeth.java b/src/main/java/org/pdfbox/pdmodel/graphics/predictor/Paeth.java new file mode 100644 index 0000000..1fddef0 --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/predictor/Paeth.java @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2005, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + */ +package org.pdfbox.pdmodel.graphics.predictor; + +/** + * From http://www.w3.org/TR/PNG-Filters.html: The Paeth filter computes a + * simple linear function of the three neighboring pixels (left, above, upper + * left), then chooses as predictor the neighboring pixel closest to the + * computed value. This technique is due to Alan W. Paeth [PAETH]. + * + * To compute the Paeth filter, apply the following formula to each byte of the + * scanline: + * + * Paeth(i,j) = Raw(i,j) - PaethPredictor(Raw(i-1,j), Raw(i,j-1), Raw(i-1,j-1)) + * + * To decode the Paeth filter + * + * Raw(i,j) = Paeth(i,j) - PaethPredictor(Raw(i-1,j), Raw(i,j-1), Raw(i-1,j-1)) + * + * @author xylifyx@yahoo.co.uk + * @version $Revision: 1.2 $ + */ +public class Paeth extends PredictorAlgorithm +{ + /** + * The paeth predictor function. + * + * This function is taken almost directly from the PNG definition on + * http://www.w3.org/TR/PNG-Filters.html + * + * @param a + * left + * @param b + * above + * @param c + * upper left + * @return The result of the paeth predictor. + */ + public int paethPredictor(int a, int b, int c) + { + int p = a + b - c; // initial estimate + int pa = Math.abs(p - a); // distances to a, b, c + int pb = Math.abs(p - b); + int pc = Math.abs(p - c); + // return nearest of a,b,c, + // breaking ties in order a,b,c. + if (pa <= pb && pa <= pc) + { + return a; + } + else if (pb <= pc) + { + return b; + } + else + { + return c; + } + } + + /** + * @see org.pdfbox.pdmodel.graphics.predictor.PredictorAlgorithm#encodeLine(byte[], byte[], + * int, int, int, int) + */ + public void encodeLine(byte[] src, byte[] dest, int srcDy, int srcOffset, + int destDy, int destOffset) + { + int bpl = getWidth() * getBpp(); + for (int x = 0; x < bpl; x++) + { + dest[x + destOffset] = (byte) (src[x + srcOffset] - paethPredictor( + leftPixel(src, srcOffset, srcDy, x), abovePixel(src, + srcOffset, srcDy, x), aboveLeftPixel(src, + srcOffset, srcDy, x))); + } + } + + /** + * @see org.pdfbox.pdmodel.graphics.predictor.PredictorAlgorithm#decodeLine(byte[], byte[], + * int, int, int, int) + */ + public void decodeLine(byte[] src, byte[] dest, int srcDy, int srcOffset, + int destDy, int destOffset) + { + int bpl = getWidth() * getBpp(); + for (int x = 0; x < bpl; x++) + { + dest[x + destOffset] = (byte) (src[x + srcOffset] + paethPredictor( + leftPixel(dest, destOffset, destDy, x), abovePixel(dest, + destOffset, destDy, x), aboveLeftPixel(dest, + destOffset, destDy, x))); + } + } +} diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/predictor/PredictorAlgorithm.java b/src/main/java/org/pdfbox/pdmodel/graphics/predictor/PredictorAlgorithm.java new file mode 100644 index 0000000..11f60f9 --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/predictor/PredictorAlgorithm.java @@ -0,0 +1,336 @@ +/** + * Copyright (c) 2005, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.pdmodel.graphics.predictor; + +import java.util.Random; + +/** + * Implements different PNG predictor algorithms that is used in PDF files. + * + * @author xylifyx@yahoo.co.uk + * @version $Revision: 1.2 $ + * @see http://www.w3.org/TR/PNG-Filters.html + */ +public abstract class PredictorAlgorithm +{ + private int width; + + private int height; + + private int bpp; + + /** + * check that buffer sizes matches width,height,bpp. This implementation is + * used by most of the filters, but not Uptimum. + * + * @param src The source buffer. + * @param dest The destination buffer. + */ + public void checkBufsiz(byte[] src, byte[] dest) + { + if (src.length != dest.length) + { + throw new IllegalArgumentException("src.length != dest.length"); + } + if (src.length != getWidth() * getHeight() * getBpp()) + { + throw new IllegalArgumentException( + "src.length != width * height * bpp"); + } + } + + /** + * encode line of pixel data in src from srcOffset and width*bpp bytes + * forward, put the decoded bytes into dest. + * + * @param src + * raw image data + * @param dest + * encoded data + * @param srcDy + * byte offset between lines + * @param srcOffset + * beginning of line data + * @param destDy + * byte offset between lines + * @param destOffset + * beginning of line data + */ + public abstract void encodeLine(byte[] src, byte[] dest, int srcDy, + int srcOffset, int destDy, int destOffset); + + /** + * decode line of pixel data in src from src_offset and width*bpp bytes + * forward, put the decoded bytes into dest. + * + * @param src + * encoded image data + * @param dest + * raw data + * @param srcDy + * byte offset between lines + * @param srcOffset + * beginning of line data + * @param destDy + * byte offset between lines + * @param destOffset + * beginning of line data + */ + public abstract void decodeLine(byte[] src, byte[] dest, int srcDy, + int srcOffset, int destDy, int destOffset); + + /** + * Simple command line program to test the algorithm. + * + * @param args The command line arguments. + */ + public static void main(String[] args) + { + Random rnd = new Random(); + int width = 5; + int height = 5; + int bpp = 3; + byte[] raw = new byte[width * height * bpp]; + rnd.nextBytes(raw); + System.out.println("raw: "); + dump(raw); + for (int i = 10; i < 15; i++) + { + byte[] decoded = new byte[width * height * bpp]; + byte[] encoded = new byte[width * height * bpp]; + + PredictorAlgorithm filter = PredictorAlgorithm.getFilter(i); + filter.setWidth(width); + filter.setHeight(height); + filter.setBpp(bpp); + filter.encode(raw, encoded); + filter.decode(encoded, decoded); + System.out.println(filter.getClass().getName()); + dump(decoded); + } + } + + /** + * Get the left pixel from the buffer. + * + * @param buf The buffer. + * @param offset The offset into the buffer. + * @param dy The dy value. + * @param x The x value. + * + * @return The left pixel. + */ + public int leftPixel(byte[] buf, int offset, int dy, int x) + { + return x >= getBpp() ? buf[offset + x - getBpp()] : 0; + } + + /** + * Get the above pixel from the buffer. + * + * @param buf The buffer. + * @param offset The offset into the buffer. + * @param dy The dy value. + * @param x The x value. + * + * @return The above pixel. + */ + public int abovePixel(byte[] buf, int offset, int dy, int x) + { + return offset >= dy ? buf[offset + x - dy] : 0; + } + + /** + * Get the above-left pixel from the buffer. + * + * @param buf The buffer. + * @param offset The offset into the buffer. + * @param dy The dy value. + * @param x The x value. + * + * @return The above-left pixel. + */ + public int aboveLeftPixel(byte[] buf, int offset, int dy, int x) + { + return offset >= dy && x >= getBpp() ? buf[offset + x - dy - getBpp()] + : 0; + } + + /** + * Simple helper to print out a buffer. + * + * @param raw The bytes to print out. + */ + private static void dump(byte[] raw) + { + for (int i = 0; i < raw.length; i++) + { + System.out.print(raw[i] + " "); + } + System.out.println(); + } + + /** + * @return Returns the bpp. + */ + public int getBpp() + { + return bpp; + } + + /** + * @param newBpp + * The bpp to set. + */ + public void setBpp(int newBpp) + { + bpp = newBpp; + } + + /** + * @return Returns the height. + */ + public int getHeight() + { + return height; + } + + /** + * @param newHeight + * The height to set. + */ + public void setHeight(int newHeight) + { + height = newHeight; + } + + /** + * @return Returns the width. + */ + public int getWidth() + { + return width; + } + + /** + * @param newWidth + * The width to set. + */ + public void setWidth(int newWidth) + { + this.width = newWidth; + } + + + /** + * encode a byte array full of image data using the filter that this object + * implements. + * + * @param src + * buffer + * @param dest + * buffer + */ + public void encode(byte[] src, byte[] dest) + { + checkBufsiz(dest, src); + int dy = getWidth()*getBpp(); + for (int y = 0; y < height; y++) + { + int yoffset = y * dy; + encodeLine(src, dest, dy, yoffset, dy, yoffset); + } + } + + /** + * decode a byte array full of image data using the filter that this object + * implements. + * + * @param src + * buffer + * @param dest + * buffer + */ + public void decode(byte[] src, byte[] dest) + { + checkBufsiz(src, dest); + int dy = width * bpp; + for (int y = 0; y < height; y++) + { + int yoffset = y * dy; + decodeLine(src, dest, dy, yoffset, dy, yoffset); + } + } + + /** + * @param predictor + * + * + * @return The predictor class based on the predictor code. + */ + public static PredictorAlgorithm getFilter(int predictor) + { + PredictorAlgorithm filter; + switch (predictor) + { + case 10: + filter = new None(); + break; + case 11: + filter = new Sub(); + break; + case 12: + filter = new Up(); + break; + case 13: + filter = new Average(); + break; + case 14: + filter = new Paeth(); + break; + case 15: + filter = new Uptimum(); + break; + default: + filter = new None(); + } + return filter; + } +} diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/predictor/Sub.java b/src/main/java/org/pdfbox/pdmodel/graphics/predictor/Sub.java new file mode 100644 index 0000000..3959dbe --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/predictor/Sub.java @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2005, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.pdmodel.graphics.predictor; + +/** + * The sub algorithm. + * + * Sub(i,j) = Raw(i,j) - Raw(i-1,j) + * + * Raw(i,j) = Sub(i,j) + Raw(i-1,j) + * + * @author xylifyx@yahoo.co.uk + * @version $Revision: 1.2 $ + */ +public class Sub extends PredictorAlgorithm +{ + /** + * @see org.pdfbox.pdmodel.graphics.predictor.PredictorAlgorithm#encodeLine(byte[], byte[], int, int, int, int) + */ + public void encodeLine(byte[] src, byte[] dest, int srcDy, int srcOffset, + int destDy, int destOffset) + { + int bpl = getWidth()*getBpp(); + int bpp = getBpp(); + // case: x < bpp + for (int x = 0; x < bpl && x < bpp; x++) + { + dest[x + destOffset] = src[x + srcOffset]; + } + // otherwise + for (int x = getBpp(); x < bpl; x++) + { + dest[x + destOffset] = (byte) (src[x + srcOffset] - src[x + + srcOffset - bpp]); + } + } + + /** + * @see org.pdfbox.pdmodel.graphics.predictor.PredictorAlgorithm#decodeLine(byte[], byte[], int, int, int, int) + */ + public void decodeLine(byte[] src, byte[] dest, int srcDy, int srcOffset, + int destDy, int destOffset) + { + int bpl = getWidth()*getBpp(); + int bpp = getBpp(); + // case: x < bpp + for (int x = 0; x < bpl && x < bpp; x++) + { + dest[x + destOffset] = src[x + srcOffset]; + } + // otherwise + for (int x = getBpp(); x < bpl; x++) + { + dest[x + destOffset] = (byte) (src[x + srcOffset] + dest[x + + destOffset - bpp]); + } + } +} diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/predictor/Up.java b/src/main/java/org/pdfbox/pdmodel/graphics/predictor/Up.java new file mode 100644 index 0000000..f1932b4 --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/predictor/Up.java @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2005, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.pdmodel.graphics.predictor; + +/** + * The up algorithm. + * + * Up(i,j) = Raw(i,j) - Raw(i,j-1) + * + * Raw(i,j) = Up(i,j) + Raw(i,j-1) + * + * @author xylifyx@yahoo.co.uk + * @version $Revision: 1.2 $ + */ +public class Up extends PredictorAlgorithm +{ + /** + * @see org.pdfbox.pdmodel.graphics.predictor.PredictorAlgorithm#encodeLine(byte[], byte[], int, int, int, int) + */ + public void encodeLine(byte[] src, byte[] dest, int srcDy, int srcOffset, + int destDy, int destOffset) + { + int bpl = getWidth()*getBpp(); + // case: y = 0; + if (srcOffset - srcDy < 0) + { + if (0 < getHeight()) + { + for (int x = 0; x < bpl; x++) + { + dest[destOffset + x] = src[srcOffset + x]; + } + } + } + else + { + for (int x = 0; x < bpl; x++) + { + dest[destOffset + x] = (byte) (src[srcOffset + x] - src[srcOffset + + x - srcDy]); + } + } + } + + /** + * @see org.pdfbox.pdmodel.graphics.predictor.PredictorAlgorithm#decodeLine(byte[], byte[], int, int, int, int) + */ + public void decodeLine(byte[] src, byte[] dest, int srcDy, int srcOffset, + int destDy, int destOffset) + { + // case: y = 0; + int bpl = getWidth()*getBpp(); + if (destOffset - destDy < 0) + { + if (0 < getHeight()) + { + for (int x = 0; x < bpl; x++) + { + dest[destOffset + x] = src[srcOffset + x]; + } + } + } + else + { + for (int x = 0; x < bpl; x++) + { + dest[destOffset + x] = (byte) (src[srcOffset + x] + dest[destOffset + + x - destDy]); + } + } + } +} diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/predictor/Uptimum.java b/src/main/java/org/pdfbox/pdmodel/graphics/predictor/Uptimum.java new file mode 100644 index 0000000..ac03162 --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/predictor/Uptimum.java @@ -0,0 +1,153 @@ +/** + * Copyright (c) 2005, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.pdmodel.graphics.predictor; + +/** + * + * + * In an Uptimum encoded image, each line takes up width*bpp+1 bytes. The first + * byte holds a number that signifies which algorithm encoded the line. + * + * @author xylifyx@yahoo.co.uk + * @version $Revision: 1.2 $ + */ +public class Uptimum extends PredictorAlgorithm +{ + /** + * @see PredictorAlgorithm#checkBufsiz(byte[], byte[]) + */ + public void checkBufsiz(byte[] filtered, byte[] raw) + { + if (filtered.length != (getWidth() * getBpp() + 1) * getHeight()) + { + + throw new IllegalArgumentException( + "filtered.length != (width*bpp + 1) * height, " + + filtered.length + " " + + (getWidth() * getBpp() + 1) * getHeight() + + "w,h,bpp=" + getWidth() + "," + getHeight() + "," + + getBpp()); + } + if (raw.length != getWidth() * getHeight() * getBpp()) + { + throw new IllegalArgumentException( + "raw.length != width * height * bpp, raw.length=" + + raw.length + " w,h,bpp=" + getWidth() + "," + + getHeight() + "," + getBpp()); + } + } + + /** + * @see org.pdfbox.pdmodel.graphics.predictor.PredictorAlgorithm#encodeLine(byte[], byte[], + * int, int, int, int) + */ + public void encodeLine(byte[] src, byte[] dest, int srcDy, int srcOffset, + int destDy, int destOffset) + { + throw new UnsupportedOperationException("encodeLine"); + } + + /** + * @see org.pdfbox.pdmodel.graphics.predictor.PredictorAlgorithm#decodeLine(byte[], byte[], + * int, int, int, int) + */ + public void decodeLine(byte[] src, byte[] dest, int srcDy, int srcOffset, + int destDy, int destOffset) + { + throw new UnsupportedOperationException("decodeLine"); + } + + /** + * @see PredictorAlgorithm#encode(byte[], byte[]) + */ + public void encode(byte[] src, byte[] dest) + { + checkBufsiz(dest, src); + throw new UnsupportedOperationException("encode"); + } + + /** + * filter indexed by byte code. + */ + PredictorAlgorithm[] filter = { new None(), new Sub(), new Up(), new Average(), + new Paeth() }; + + /** + * @see org.pdfbox.pdmodel.graphics.predictor.PredictorAlgorithm#setBpp(int) + */ + public void setBpp(int bpp) + { + super.setBpp(bpp); + for (int i = 0; i < filter.length; i++) + { + filter[i].setBpp(bpp); + } + } + /** + * @see org.pdfbox.pdmodel.graphics.predictor.PredictorAlgorithm#setHeight(int) + */ + public void setHeight(int height) + { + super.setHeight(height); + for (int i = 0; i < filter.length; i++) + { + filter[i].setHeight(height); + } + } + + /** + * @see org.pdfbox.pdmodel.graphics.predictor.PredictorAlgorithm#setWidth(int) + */ + public void setWidth(int width) + { + super.setWidth(width); + for (int i = 0; i < filter.length; i++) + { + filter[i].setWidth(width); + } + } + + /** + * @see PredictorAlgorithm#decode(byte[], byte[]) + */ + public void decode(byte[] src, byte[] dest) + { + checkBufsiz(src, dest); + int bpl = getWidth() * getBpp(); + int srcDy = bpl + 1; + for (int y = 0; y < getHeight(); y++) + { + PredictorAlgorithm f = filter[src[y * srcDy]]; + int srcOffset = y * srcDy + 1; + f.decodeLine(src, dest, srcDy, srcOffset, bpl, y * bpl); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/predictor/package.html b/src/main/java/org/pdfbox/pdmodel/graphics/predictor/package.html new file mode 100644 index 0000000..127d2e0 --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/predictor/package.html @@ -0,0 +1,10 @@ + + + + + + +The predictor package contains code for different PNG predictor algorithms that +are present in PDF documents. These classes are used internally by PDFBox. + + diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDCcitt.java b/src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDCcitt.java new file mode 100644 index 0000000..59387a0 --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDCcitt.java @@ -0,0 +1,598 @@ +/** + * Copyright (c) 2005, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.pdmodel.graphics.xobject; + +import java.awt.image.BufferedImage; +import java.io.InputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.RandomAccessFile; + +import java.util.ArrayList; +import java.util.List; + +import javax.imageio.ImageIO; + +import org.pdfbox.cos.COSDictionary; +import org.pdfbox.cos.COSName; + +import org.pdfbox.pdmodel.PDDocument; +import org.pdfbox.pdmodel.common.PDStream; +import org.pdfbox.pdmodel.graphics.color.PDDeviceGray; + +/** + * An image class for CCITT Fax. + * + * @author paul king + * @version $Revision: 1.2 $ + */ +public class PDCcitt extends PDXObjectImage +{ + private static final List FAX_FILTERS = new ArrayList(); + + static + { + FAX_FILTERS.add( COSName.CCITTFAX_DECODE.getName() ); + FAX_FILTERS.add( COSName.CCITTFAX_DECODE_ABBREVIATION.getName() ); + } + + /** + * Standard constructor. + * + * @param ccitt The PDStream that already contains all ccitt information. + */ + public PDCcitt(PDStream ccitt) + { + super(ccitt, "tiff"); + + } + + /** + * Construct from a tiff file. + * + * @param doc The document to create the image as part of. + * @param raf The random access TIFF file which contains a suitable CCITT compressed image + * @throws IOException If there is an error reading the tiff data. + */ + + public PDCcitt( PDDocument doc, java.io.RandomAccessFile raf ) throws IOException + { + super( new PDStream(doc),"tiff"); + // super( new PDStream( doc, null, true ), "tiff" ); + + COSDictionary decodeParms = new COSDictionary(); + + COSDictionary dic = getCOSStream(); + + extractFromTiff(raf, getCOSStream().createFilteredStream(),decodeParms); + + dic.setItem( COSName.FILTER, COSName.CCITTFAX_DECODE); + dic.setItem( COSName.SUBTYPE, COSName.IMAGE); + dic.setItem( COSName.TYPE, COSName.getPDFName( "XObject" ) ); + dic.setItem( "DecodeParms", decodeParms); + + setBitsPerComponent( 1 ); + setColorSpace( new PDDeviceGray() ); + setWidth( decodeParms.getInt("Columns") ); + setHeight( decodeParms.getInt("Rows") ); + + } + + /** + * Returns an image of the CCITT Fax, or null if TIFFs are not supported. (Requires additional JAI Image filters ) + * @see org.pdfbox.pdmodel.graphics.xobject.PDXObjectImage#getRGBImage() + */ + public BufferedImage getRGBImage() throws IOException + { + // ImageIO.scanForPlugins(); + return ImageIO.read(new TiffWrapper(getPDStream().getPartiallyFilteredStream( FAX_FILTERS ),getCOSStream())); + } + + /** + * This writes a tiff to out. + * @see org.pdfbox.pdmodel.graphics.xobject.PDXObjectImage#write2OutputStream(java.io.OutputStream) + */ + public void write2OutputStream(OutputStream out) throws IOException + { + InputStream data = new TiffWrapper(getPDStream().getPartiallyFilteredStream( FAX_FILTERS ),getCOSStream()); + byte[] buf = new byte[1024]; + int amountRead = -1; + while( (amountRead = data.read( buf )) != -1 ) + { + out.write( buf, 0, amountRead ); + } + } + + /** + * Extract the ccitt stream from the tiff file. + * + * @param raf - TIFF File + * @param os - Stream to write raw ccitt data two + * @param parms - COSDictionary which the encoding parameters are added to + * @throws IOException If there is an error reading/writing to/from the stream + */ + private void extractFromTiff(RandomAccessFile raf, OutputStream os, COSDictionary parms) throws IOException + { + try + { + + // First check the basic tiff header + raf.seek(0); + char endianess = (char) raf.read(); + if ((char) raf.read() != endianess) + { + throw new IOException("Not a valid tiff file"); + } + //ensure that endianess is either M or I + if (endianess != 'M' && endianess != 'I') + { + throw new IOException("Not a valid tiff file"); + } + int magicNumber = readshort(endianess, raf); + if( magicNumber != 42) + { + throw new IOException("Not a valid tiff file"); + } + + // Relocate to the first set of tags + raf.seek(readlong(endianess, raf)); + + int numtags = readshort(endianess, raf); + + // The number 50 is somewhat arbitary, it just stops us load up junk from somewhere and tramping on + if (numtags > 50) + { + throw new IOException("Not a valid tiff file"); + } + + // Loop through the tags, some will convert to items in the parms dictionary + // Other point us to where to find the data stream + // The only parm which might change as a result of other options is K, so + // We'll deal with that as a special; + + int k=-1000; // Default Non CCITT compression + int dataoffset=0; + int datalength=0; + + for (int i=0; i < numtags; i++) + { + int tag = readshort(endianess, raf); + int type = readshort(endianess, raf); + int count = readlong(endianess, raf); + int val = readlong(endianess, raf); // See note + + // Note, we treated that value as a long. The value always occupies 4 bytes + // But it might only use the first byte or two. Depending on endianess we might need to correct + // Note we ignore all other types, they are of little interest for PDFs/CCITT Fax + if (endianess == 'M') + { + switch (type) + { + case 1: + { + val = val >> 24; + break; // byte value + } + case 3: + { + val = val >> 16; + break; // short value + } + case 4: + { + break; // long value + } + default: + { + //do nothing + } + } + } + switch (tag) + { + case 256: + { + parms.setInt("Columns",val); + break; + } + case 257: + { + parms.setInt("Rows",val); + break; + } + case 259: + { + if (val == 4) + { + k=-1; + } + if (val == 3) + { + k=0; + } + break; // T6/T4 Compression + } + case 262: + { + if (val == 1) + { + parms.setBoolean("BlackIs1", true); + } + break; + } + case 273: + { + if (count == 1) + { + dataoffset=val; + } + break; + } + case 279: + { + if (count == 1) + { + datalength=val; + } + break; + } + case 292: + { + if (val == 1) + { + k=50; // T4 2D - arbitary K value + } + break; + } + case 324: + { + if (count == 1) + { + dataoffset=val; + } + break; + } + case 325: + { + if (count == 1) + { + datalength=val; + } + break; + } + default: + { + //do nothing + } + } + } + + if (k == -1000) + { + throw new IOException("First image in tiff is not CCITT T4 or T6 compressed"); + } + if (dataoffset == 0) + { + throw new IOException("First image in tiff is not a single tile/strip"); + } + + parms.setInt("K",k); + + raf.seek(dataoffset); + + byte[] buf = new byte[8192]; + int amountRead = -1; + while( (amountRead = raf.read( buf,0, Math.min(8192,datalength) )) > 0 ) + { + datalength -= amountRead; + os.write( buf, 0, amountRead ); + } + + } + finally + { + os.close(); + } + } + + private int readshort(char endianess, RandomAccessFile raf) throws IOException + { + if (endianess == 'I') + { + return raf.read() | (raf.read() << 8); + } + return (raf.read() << 8) | raf.read(); + } + + private int readlong(char endianess, RandomAccessFile raf) throws IOException + { + if (endianess == 'I') + { + return raf.read() | (raf.read() << 8) | (raf.read() << 16) | (raf.read() << 24); + } + return (raf.read() << 24) | (raf.read() << 16) | (raf.read() << 8) | raf.read(); + } + + + /** + * Extends InputStream to wrap the data from the CCITT Fax with a suitable TIFF Header. + * For details see www.tiff.org, which contains useful information including pointers to the + * TIFF 6.0 Specification + * + */ + private class TiffWrapper extends InputStream + { + + private int currentOffset; // When reading, where in the tiffheader are we. + private byte[] tiffheader; // Byte array to store tiff header data + private InputStream datastream; // Original InputStream + + public TiffWrapper(InputStream rawstream, COSDictionary options) + { + buildHeader(options); + currentOffset=0; + datastream = rawstream; + } + + // Implement basic methods from InputStream + + public boolean markSupported() + { + return false; + } + + public void reset() throws IOException + { + throw new IOException("reset not supported"); + } + + // For simple read, take a byte from the tiffheader array or pass through. + public int read() throws IOException + { + if (currentOffset < tiffheader.length) + { + return tiffheader[currentOffset++]; + } + return datastream.read(); + } + + // For read methods only return as many bytes as we have left in the header + // if we've exhausted the header, pass through to the InputStream of the raw CCITT data + public int read(byte[] data) throws IOException + { + if (currentOffset < tiffheader.length) + { + int length = java.lang.Math.min(tiffheader.length - currentOffset, data.length); + if (length > 0) + { + System.arraycopy(tiffheader, currentOffset, data, 0, length); + } + currentOffset += length; + return length; + } + else + { + return datastream.read(data); + } + } + + // For read methods only return as many bytes as we have left in the header + // if we've exhausted the header, pass through to the InputStream of the raw CCITT data + public int read(byte[] data, int off, int len) throws IOException + { + if (currentOffset < tiffheader.length) + { + int length = java.lang.Math.min(tiffheader.length - currentOffset, len); + if (length > 0) + { + System.arraycopy(tiffheader, currentOffset, data, off, length); + } + currentOffset += length; + return length; + } + else + { + return datastream.read(data,off,len); + } + } + + // When skipping if any header data not yet read, only allow to skip what we've in the buffer + // Otherwise just pass through. + public long skip(long n) throws IOException + { + if (currentOffset < tiffheader.length) + { + long length = Math.min(tiffheader.length - currentOffset, n); + currentOffset += length; + return length; + } + else + { + return datastream.skip(n); + } + } + + // Static data for the beginning of the TIFF header + private final byte[] basicHeader = { + 'I','I',42,0,8,0,0,0, // File introducer and pointer to first IFD + 0,0}; // Number of tags start with two + + + private int additionalOffset; // Offset in header to additional data + + // Builds up the tiffheader based on the options passed through. + private void buildHeader(COSDictionary options) + { + + final int numOfTags = 10; // The maximum tags we'll fill + final int maxAdditionalData = 24; // The maximum amount of additional data + // outside the IFDs. (bytes) + + // The length of the header will be the length of the basic header (10) + // plus 12 bytes for each IFD, 4 bytes as a pointer to the next IFD (will be 0) + // plus the length of the additional data + + tiffheader = new byte[10 + (12 * numOfTags ) + 4 + maxAdditionalData]; + java.util.Arrays.fill(tiffheader,(byte)0); + System.arraycopy(basicHeader,0,tiffheader,0,basicHeader.length); + + // Additional data outside the IFD starts after the IFD's and pointer to the next IFD (0) + additionalOffset = 10 + (12 * numOfTags ) + 4; + + // Now work out the variable values from TIFF defaults, + // PDF Defaults and the Dictionary for this XObject + short cols = 1728; + short rows = 0; + short blackis1 = 0; + short comptype = 3; // T4 compression + long t4options = 0; // Will set if 1d or 2d T4 + + COSDictionary decodeParms = (COSDictionary) options.getDictionaryObject("DecodeParms"); + + if (decodeParms != null) + { + cols = (short) decodeParms.getInt("Columns", cols); + rows = (short) decodeParms.getInt("Rows", rows); + if (decodeParms.getBoolean("BlackIs1", false)) + { + blackis1 = 1; + } + int k = decodeParms.getInt("K"); // Mandatory parm + if (k < 0) + { + //T6 + comptype = 4; + } + if (k > 0) + { + //T4 2D + comptype = 3; + t4options = 1; + } + // else k = 0, leave as default T4 1D compression + } + + // If we couldn't get the number of rows, use the main item from XObject + if (rows == 0) + { + rows = (short) options.getInt("Height", rows); + } + + // Now put the tags into the tiffheader + // These musn't exceed the maximum set above, and by TIFF spec should be sorted into + // Numeric sequence. + + addTag(256, cols); // Columns + addTag(257, rows); // Rows + addTag(259, comptype); // T6 + addTag(262, blackis1); // Photometric Interpretation + addTag(273, (long) tiffheader.length); // Offset to start of image data - updated below + addTag(279, (long) options.getInt("Length")); // Length of image data + addTag(282, 300, 1); // X Resolution 300 (default unit Inches) This is arbitary + addTag(283, 300, 1); // Y Resolution 300 (default unit Inches) This is arbitary + if (comptype == 3) + { + addTag(292, t4options); + } + addTag(305, "PDFBOX"); // Software generating image + } + + /* Tiff types 1 = byte, 2=ascii, 3=short, 4=ulong 5=rational */ + + private void addTag(int tag,long value) + { + // Adds a tag of type 4 (ulong) + int count = ++tiffheader[8]; + int offset = (count-1)*12 + 10; + tiffheader[offset]=(byte)(tag & 0xff); + tiffheader[offset+1]=(byte)((tag>>8) & 0xff); + tiffheader[offset+2]=4; // Type Long + tiffheader[offset+4]=1; // One Value + tiffheader[offset+8]=(byte)(value & 0xff); + tiffheader[offset+9]=(byte)((value>>8) & 0xff); + tiffheader[offset+10]=(byte)((value>>16) & 0xff); + tiffheader[offset+11]=(byte)((value>>24) & 0xff); + } + + private void addTag(int tag, short value) + { + // Adds a tag of type 3 (short) + int count = ++tiffheader[8]; + int offset = (count-1)*12 + 10; + tiffheader[offset]=(byte)(tag & 0xff); + tiffheader[offset+1]=(byte)((tag>>8) & 0xff); + tiffheader[offset+2]=3; // Type Short + tiffheader[offset+4]=1; // One Value + tiffheader[offset+8]=(byte)(value & 0xff); + tiffheader[offset+9]=(byte)((value>>8) & 0xff); + } + + private void addTag(int tag, String value) + { + // Adds a tag of type 2 (ascii) + int count = ++tiffheader[8]; + int offset = (count-1)*12 + 10; + tiffheader[offset]=(byte)(tag & 0xff); + tiffheader[offset+1]=(byte)((tag>>8) & 0xff); + tiffheader[offset+2]=2; // Type Ascii + tiffheader[offset+4]=1; // One Value + tiffheader[offset+8]=(byte)(additionalOffset & 0xff); + tiffheader[offset+9]=(byte)((additionalOffset>>8) & 0xff); + tiffheader[offset+10]=(byte)((additionalOffset>>16) & 0xff); + tiffheader[offset+11]=(byte)((additionalOffset>>24) & 0xff); + System.arraycopy(value.getBytes(), 0, tiffheader, additionalOffset, value.length()); + additionalOffset += value.length() + 1; + } + + private void addTag(int tag, long numerator, long denominator) + { + // Adds a tag of type 5 (rational) + int count = ++tiffheader[8]; + int offset = (count-1)*12 + 10; + tiffheader[offset]=(byte)(tag & 0xff); + tiffheader[offset+1]=(byte)((tag>>8) & 0xff); + tiffheader[offset+2]=5; // Type Rational + tiffheader[offset+4]=1; // One Value + tiffheader[offset+8]=(byte)(additionalOffset & 0xff); + tiffheader[offset+9]=(byte)((additionalOffset>>8) & 0xff); + tiffheader[offset+10]=(byte)((additionalOffset>>16) & 0xff); + tiffheader[offset+11]=(byte)((additionalOffset>>24) & 0xff); + tiffheader[additionalOffset++]=(byte) ((numerator) & 0xFF); + tiffheader[additionalOffset++]=(byte) ((numerator>>8) & 0xFF); + tiffheader[additionalOffset++]=(byte) ((numerator>>16) & 0xFF); + tiffheader[additionalOffset++]=(byte) ((numerator>>24) & 0xFF); + tiffheader[additionalOffset++]=(byte) ((denominator) & 0xFF); + tiffheader[additionalOffset++]=(byte) ((denominator>>8) & 0xFF); + tiffheader[additionalOffset++]=(byte) ((denominator>>16) & 0xFF); + tiffheader[additionalOffset++]=(byte) ((denominator>>24) & 0xFF); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDInlinedImage.java b/src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDInlinedImage.java new file mode 100644 index 0000000..009743f --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDInlinedImage.java @@ -0,0 +1,201 @@ +/** + * Copyright (c) 2003-2004, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.pdmodel.graphics.xobject; + +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferByte; +import java.awt.image.DataBufferInt; +import java.awt.image.IndexColorModel; +import java.awt.image.WritableRaster; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.List; + +import org.pdfbox.filter.Filter; +import org.pdfbox.filter.FilterManager; +import org.pdfbox.pdmodel.graphics.color.PDColorSpace; +import org.pdfbox.util.ImageParameters; + +/** + * This class represents an inlined image. + * + * @author Ben Litchfield (ben@csh.rit.edu) + * @version $Revision: 1.4 $ + */ +public class PDInlinedImage +{ + private ImageParameters params; + private byte[] imageData; + + /** + * This will get the image parameters. + * + * @return The image parameters. + */ + public ImageParameters getImageParameters() + { + return params; + } + + /** + * This will set the image parameters for this image. + * + * @param imageParams The imageParams. + */ + public void setImageParameters( ImageParameters imageParams ) + { + params = imageParams; + } + + /** + * Get the bytes for the image. + * + * @return The image data. + */ + public byte[] getImageData() + { + return imageData; + } + + /** + * Set the bytes that make up the image. + * + * @param value The image data. + */ + public void setImageData(byte[] value) + { + imageData = value; + } + + /** + * This will take the inlined image information and create a java.awt.Image from + * it. + * + * @return The image that this object represents. + * + * @throws IOException If there is an error creating the image. + */ + public BufferedImage createImage() throws IOException + { + /* + * This was the previous implementation, not sure which is better right now. + * byte[] transparentColors = new byte[]{(byte)0xFF,(byte)0xFF}; + byte[] colors=new byte[]{0, (byte)0xFF}; + IndexColorModel colorModel = new IndexColorModel( 1, 2, colors, colors, colors, transparentColors ); + BufferedImage image = new BufferedImage( + params.getWidth(), + params.getHeight(), + BufferedImage.TYPE_BYTE_BINARY, + colorModel ); + DataBufferByte buffer = new DataBufferByte( getImageData(), 1 ); + WritableRaster raster = + Raster.createPackedRaster( + buffer, + params.getWidth(), + params.getHeight(), + params.getBitsPerComponent(), + new Point(0,0) ); + image.setData( raster ); + return image; + */ + + + //verify again pci32.pdf before changing below + PDColorSpace pcs = params.getColorSpace(); + ColorModel colorModel = null; + if(pcs != null) + { + colorModel = + params.getColorSpace().createColorModel( + params.getBitsPerComponent() ); + } + else + { + byte[] transparentColors = new + byte[]{(byte)0xFF,(byte)0xFF}; + byte[] colors=new byte[]{0, (byte)0xFF}; + colorModel = new IndexColorModel( 1, 2, + colors, colors, colors, transparentColors ); + } + List filters = params.getFilters(); + byte[] finalData = null; + if( filters == null ) + { + finalData = getImageData(); + } + else + { + ByteArrayInputStream in = new ByteArrayInputStream( getImageData() ); + ByteArrayOutputStream out = new ByteArrayOutputStream(getImageData().length); + FilterManager filterManager = new FilterManager(); + for( int i=0; filters != null && i + *
  • 1 No prediction (the default value) + *
  • 2 TIFF Predictor 2 + *
  • 10 PNG prediction (on encoding, PNG None on all rows) + *
  • 11 PNG prediction (on encoding, PNG Sub on all rows) + *
  • 12 PNG prediction (on encoding, PNG Up on all rows) + *
  • 13 PNG prediction (on encoding, PNG Average on all rows) + *
  • 14 PNG prediction (on encoding, PNG Paeth on all rows) + *
  • 15 PNG prediction (on encoding, PNG optimum) + * + * + * Default value: 1. + * + * @return predictor algorithm code + */ + public int getPredictor() + { + COSDictionary decodeParms = getDecodeParams(); + if (decodeParms != null) + { + int i = decodeParms.getInt("Predictor"); + if (i != -1) + { + return i; + } + } + return 1; + } +} \ No newline at end of file diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDXObject.java b/src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDXObject.java new file mode 100644 index 0000000..99ac8a5 --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDXObject.java @@ -0,0 +1,207 @@ +/** + * Copyright (c) 2005, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.pdmodel.graphics.xobject; + +import java.io.IOException; +import java.util.List; + +import org.pdfbox.cos.COSBase; +import org.pdfbox.cos.COSName; +import org.pdfbox.cos.COSStream; + +import org.pdfbox.pdmodel.PDDocument; +import org.pdfbox.pdmodel.common.COSObjectable; +import org.pdfbox.pdmodel.common.PDMetadata; +import org.pdfbox.pdmodel.common.PDStream; + +/** + * The base class for all XObjects in the PDF document. + * + * @author Ben Litchfield (ben@benlitchfield.com) + * @author mathiak + * @author Marcel Kammer + * @version $Revision: 1.12 $ + */ +public abstract class PDXObject implements COSObjectable +{ + private PDStream xobject; + + /** + * Standard constuctor. + * + * @param xobj The XObject dictionary. + */ + public PDXObject(COSStream xobj) + { + xobject = new PDStream( xobj ); + } + + /** + * Standard constuctor. + * + * @param xobj The XObject dictionary. + */ + public PDXObject(PDStream xobj) + { + xobject = xobj; + } + + /** + * Standard constuctor. + * + * @param doc The doc to store the object contents. + */ + public PDXObject(PDDocument doc) + { + xobject = new PDStream(doc); + xobject.getStream().setName( COSName.TYPE, "XObject" ); + } + + /** + * Returns the stream. + * @see org.pdfbox.pdmodel.common.COSObjectable#getCOSObject() + */ + public COSBase getCOSObject() + { + return xobject.getCOSObject(); + } + + /** + * Returns the stream. + * @return The stream for this object. + */ + public COSStream getCOSStream() + { + return xobject.getStream(); + } + + /** + * Returns the stream. + * @return The stream for this object. + */ + public PDStream getPDStream() + { + return xobject; + } + + /** + * Create the correct xobject from the cos base. + * + * @param xobject The cos level xobject to create. + * + * @return a pdmodel xobject + * @throws IOException If there is an error creating the xobject. + */ + public static PDXObject createXObject( COSBase xobject ) throws IOException + { + PDXObject retval = null; + if( xobject == null ) + { + retval = null; + } + else if( xobject instanceof COSStream ) + { + COSStream xstream = (COSStream)xobject; + String subtype = xstream.getNameAsString( "Subtype" ); + if( subtype.equals( PDXObjectImage.SUB_TYPE ) ) + { + PDStream image = new PDStream( xstream ); + // See if filters are DCT or JPX otherwise treat as Bitmap-like + // There might be a problem with several filters, but that's ToDo until + // I find an example + List filters = image.getFilters(); + if( filters != null && filters.contains( COSName.DCT_DECODE.getName() ) ) + { + return new PDJpeg(image); + } + else if ( filters != null && filters.contains( COSName.CCITTFAX_DECODE.getName() ) ) + { + return new PDCcitt(image); + } + else if( filters != null && filters.contains(COSName.JPX_DECODE.getName())) + { + //throw new IOException( "JPXDecode has not been implemented for images" ); + //JPX Decode is not really supported right now, but if we are just doing + //text extraction then we don't want to throw an exception, so for now + //just return a PDPixelMap, which will break later on if it is + //actually used, but for text extraction it is not used. + return new PDPixelMap( image ); + + } + else + { + retval = new PDPixelMap(image); + } + } + else if( subtype.equals( PDXObjectForm.SUB_TYPE ) ) + { + retval = new PDXObjectForm( xstream ); + } + else + { + throw new IOException( "Unknown xobject subtype '" + subtype + "'" ); + } + } + else + { + throw new IOException( "Unknown xobject type:" + xobject.getClass().getName() ); + } + + return retval; + } + + /** + * Get the metadata that is part of the document catalog. This will + * return null if there is no meta data for this object. + * + * @return The metadata for this object. + */ + public PDMetadata getMetadata() + { + PDMetadata retval = null; + COSStream mdStream = (COSStream)xobject.getStream().getDictionaryObject( "Metadata" ); + if( mdStream != null ) + { + retval = new PDMetadata( mdStream ); + } + return retval; + } + + /** + * Set the metadata for this object. This can be null. + * + * @param meta The meta data for this object. + */ + public void setMetadata( PDMetadata meta ) + { + xobject.getStream().setItem( "Metadata", meta ); + } +} diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDXObjectForm.java b/src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDXObjectForm.java new file mode 100644 index 0000000..08858ea --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDXObjectForm.java @@ -0,0 +1,120 @@ +/** + * Copyright (c) 2005, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.pdmodel.graphics.xobject; + +import org.pdfbox.cos.COSDictionary; +import org.pdfbox.cos.COSName; +import org.pdfbox.cos.COSStream; + +import org.pdfbox.pdmodel.PDResources; +import org.pdfbox.pdmodel.common.PDStream; + +/** + * A form xobject. + * + * @author Ben Litchfield (ben@benlitchfield.com) + * @version $Revision: 1.4 $ + */ +public class PDXObjectForm extends PDXObject +{ + /** + * The XObject subtype. + */ + public static final String SUB_TYPE = "Form"; + + /** + * Standard constuctor. + * + * @param formStream The XObject is passed as a COSStream. + */ + public PDXObjectForm(PDStream formStream) + { + super( formStream ); + } + + /** + * Standard constuctor. + * + * @param formStream The XObject is passed as a COSStream. + */ + public PDXObjectForm(COSStream formStream) + { + super( formStream ); + } + + /** + * This will get the form type, currently 1 is the only form type. + * + * @return The form type. + */ + public int getFormType() + { + return getCOSStream().getInt( "FormType",1 ); + } + + /** + * Set the form type. + * + * @param formType The new form type. + */ + public void setFormType( int formType ) + { + getCOSStream().setInt( "FormType", formType ); + } + + /** + * This will get the resources at this page and not look up the hierarchy. + * This attribute is inheritable, and findResources() should probably used. + * This will return null if no resources are available at this level. + * + * @return The resources at this level in the hierarchy. + */ + public PDResources getResources() + { + PDResources retval = null; + COSDictionary resources = (COSDictionary)getCOSStream().getDictionaryObject( COSName.RESOURCES ); + if( resources != null ) + { + retval = new PDResources( resources ); + } + return retval; + } + + /** + * This will set the resources for this page. + * + * @param resources The new resources for this page. + */ + public void setResources( PDResources resources ) + { + getCOSStream().setItem( COSName.RESOURCES, resources ); + } +} diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDXObjectImage.java b/src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDXObjectImage.java new file mode 100644 index 0000000..6257113 --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDXObjectImage.java @@ -0,0 +1,244 @@ +/** + * Copyright (c) 2004-2005, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.pdmodel.graphics.xobject; + +import java.awt.image.BufferedImage; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import org.pdfbox.cos.COSBase; +import org.pdfbox.cos.COSName; +import org.pdfbox.pdmodel.PDDocument; +import org.pdfbox.pdmodel.common.PDStream; +import org.pdfbox.pdmodel.graphics.color.PDColorSpace; +import org.pdfbox.pdmodel.graphics.color.PDColorSpaceFactory; +import org.pdfbox.pdmodel.graphics.color.PDDeviceGray; + +/** + * The prototype for all PDImages. + * + * @author Ben Litchfield (ben@benlitchfield.com) + * @author mathiak + * @version $Revision: 1.8 $ + */ +public abstract class PDXObjectImage extends PDXObject +{ + /** + * The XObject subtype. + */ + public static final String SUB_TYPE = "Image"; + + /** + * This contains the suffix used when writing to file. + */ + private String suffix; + + /** + * Standard constuctor. + * + * @param imageStream The XObject is passed as a COSStream. + * @param fileSuffix The file suffix, jpg/png. + */ + public PDXObjectImage(PDStream imageStream, String fileSuffix) + { + super( imageStream ); + suffix = fileSuffix; + } + + /** + * Standard constuctor. + * + * @param doc The document to store the stream in. + * @param fileSuffix The file suffix, jpg/png. + */ + public PDXObjectImage(PDDocument doc, String fileSuffix) + { + super( doc ); + getCOSStream().setName( COSName.SUBTYPE, SUB_TYPE ); + suffix = fileSuffix; + } + + /** + * Returns an java.awt.Image, that can be used for display etc. + * + * @return This PDF object as an AWT image. + * + * @throws IOException If there is an error creating the image. + */ + public abstract BufferedImage getRGBImage() throws IOException; + + /** + * Writes the Image to out. + * @param out the OutputStream that the Image is written to. + * @throws IOException when somethings wrong with out + */ + public abstract void write2OutputStream(OutputStream out) throws IOException; + + /** + * Writes the image to a file with the filename + an appropriate suffix, like "Image.jpg". + * The suffix is automatically set by the + * @param filename the filename + * @throws IOException When somethings wrong with the corresponding file. + */ + public void write2file(String filename) throws IOException + { + FileOutputStream out = null; + try + { + out = new FileOutputStream(filename + "." + suffix); + write2OutputStream(out); + out.flush(); + } + finally + { + if( out != null ) + { + out.close(); + } + } + } + + /** + * Get the height of the image. + * + * @return The height of the image. + */ + public int getHeight() + { + return getCOSStream().getInt( "Height", -1 ); + } + + /** + * Set the height of the image. + * + * @param height The height of the image. + */ + public void setHeight( int height ) + { + getCOSStream().setInt( "Height", height ); + } + + /** + * Get the width of the image. + * + * @return The width of the image. + */ + public int getWidth() + { + return getCOSStream().getInt( "Width", -1 ); + } + + /** + * Set the width of the image. + * + * @param width The width of the image. + */ + public void setWidth( int width ) + { + getCOSStream().setInt( "Width", width ); + } + + /** + * The bits per component of this image. This will return -1 if one has not + * been set. + * + * @return The number of bits per component. + */ + public int getBitsPerComponent() + { + return getCOSStream().getInt( new String[] { "BPC", "BitsPerComponent"}, -1 ); + } + + /** + * Set the number of bits per component. + * + * @param bpc The number of bits per component. + */ + public void setBitsPerComponent( int bpc ) + { + getCOSStream().setInt( "BitsPerComponent", bpc ); + } + + /** + * This will get the color space or null if none exists. + * + * @return The color space for this image. + * + * @throws IOException If there is an error getting the colorspace. + */ + public PDColorSpace getColorSpace() throws IOException + { + COSBase cs = getCOSStream().getDictionaryObject( new String[]{ "CS", "ColorSpace" } ); + PDColorSpace retval = null; + if( cs != null ) + { + retval = PDColorSpaceFactory.createColorSpace( cs ); + } + else + { + //there are some cases where the 'required' CS value is not present + //but we know that it will be grayscale for a CCITT filter. + COSBase filter = getCOSStream().getDictionaryObject( "Filter" ); + if( COSName.CCITTFAX_DECODE.equals( filter ) || + COSName.CCITTFAX_DECODE_ABBREVIATION.equals( filter ) ) + { + retval = new PDDeviceGray(); + } + } + return retval; + } + + /** + * This will set the color space for this image. + * + * @param cs The color space for this image. + */ + public void setColorSpace( PDColorSpace cs ) + { + COSBase base = null; + if( cs != null ) + { + base = cs.getCOSObject(); + } + getCOSStream().setItem( COSName.getPDFName( "ColorSpace" ), base ); + } + + /** + * This will get the suffix for this image type, jpg/png. + * + * @return The image suffix. + */ + public String getSuffix() + { + return suffix; + } +} diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/xobject/package.html b/src/main/java/org/pdfbox/pdmodel/graphics/xobject/package.html new file mode 100644 index 0000000..60d3324 --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/graphics/xobject/package.html @@ -0,0 +1,9 @@ + + + + + + +This package deals with images that are stored in a PDF document. + + -- cgit v1.2.3