aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/pdfbox/pdmodel/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/pdfbox/pdmodel/graphics')
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/PDExtendedGraphicsState.java724
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/PDFontSetting.java133
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/PDGraphicsState.java438
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/PDLineDashPattern.java135
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/color/PDCalGray.java240
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/color/PDCalRGB.java289
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/color/PDColorSpace.java97
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/color/PDColorSpaceFactory.java218
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/color/PDColorSpaceInstance.java130
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceCMYK.java137
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceGray.java112
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceN.java244
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceNAttributes.java126
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceRGB.java130
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/color/PDGamma.java151
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/color/PDICCBased.java343
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/color/PDIndexed.java271
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/color/PDLab.java300
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/color/PDPattern.java122
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/color/PDSeparation.java198
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/color/PDTristimulus.java155
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/color/package.html9
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/package.html9
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/predictor/Average.java81
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/predictor/None.java104
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/predictor/Paeth.java121
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/predictor/PredictorAlgorithm.java336
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/predictor/Sub.java86
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/predictor/Up.java100
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/predictor/Uptimum.java153
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/predictor/package.html10
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDCcitt.java598
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDInlinedImage.java201
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDJpeg.java156
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDPixelMap.java236
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDXObject.java207
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDXObjectForm.java120
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDXObjectImage.java244
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/xobject/package.html9
39 files changed, 7473 insertions, 0 deletions
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<cs.getNumComponents(); i++ )
+ {
+ ranges.add( new COSFloat( ics.getMinValue( i ) ) );
+ ranges.add( new COSFloat( ics.getMaxValue( i ) ) );
+ }
+ PDStream iccData = pdCS.getPDStream();
+ OutputStream output = null;
+ try
+ {
+ output = iccData.createOutputStream();
+ output.write( ics.getProfile().getData() );
+ }
+ finally
+ {
+ if( output != null )
+ {
+ output.close();
+ }
+ }
+ pdCS.setNumberOfComponents( cs.getNumComponents() );
+ }
+ else
+ {
+ throw new IOException( "Not yet implemented:" + cs );
+ }
+ return retval;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/color/PDColorSpaceInstance.java b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDColorSpaceInstance.java
new file mode 100644
index 0000000..23693df
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDColorSpaceInstance.java
@@ -0,0 +1,130 @@
+/**
+ * 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;
+import java.io.IOException;
+
+import org.pdfbox.cos.COSArray;
+
+/**
+ * This class represents a color space and the color value for that colorspace.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.3 $
+ */
+public class PDColorSpaceInstance
+{
+ private PDColorSpace colorSpace = new PDDeviceGray();
+ private COSArray colorSpaceValue = new COSArray();
+
+ /**
+ * Default constructor.
+ *
+ */
+ public PDColorSpaceInstance()
+ {
+ //do nothing
+ }
+
+ /**
+ * Create the current color from the colorspace and values.
+ * @return The current awt color.
+ * @throws IOException If there is an error creating the color.
+ */
+ public Color createColor() throws IOException
+ {
+ float[] components = colorSpaceValue.toFloatArray();
+ Color color = new Color( colorSpace.createColorSpace(), components, 1f );
+ return color;
+ }
+
+ /**
+ * Constructor with an existing color set. Default colorspace is PDDeviceGray.
+ *
+ * @param csValues The color space values.
+ */
+ public PDColorSpaceInstance( COSArray csValues )
+ {
+ colorSpaceValue = csValues;
+ }
+
+
+ /**
+ * This will get the current colorspace.
+ *
+ * @return The current colorspace.
+ */
+ public PDColorSpace getColorSpace()
+ {
+ return colorSpace;
+ }
+
+ /**
+ * This will set the current colorspace.
+ *
+ * @param value The new colorspace.
+ */
+ public void setColorSpace(PDColorSpace value)
+ {
+ colorSpace = value;
+ }
+
+ /**
+ * This will get the color space values. Either 1 for gray or 3 for RGB.
+ *
+ * @return The colorspace values.
+ */
+ public float[] getColorSpaceValue()
+ {
+ return colorSpaceValue.toFloatArray();
+ }
+
+ /**
+ * This will get the color space values. Either 1 for gray or 3 for RGB.
+ *
+ * @return The colorspace values.
+ */
+ public COSArray getCOSColorSpaceValue()
+ {
+ return colorSpaceValue;
+ }
+
+ /**
+ * This will update the colorspace values.
+ *
+ * @param value The new colorspace values.
+ */
+ public void setColorSpaceValue(float[] value)
+ {
+ colorSpaceValue.setFloatArray( value );
+ }
+}
diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceCMYK.java b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceCMYK.java
new file mode 100644
index 0000000..dfbdfe5
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceCMYK.java
@@ -0,0 +1,137 @@
+/**
+ * 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.awt.color.ICC_Profile;
+import java.awt.image.ColorModel;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+import org.pdfbox.util.ResourceLoader;
+
+/**
+ * This class represents a CMYK color space.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.5 $
+ */
+public class PDDeviceCMYK extends PDColorSpace
+{
+ /**
+ * The single instance of this class.
+ */
+ public static final PDDeviceCMYK INSTANCE = new PDDeviceCMYK();
+
+ /**
+ * The name of this color space.
+ */
+ public static final String NAME = "DeviceCMYK";
+
+ /**
+ * The abbreviated name of this color space.
+ */
+ public static final String ABBREVIATED_NAME = "CMYK";
+
+ private ColorSpace cSpace = null;
+
+ private PDDeviceCMYK()
+ {
+
+ }
+
+ /**
+ * This will return the name of the color space.
+ *
+ * @return The name of the color space.
+ */
+ public String getName()
+ {
+ return NAME;
+ }
+
+ /**
+ * 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 4;
+ }
+
+ /**
+ * 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
+ {
+ if( cSpace == null )
+ {
+ InputStream profile = null;
+ try
+ {
+ profile = ResourceLoader.loadResource( "Resources/colorspace-profiles/CMYK.pf" );
+ ICC_Profile iccProfile = ICC_Profile.getInstance( profile );
+ cSpace = new ICC_ColorSpace( iccProfile );
+ }
+ finally
+ {
+ if( profile != null )
+ {
+ profile.close();
+ }
+ }
+ }
+ return cSpace;
+ }
+
+ /**
+ * 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" );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceGray.java b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceGray.java
new file mode 100644
index 0000000..a9afddb
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceGray.java
@@ -0,0 +1,112 @@
+/**
+ * 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.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.Transparency;
+
+import java.io.IOException;
+
+/**
+ * This class represents a Gray color space.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.5 $
+ */
+public class PDDeviceGray extends PDColorSpace
+{
+ /**
+ * The name of this color space.
+ */
+ public static final String NAME = "DeviceGray";
+
+ /**
+ * The abbreviated name of this color space.
+ */
+ public static final String ABBREVIATED_NAME = "G";
+
+ /**
+ * This will return the name of the color space.
+ *
+ * @return The name of the color space.
+ */
+ public String getName()
+ {
+ return NAME;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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
+ {
+ return ColorSpace.getInstance( ColorSpace.CS_GRAY );
+ }
+
+ /**
+ * 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
+ {
+ ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
+ int[] nBits = {bpc};
+ ColorModel colorModel = new ComponentColorModel(cs, nBits, false,false,
+ Transparency.OPAQUE,DataBuffer.TYPE_BYTE);
+ return colorModel;
+
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceN.java b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceN.java
new file mode 100644
index 0000000..92561e7
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceN.java
@@ -0,0 +1,244 @@
+/**
+ * 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.image.ColorModel;
+
+import java.io.IOException;
+
+import java.util.List;
+
+import org.pdfbox.cos.COSArray;
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSName;
+import org.pdfbox.cos.COSNull;
+
+import org.pdfbox.pdmodel.common.COSArrayList;
+
+/**
+ * This class represents a DeviceN color space.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.2 $
+ */
+public class PDDeviceN extends PDColorSpace
+{
+ /**
+ * The name of this color space.
+ */
+ public static final String NAME = "DeviceN";
+
+ private COSArray array;
+
+ /**
+ * Constructor.
+ */
+ public PDDeviceN()
+ {
+ array = new COSArray();
+ array.add( COSName.getPDFName( NAME ) );
+ array.add( COSName.getPDFName( "" ) );
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param separation The array containing all separation information.
+ */
+ public PDDeviceN( COSArray separation )
+ {
+ array = separation;
+ }
+
+ /**
+ * This will return the name of the color space. For a PDSeparation object
+ * this will always return "Separation"
+ *
+ * @return The name of the color space.
+ */
+ public String getName()
+ {
+ return NAME;
+ }
+
+ /**
+ * 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 getColorantNames().size();
+ }
+
+ /**
+ * 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" );
+ }
+
+ /**
+ * This will get the colorant names. A list of string objects.
+ *
+ * @return A list of colorants
+ */
+ public List getColorantNames()
+ {
+ COSArray names = (COSArray)array.getObject( 1 );
+ return COSArrayList.convertCOSNameCOSArrayToList( names );
+ }
+
+ /**
+ * This will set the list of colorants.
+ *
+ * @param names The list of colorant names.
+ */
+ public void setColorantNames( List names )
+ {
+ COSArray namesArray = COSArrayList.convertStringListToCOSNameCOSArray( names );
+ array.set( 1, namesArray );
+ }
+
+ /**
+ * This will get the alternate color space for this separation.
+ *
+ * @return The alternate color space.
+ *
+ * @throws IOException If there is an error getting the alternate color space.
+ */
+ public PDColorSpace getAlternateColorSpace() throws IOException
+ {
+ COSBase alternate = array.getObject( 2 );
+ return PDColorSpaceFactory.createColorSpace( alternate );
+ }
+
+ /**
+ * This will set the alternate color space.
+ *
+ * @param cs The alternate color space.
+ */
+ public void setAlternateColorSpace( PDColorSpace cs )
+ {
+ COSBase space = null;
+ if( cs != null )
+ {
+ space = cs.getCOSObject();
+ }
+ array.set( 2, space );
+ }
+
+ /**
+ * This will get the tint transform function. At this time the PDModel
+ * does not support functions so we will just return the COSBase object. This
+ * method will change in the future to be a PDModel object.
+ *
+ * @return The tint transform function.
+ */
+ public COSBase getTintTransform()
+ {
+ return array.get( 3 );
+ }
+
+ /**
+ * This will set the tint transform function. At this time the PDModel
+ * does not support functions so we will just return the COSBase object. This
+ * method will change in the future to be a PDModel object.
+ *
+ * @param tint The tint transform function.
+ */
+ public void setTintTransform( COSBase tint )
+ {
+ array.set( 3, tint );
+ }
+
+ /**
+ * This will get the attributes that are associated with the deviceN
+ * color space.
+ *
+ * @return The DeviceN attributes.
+ */
+ public PDDeviceNAttributes getAttributes()
+ {
+ PDDeviceNAttributes retval = null;
+ if( array.size() <5)
+ {
+ retval = new PDDeviceNAttributes();
+ setAttributes( retval );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set the color space attributes. If null is passed in then
+ * all attribute will be removed.
+ *
+ * @param attributes The color space attributes.
+ */
+ public void setAttributes( PDDeviceNAttributes attributes )
+ {
+ if( attributes == null )
+ {
+ array.remove( 4 );
+ }
+ else
+ {
+ //make sure array is large enough
+ while( array.size() < 5 )
+ {
+ array.add( COSNull.NULL );
+ }
+ array.set( 4, attributes.getCOSDictionary() );
+ }
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceNAttributes.java b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceNAttributes.java
new file mode 100644
index 0000000..00366df
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceNAttributes.java
@@ -0,0 +1,126 @@
+/**
+ * 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.COSDictionary;
+import org.pdfbox.cos.COSName;
+
+import org.pdfbox.pdmodel.common.COSDictionaryMap;
+
+import java.io.IOException;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * This class represents attributes for a DeviceN color space.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class PDDeviceNAttributes
+{
+ private COSDictionary dictionary;
+
+ /**
+ * Constructor.
+ */
+ public PDDeviceNAttributes()
+ {
+ dictionary = new COSDictionary();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param attributes A dictionary that has all of the attributes.
+ */
+ public PDDeviceNAttributes( COSDictionary attributes )
+ {
+ dictionary = attributes;
+ }
+
+ /**
+ * This will get the underlying cos dictionary.
+ *
+ * @return The dictionary that this object wraps.
+ */
+ public COSDictionary getCOSDictionary()
+ {
+ return dictionary;
+ }
+
+ /**
+ * This will get a map of colorants. See the PDF Reference for more details about
+ * this attribute. The map will contain a java.lang.String as the key, a colorant name,
+ * and a PDColorSpace as the value.
+ *
+ * @return The colorant map.
+ *
+ * @throws IOException If there is an error getting the colorspaces.
+ */
+ public Map getColorants() throws IOException
+ {
+ Map actuals = new HashMap();
+ COSDictionary colorants = (COSDictionary)dictionary.getDictionaryObject( COSName.getPDFName( "Colorants" ) );
+ if( colorants == null )
+ {
+ colorants = new COSDictionary();
+ dictionary.setItem( COSName.getPDFName( "Colorants" ), colorants );
+ }
+ Iterator iter = colorants.keyList().iterator();
+ while( iter.hasNext() )
+ {
+ COSName name = (COSName)iter.next();
+ COSBase value = colorants.getDictionaryObject( name );
+ actuals.put( name.getName(), PDColorSpaceFactory.createColorSpace( value ) );
+ }
+ return new COSDictionaryMap( actuals, colorants );
+ }
+
+ /**
+ * This will replace the existing colorant attribute. The key should be strings
+ * and the values should be PDColorSpaces.
+ *
+ * @param colorants The map of colorants.
+ */
+ public void setColorants( Map colorants )
+ {
+ COSDictionary colorantDict = null;
+ if( colorants != null )
+ {
+ colorantDict = COSDictionaryMap.convert( colorants );
+ }
+ dictionary.setItem( COSName.getPDFName( "Colorants" ), colorantDict );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceRGB.java b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceRGB.java
new file mode 100644
index 0000000..14c0dc3
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDDeviceRGB.java
@@ -0,0 +1,130 @@
+/**
+ * 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.Transparency;
+
+import java.awt.color.ColorSpace;
+
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+
+import java.io.IOException;
+
+/**
+ * This class represents an RGB color space.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.7 $
+ */
+public class PDDeviceRGB extends PDColorSpace
+{
+ /**
+ * The name of this color space.
+ */
+ public static final String NAME = "DeviceRGB";
+
+ /**
+ * The abbreviated name of this color space.
+ */
+ public static final String ABBREVIATED_NAME = "RGB";
+
+ /**
+ * This is the single instance of this class.
+ */
+ public static final PDDeviceRGB INSTANCE = new PDDeviceRGB();
+
+ /**
+ * This class is immutable.
+ */
+ private PDDeviceRGB()
+ {
+ //only here to make immutable.
+ }
+
+ /**
+ * This will return the name of the color space.
+ *
+ * @return The name of the color space.
+ */
+ public String getName()
+ {
+ return NAME;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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
+ {
+ return ColorSpace.getInstance( ColorSpace.CS_sRGB );
+ }
+
+ /**
+ * 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
+ {
+ int[] nbBits = { bpc, bpc, bpc };
+ ComponentColorModel componentColorModel =
+ new ComponentColorModel( createColorSpace(),
+ nbBits,
+ false,
+ false,
+ Transparency.OPAQUE,
+ DataBuffer.TYPE_BYTE );
+
+ return (ColorModel)componentColorModel;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/color/PDGamma.java b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDGamma.java
new file mode 100644
index 0000000..31fa82e
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDGamma.java
@@ -0,0 +1,151 @@
+/**
+ * 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.COSFloat;
+import org.pdfbox.cos.COSNumber;
+
+import org.pdfbox.pdmodel.common.COSObjectable;
+
+/**
+ * A gamma array, or collection of three floating point parameters used for
+ * color operations.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class PDGamma implements COSObjectable
+{
+ private COSArray values = null;
+
+ /**
+ * Constructor. Defaults all values to 0, 0, 0.
+ */
+ public PDGamma()
+ {
+ values = new COSArray();
+ values.add( new COSFloat( 0.0f ) );
+ values.add( new COSFloat( 0.0f ) );
+ values.add( new COSFloat( 0.0f ) );
+ }
+
+ /**
+ * Constructor from COS object.
+ *
+ * @param array The array containing the XYZ values.
+ */
+ public PDGamma( COSArray array )
+ {
+ values = array;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSBase getCOSObject()
+ {
+ return values;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSArray getCOSArray()
+ {
+ return values;
+ }
+
+ /**
+ * This will get the r value of the tristimulus.
+ *
+ * @return The R value.
+ */
+ public float getR()
+ {
+ return ((COSNumber)values.get( 0 )).floatValue();
+ }
+
+ /**
+ * This will set the r value of the tristimulus.
+ *
+ * @param r The r value for the tristimulus.
+ */
+ public void setR( float r )
+ {
+ values.set( 0, new COSFloat( r ) );
+ }
+
+ /**
+ * This will get the g value of the tristimulus.
+ *
+ * @return The g value.
+ */
+ public float getG()
+ {
+ return ((COSNumber)values.get( 1 )).floatValue();
+ }
+
+ /**
+ * This will set the g value of the tristimulus.
+ *
+ * @param g The g value for the tristimulus.
+ */
+ public void setG( float g )
+ {
+ values.set( 1, new COSFloat( g ) );
+ }
+
+ /**
+ * This will get the b value of the tristimulus.
+ *
+ * @return The B value.
+ */
+ public float getB()
+ {
+ return ((COSNumber)values.get( 2 )).floatValue();
+ }
+
+ /**
+ * This will set the b value of the tristimulus.
+ *
+ * @param b The b value for the tristimulus.
+ */
+ public void setB( float b )
+ {
+ values.set( 2, new COSFloat( b ) );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/color/PDICCBased.java b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDICCBased.java
new file mode 100644
index 0000000..d8189d0
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDICCBased.java
@@ -0,0 +1,343 @@
+/**
+ * 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.COSInteger;
+import org.pdfbox.cos.COSFloat;
+import org.pdfbox.cos.COSName;
+import org.pdfbox.cos.COSNumber;
+import org.pdfbox.cos.COSStream;
+
+import org.pdfbox.pdmodel.PDDocument;
+import org.pdfbox.pdmodel.common.COSArrayList;
+import org.pdfbox.pdmodel.common.PDRange;
+import org.pdfbox.pdmodel.common.PDStream;
+
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.color.ICC_ColorSpace;
+import java.awt.color.ICC_Profile;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class represents a ICC profile color space.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.5 $
+ */
+public class PDICCBased extends PDColorSpace
+{
+ /**
+ * The name of this color space.
+ */
+ public static final String NAME = "ICCBased";
+
+ private COSArray array;
+ private PDStream stream;
+
+ /**
+ * Default constructor, creates empty stream.
+ *
+ * @param doc The document to store the icc data.
+ */
+ public PDICCBased( PDDocument doc )
+ {
+ array = new COSArray();
+ array.add( COSName.getPDFName( NAME ) );
+ array.add( new PDStream( doc ) );
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param iccArray The ICC stream object.
+ */
+ public PDICCBased( COSArray iccArray )
+ {
+ array = iccArray;
+ stream = new PDStream( (COSStream)iccArray.getObject( 1 ) );
+ }
+
+ /**
+ * This will return the name of the color space.
+ *
+ * @return The name of the color space.
+ */
+ public String getName()
+ {
+ return NAME;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSBase getCOSObject()
+ {
+ return array;
+ }
+
+ /**
+ * Get the pd stream for this icc color space.
+ *
+ * @return Get the stream for this icc based color space.
+ */
+ public PDStream getPDStream()
+ {
+ return stream;
+ }
+
+ /**
+ * 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
+ {
+ InputStream profile = null;
+ ColorSpace cSpace = null;
+ try
+ {
+ profile = stream.createInputStream();
+ ICC_Profile iccProfile = ICC_Profile.getInstance( profile );
+ cSpace = new ICC_ColorSpace( iccProfile );
+ }
+ finally
+ {
+ if( profile != null )
+ {
+ profile.close();
+ }
+ }
+ return cSpace;
+ }
+
+ /**
+ * 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
+ {
+ int[] nbBits = { bpc, bpc, bpc };
+ ComponentColorModel componentColorModel =
+ new ComponentColorModel( createColorSpace(),
+ nbBits,
+ false,
+ false,
+ Transparency.OPAQUE,
+ DataBuffer.TYPE_BYTE );
+
+ return componentColorModel;
+ }
+
+ /**
+ * This will return the number of color components. As of PDF 1.4 this will
+ * be 1,3,4.
+ *
+ * @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
+ {
+ COSNumber n = (COSNumber)stream.getStream().getDictionaryObject( COSName.getPDFName( "N" ) );
+ return n.intValue();
+ }
+
+ /**
+ * This will set the number of color components.
+ *
+ * @param n The number of color components.
+ */
+ public void setNumberOfComponents( int n )
+ {
+ stream.getStream().setItem( COSName.getPDFName( "N" ), new COSInteger( n ) );
+ }
+
+ /**
+ * This will return a list of alternate color spaces(PDColorSpace) if the display application
+ * does not support this icc stream.
+ *
+ * @return A list of alternate color spaces.
+ *
+ * @throws IOException If there is an error getting the alternate color spaces.
+ */
+ public List getAlternateColorSpaces() throws IOException
+ {
+ COSBase alternate = stream.getStream().getDictionaryObject( COSName.getPDFName( "Alternate" ) );
+ COSArray alternateArray = null;
+ if( alternate == null )
+ {
+ alternateArray = new COSArray();
+ int numComponents = getNumberOfComponents();
+ String csName = null;
+ if( numComponents == 1 )
+ {
+ csName = PDDeviceGray.NAME;
+ }
+ else if( numComponents == 3 )
+ {
+ csName = PDDeviceRGB.NAME;
+ }
+ else if( numComponents == 4 )
+ {
+ csName = PDDeviceCMYK.NAME;
+ }
+ else
+ {
+ throw new IOException( "Unknown colorspace number of components:" + numComponents );
+ }
+ alternateArray.add( COSName.getPDFName( csName ) );
+ }
+ else
+ {
+ if( alternate instanceof COSArray )
+ {
+ alternateArray = (COSArray)alternate;
+ }
+ else if( alternate instanceof COSName )
+ {
+ alternateArray = new COSArray();
+ alternateArray.add( alternate );
+ }
+ else
+ {
+ throw new IOException( "Error: expected COSArray or COSName and not " +
+ alternate.getClass().getName() );
+ }
+ }
+ List retval = new ArrayList();
+ for( int i=0; i<alternateArray.size(); i++ )
+ {
+ retval.add( PDColorSpaceFactory.createColorSpace( alternateArray.get( i ) ) );
+ }
+ return new COSArrayList( retval, alternateArray );
+ }
+
+ /**
+ * This will set the list of alternate color spaces. This should be a list
+ * of PDColorSpace objects.
+ *
+ * @param list The list of colorspace objects.
+ */
+ public void setAlternateColorSpaces( List list )
+ {
+ COSArray altArray = null;
+ if( list != null )
+ {
+ altArray = COSArrayList.converterToCOSArray( list );
+ }
+ stream.getStream().setItem( COSName.getPDFName( "Alternate" ), altArray );
+ }
+
+ private COSArray getRangeArray( int n )
+ {
+ COSArray rangeArray = (COSArray)stream.getStream().getDictionaryObject( COSName.getPDFName( "Range" ) );
+ if( rangeArray == null )
+ {
+ rangeArray = new COSArray();
+ stream.getStream().setItem( COSName.getPDFName( "Range" ), rangeArray );
+ while( rangeArray.size() < n*2 )
+ {
+ rangeArray.add( new COSFloat( -100 ) );
+ rangeArray.add( new COSFloat( 100 ) );
+ }
+ }
+ return rangeArray;
+ }
+
+ /**
+ * This will get the range for a certain component number. This is will never
+ * return null. If it is not present then the range -100 to 100 will
+ * be returned.
+ *
+ * @param n The component number to get the range for.
+ *
+ * @return The range for this component.
+ */
+ public PDRange getRangeForComponent( int n )
+ {
+ COSArray rangeArray = getRangeArray( n );
+ return new PDRange( rangeArray, n );
+ }
+
+ /**
+ * This will set the a range for this color space.
+ *
+ * @param range The new range for the a component.
+ * @param n The component to set the range for.
+ */
+ public void setRangeForComponent( PDRange range, int n )
+ {
+ COSArray rangeArray = getRangeArray( n );
+ rangeArray.set( n*2, new COSFloat( range.getMin() ) );
+ rangeArray.set( n*2+1, new COSFloat( range.getMax() ) );
+ }
+
+ /**
+ * This will get the metadata stream for this object. Null if there is no
+ * metadata stream.
+ *
+ * @return The metadata stream, if it exists.
+ */
+ public COSStream getMetadata()
+ {
+ return (COSStream)stream.getStream().getDictionaryObject( COSName.getPDFName( "Metadata" ) );
+ }
+
+ /**
+ * This will set the metadata stream that is associated with this color space.
+ *
+ * @param metadata The new metadata stream.
+ */
+ public void setMetadata( COSStream metadata )
+ {
+ stream.getStream().setItem( COSName.getPDFName( "Metadata" ), metadata );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/color/PDIndexed.java b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDIndexed.java
new file mode 100644
index 0000000..cd1d9e7
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDIndexed.java
@@ -0,0 +1,271 @@
+/**
+ * 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.COSInteger;
+import org.pdfbox.cos.COSName;
+import org.pdfbox.cos.COSNumber;
+import org.pdfbox.cos.COSStream;
+import org.pdfbox.cos.COSString;
+
+import java.awt.color.ColorSpace;
+import java.awt.image.ColorModel;
+import java.awt.image.IndexColorModel;
+
+import java.io.InputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+/**
+ * This class represents an Indexed color space.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.3 $
+ */
+public class PDIndexed extends PDColorSpace
+{
+
+ /**
+ * The name of this color space.
+ */
+ public static final String NAME = "Indexed";
+
+ /**
+ * The abbreviated name of this color space.
+ */
+ public static final String ABBREVIATED_NAME = "I";
+
+ private COSArray array;
+
+ /**
+ * Constructor, default DeviceRGB, hival 255.
+ */
+ public PDIndexed()
+ {
+ array = new COSArray();
+ array.add( COSName.getPDFName( NAME ) );
+ array.add( COSName.getPDFName( PDDeviceRGB.NAME ) );
+ array.add( new COSInteger( 255 ) );
+ array.add( org.pdfbox.cos.COSNull.NULL );
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param indexedArray The array containing the indexed parameters
+ */
+ public PDIndexed( COSArray indexedArray )
+ {
+ array = indexedArray;
+ }
+
+ /**
+ * This will return the number of color components. This will return the
+ * number of color components in the base color.
+ *
+ * @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 getBaseColorSpace().getNumberOfComponents();
+ }
+
+ /**
+ * 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
+ {
+ int size = getHighValue();
+ byte[] index = getLookupData();
+ //for (int i=0;i<index.length;i++) System.out.print(index[i]+" ");
+
+ ColorModel cm = new IndexColorModel(bpc, size+1, index,0,false);
+ return cm;
+ }
+
+ /**
+ * This will get the color space that acts as the index for this color space.
+ *
+ * @return The base color space.
+ *
+ * @throws IOException If there is error creating the base color space.
+ */
+ public PDColorSpace getBaseColorSpace() throws IOException
+ {
+ PDColorSpace retval = null;
+ COSBase base = array.getObject( 1 );
+ if( base instanceof COSName )
+ {
+ retval = PDColorSpaceFactory.createColorSpace( (COSName)base );
+ }
+ else
+ {
+ throw new IOException( "Error:unknown base colorspace" );
+ }
+
+ return retval;
+ }
+
+ /**
+ * This will set the base color space.
+ *
+ * @param base The base color space to use as the index.
+ */
+ public void setBaseColorSpace( PDColorSpace base )
+ {
+ array.set( 1, base.getCOSObject() );
+ }
+
+ /**
+ * Get the highest value for the lookup.
+ *
+ * @return The hival entry.
+ */
+ public int getHighValue()
+ {
+ return ((COSNumber)array.getObject( 2 )).intValue();
+ }
+
+ /**
+ * This will set the highest value that is allowed. This cannot be higher
+ * than 255.
+ *
+ * @param high The highest value for the lookup table.
+ */
+ public void setHighValue( int high )
+ {
+ array.set( 2, new COSInteger( high ) );
+ }
+
+ /**
+ * This will perform a lookup into the color lookup table.
+ *
+ * @param componentNumber The component number, probably 1,2,3,3.
+ * @param lookupIndex The zero-based index into the table, should not exceed the high value.
+ *
+ * @return The value that was from the lookup table.
+ *
+ * @throws IOException If there is an error looking up the color.
+ */
+ public int lookupColor( int componentNumber, int lookupIndex ) throws IOException
+ {
+ COSBase lookupTable = array.getObject( 3 );
+ PDColorSpace baseColor = getBaseColorSpace();
+ byte[] data = getLookupData();
+ int numberOfComponents = baseColor.getNumberOfComponents();
+ return (data[componentNumber*numberOfComponents + lookupIndex]+256)%256;
+ }
+
+ private byte[] getLookupData() throws IOException
+ {
+ COSBase lookupTable = array.getObject( 3 );
+ byte[] data = null;
+ if( lookupTable instanceof COSString )
+ {
+ data = ((COSString)lookupTable).getBytes();
+ }
+ else if( lookupTable instanceof COSStream )
+ {
+ //Data will be small so just load the whole thing into memory for
+ //easier processing
+ COSStream lookupStream = (COSStream)lookupTable;
+ InputStream input = lookupStream.getUnfilteredStream();
+ ByteArrayOutputStream output = new ByteArrayOutputStream(1024);
+ byte[] buffer = new byte[ 1024 ];
+ int amountRead;
+ while( (amountRead = input.read(buffer, 0, buffer.length)) != -1 )
+ {
+ output.write( buffer, 0, amountRead );
+ }
+ data = output.toByteArray();
+ }
+ else if( lookupTable == null )
+ {
+ data = new byte[0];
+ }
+ else
+ {
+ throw new IOException( "Error: Unknown type for lookup table " + lookupTable );
+ }
+ return data;
+ }
+
+ /**
+ * This will set a color in the color lookup table.
+ *
+ * @param componentNumber The component number, probably 1,2,3,3.
+ * @param lookupIndex The zero-based index into the table, should not exceed the high value.
+ * @param color The color that will go into the table.
+ *
+ * @throws IOException If there is an error looking up the color.
+ */
+ public void setLookupColor( int componentNumber, int lookupIndex, int color ) throws IOException
+ {
+ PDColorSpace baseColor = getBaseColorSpace();
+ int numberOfComponents = baseColor.getNumberOfComponents();
+ byte[] data = getLookupData();
+ data[componentNumber*numberOfComponents + lookupIndex] = (byte)color;
+ COSString string = new COSString( data );
+ array.set( 3, string );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/color/PDLab.java b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDLab.java
new file mode 100644
index 0000000..9bd3220
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDLab.java
@@ -0,0 +1,300 @@
+/**
+ * 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.PDRange;
+
+import java.awt.color.ColorSpace;
+import java.awt.image.ColorModel;
+
+import java.io.IOException;
+
+/**
+ * This class represents a Lab color space.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.2 $
+ */
+public class PDLab extends PDColorSpace
+{
+ /**
+ * The name of this color space.
+ */
+ public static final String NAME = "Lab";
+
+ private COSArray array;
+ private COSDictionary dictionary;
+
+ /**
+ * Constructor.
+ */
+ public PDLab()
+ {
+ array = new COSArray();
+ dictionary = new COSDictionary();
+ array.add( COSName.getPDFName( NAME ) );
+ array.add( dictionary );
+ }
+
+ /**
+ * Constructor with array.
+ *
+ * @param lab The underlying color space.
+ */
+ public PDLab( COSArray lab )
+ {
+ array = lab;
+ dictionary = (COSDictionary)array.getObject( 1 );
+ }
+
+ /**
+ * This will return the name of the color space.
+ *
+ * @return The name of the color space.
+ */
+ public String getName()
+ {
+ return NAME;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSBase getCOSObject()
+ {
+ return array;
+ }
+
+ /**
+ * 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" );
+ }
+
+ /**
+ * 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
+ {
+ //BJL
+ //hmm is this correct, I am not 100% sure.
+ return 3;
+ }
+
+ /**
+ * 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 );
+ }
+
+ private COSArray getRangeArray()
+ {
+ COSArray range = (COSArray)dictionary.getDictionaryObject( COSName.getPDFName( "Range" ) );
+ if( range == null )
+ {
+ range = new COSArray();
+ dictionary.setItem( COSName.getPDFName( "Range" ), array );
+ range.add( new COSFloat( -100 ) );
+ range.add( new COSFloat( 100 ) );
+ range.add( new COSFloat( -100 ) );
+ range.add( new COSFloat( 100 ) );
+ }
+ return range;
+ }
+
+ /**
+ * This will get the valid range for the a component. If none is found
+ * then the default will be returned, which is -100 to 100.
+ *
+ * @return The a range.
+ */
+ public PDRange getARange()
+ {
+ COSArray range = getRangeArray();
+ return new PDRange( range, 0 );
+ }
+
+ /**
+ * This will set the a range for this color space.
+ *
+ * @param range The new range for the a component.
+ */
+ public void setARange( PDRange range )
+ {
+ COSArray rangeArray = null;
+ //if null then reset to defaults
+ if( range == null )
+ {
+ rangeArray = getRangeArray();
+ rangeArray.set( 0, new COSFloat( -100 ) );
+ rangeArray.set( 1, new COSFloat( 100 ) );
+ }
+ else
+ {
+ rangeArray = range.getCOSArray();
+ }
+ dictionary.setItem( COSName.getPDFName( "Range" ), rangeArray );
+ }
+
+ /**
+ * This will get the valid range for the b component. If none is found
+ * then the default will be returned, which is -100 to 100.
+ *
+ * @return The b range.
+ */
+ public PDRange getBRange()
+ {
+ COSArray range = getRangeArray();
+ return new PDRange( range, 2 );
+ }
+
+ /**
+ * This will set the b range for this color space.
+ *
+ * @param range The new range for the b component.
+ */
+ public void setBRange( PDRange range )
+ {
+ COSArray rangeArray = null;
+ //if null then reset to defaults
+ if( range == null )
+ {
+ rangeArray = getRangeArray();
+ rangeArray.set( 2, new COSFloat( -100 ) );
+ rangeArray.set( 3, new COSFloat( 100 ) );
+ }
+ else
+ {
+ rangeArray = range.getCOSArray();
+ }
+ dictionary.setItem( COSName.getPDFName( "Range" ), rangeArray );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/color/PDPattern.java b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDPattern.java
new file mode 100644
index 0000000..4c43914
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDPattern.java
@@ -0,0 +1,122 @@
+/**
+ * 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.COSName;
+
+import java.awt.color.ColorSpace;
+import java.awt.image.ColorModel;
+
+import java.io.IOException;
+
+/**
+ * This class represents a Pattern color space.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.3 $
+ */
+public class PDPattern extends PDColorSpace
+{
+ private COSArray array;
+
+ /**
+ * The name of this color space.
+ */
+ public static final String NAME = "Pattern";
+
+ /**
+ * Default constructor.
+ */
+ public PDPattern()
+ {
+ array = new COSArray();
+ array.add( COSName.getPDFName( NAME ) );
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param pattern The pattern array.
+ */
+ public PDPattern( COSArray pattern)
+ {
+ array = pattern;
+ }
+
+ /**
+ * This will return the name of the color space.
+ *
+ * @return The name of the color space.
+ */
+ public String getName()
+ {
+ return NAME;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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" );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/color/PDSeparation.java b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDSeparation.java
new file mode 100644
index 0000000..cc92f6f
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDSeparation.java
@@ -0,0 +1,198 @@
+/**
+ * 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.image.ColorModel;
+
+import java.io.IOException;
+
+import org.pdfbox.cos.COSArray;
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSName;
+
+/**
+ * This class represents a Separation color space.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.2 $
+ */
+public class PDSeparation extends PDColorSpace
+{
+ /**
+ * The name of this color space.
+ */
+ public static final String NAME = "Separation";
+
+ private COSArray array;
+
+ /**
+ * Constructor.
+ */
+ public PDSeparation()
+ {
+ array = new COSArray();
+ array.add( COSName.getPDFName( NAME ) );
+ array.add( COSName.getPDFName( "" ) );
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param separation The array containing all separation information.
+ */
+ public PDSeparation( COSArray separation )
+ {
+ array = separation;
+ }
+
+ /**
+ * This will return the name of the color space. For a PDSeparation object
+ * this will always return "Separation"
+ *
+ * @return The name of the color space.
+ */
+ public String getName()
+ {
+ return NAME;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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" );
+ }
+
+ /**
+ * This will get the separation name.
+ *
+ * @return The name in the separation.
+ */
+ public String getColorantName()
+ {
+ COSName name = (COSName)array.getObject( 1 );
+ return name.getName();
+ }
+
+ /**
+ * This will set the separation name.
+ *
+ * @param name The separation name.
+ */
+ public void setColorantName( String name )
+ {
+ array.set( 1, COSName.getPDFName( name ) );
+ }
+
+ /**
+ * This will get the alternate color space for this separation.
+ *
+ * @return The alternate color space.
+ *
+ * @throws IOException If there is an error getting the alternate color space.
+ */
+ public PDColorSpace getAlternateColorSpace() throws IOException
+ {
+ COSBase alternate = array.getObject( 2 );
+ return PDColorSpaceFactory.createColorSpace( alternate );
+ }
+
+ /**
+ * This will set the alternate color space.
+ *
+ * @param cs The alternate color space.
+ */
+ public void setAlternateColorSpace( PDColorSpace cs )
+ {
+ COSBase space = null;
+ if( cs != null )
+ {
+ space = cs.getCOSObject();
+ }
+ array.set( 2, space );
+ }
+
+ /**
+ * This will get the tint transform function. At this time the PDModel
+ * does not support functions so we will just return the COSBase object. This
+ * method will change in the future to be a PDModel object.
+ *
+ * @return The tint transform function.
+ */
+ public COSBase getTintTransform()
+ {
+ return array.get( 3 );
+ }
+
+ /**
+ * This will set the tint transform function. At this time the PDModel
+ * does not support functions so we will just return the COSBase object. This
+ * method will change in the future to be a PDModel object.
+ *
+ * @param tint The tint transform function.
+ */
+ public void setTintTransform( COSBase tint )
+ {
+ array.set( 3, tint );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/color/PDTristimulus.java b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDTristimulus.java
new file mode 100644
index 0000000..296b147
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/graphics/color/PDTristimulus.java
@@ -0,0 +1,155 @@
+/**
+ * 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.COSFloat;
+import org.pdfbox.cos.COSNumber;
+
+import org.pdfbox.pdmodel.common.COSObjectable;
+
+/**
+ * A tristimulus, or collection of three floating point parameters used for
+ * color operations.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class PDTristimulus implements COSObjectable
+{
+ private COSArray values = null;
+
+ /**
+ * Constructor. Defaults all values to 0, 0, 0.
+ */
+ public PDTristimulus()
+ {
+ values = new COSArray();
+ values.add( new COSFloat( 0.0f ) );
+ values.add( new COSFloat( 0.0f ) );
+ values.add( new COSFloat( 0.0f ) );
+ }
+
+ /**
+ * Constructor from COS object.
+ *
+ * @param array The array containing the XYZ values.
+ */
+ public PDTristimulus( COSArray array )
+ {
+ values = array;
+ }
+
+ /**
+ * Constructor from COS object.
+ *
+ * @param array The array containing the XYZ values.
+ */
+ public PDTristimulus( float[] array )
+ {
+ values = new COSArray();
+ for( int i=0; i<array.length && i<3; i++ )
+ {
+ values.add( new COSFloat( array[i] ) );
+ }
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSBase getCOSObject()
+ {
+ return values;
+ }
+
+ /**
+ * This will get the x value of the tristimulus.
+ *
+ * @return The X value.
+ */
+ public float getX()
+ {
+ return ((COSNumber)values.get( 0 )).floatValue();
+ }
+
+ /**
+ * This will set the x value of the tristimulus.
+ *
+ * @param x The x value for the tristimulus.
+ */
+ public void setX( float x )
+ {
+ values.set( 0, new COSFloat( x ) );
+ }
+
+ /**
+ * This will get the y value of the tristimulus.
+ *
+ * @return The Y value.
+ */
+ public float getY()
+ {
+ return ((COSNumber)values.get( 1 )).floatValue();
+ }
+
+ /**
+ * This will set the y value of the tristimulus.
+ *
+ * @param y The y value for the tristimulus.
+ */
+ public void setY( float y )
+ {
+ values.set( 1, new COSFloat( y ) );
+ }
+
+ /**
+ * This will get the z value of the tristimulus.
+ *
+ * @return The Z value.
+ */
+ public float getZ()
+ {
+ return ((COSNumber)values.get( 2 )).floatValue();
+ }
+
+ /**
+ * This will set the z value of the tristimulus.
+ *
+ * @param z The z value for the tristimulus.
+ */
+ public void setZ( float z )
+ {
+ values.set( 2, new COSFloat( z ) );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/color/package.html b/src/main/java/org/pdfbox/pdmodel/graphics/color/package.html
new file mode 100644
index 0000000..733efff
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/graphics/color/package.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+
+</head>
+<body>
+This package deals with colors that are stored in a PDF document.
+</body>
+</html> \ 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 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+
+</head>
+<body>
+The PDModel graphics package deals with graphics states, operations, and parameters within the PDF document.
+</body>
+</html>
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.
+ *
+ * <code>average(i,j) = raw(i,j) + (raw(i-1,j)+raw(i,j-1)/2</code>
+ *
+ * decoding
+ *
+ * <code>raw(i,j) = avarage(i,j) - (raw(i-1,j)+raw(i,j-1)/2</code>
+ *
+ * @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.
+ *
+ * <code>None(i,j) = Raw(i,j)</code>
+ *
+ * <code>Raw(i,j) = None(i,j)</code>
+ *
+ * @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:
+ *
+ * <code>Paeth(i,j) = Raw(i,j) - PaethPredictor(Raw(i-1,j), Raw(i,j-1), Raw(i-1,j-1))</code>
+ *
+ * To decode the Paeth filter
+ *
+ * <code>Raw(i,j) = Paeth(i,j) - PaethPredictor(Raw(i-1,j), Raw(i,j-1), Raw(i-1,j-1))</code>
+ *
+ * @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
+ * <ul>
+ * <li>1 No prediction (the default value)
+ * <li>2 TIFF Predictor 2
+ * <li>10 PNG prediction (on encoding, PNG None on all rows)
+ * <li>11 PNG prediction (on encoding, PNG Sub on all rows)
+ * <li>12 PNG prediction (on encoding, PNG Up on all rows)
+ * <li>13 PNG prediction (on encoding, PNG Average on all rows)
+ * <li>14 PNG prediction (on encoding, PNG Paeth on all rows)
+ * <li>15 PNG prediction (on encoding, PNG optimum)
+ * </ul>
+ *
+ * @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.
+ *
+ * <code>Sub(i,j) = Raw(i,j) - Raw(i-1,j)</code>
+ *
+ * <code>Raw(i,j) = Sub(i,j) + Raw(i-1,j)</code>
+ *
+ * @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.
+ *
+ * <code>Up(i,j) = Raw(i,j) - Raw(i,j-1)</code>
+ *
+ * <code>Raw(i,j) = Up(i,j) + Raw(i,j-1)</code>
+ *
+ * @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 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+
+</head>
+<body>
+The predictor package contains code for different PNG predictor algorithms that
+are present in PDF documents. These classes are used internally by PDFBox.
+</body>
+</html>
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<filters.size(); i++ )
+ {
+ out.reset();
+ Filter filter = filterManager.getFilter( (String)filters.get( i ) );
+ filter.decode( in, out, params.getDictionary() );
+ in = new ByteArrayInputStream( out.toByteArray() );
+ }
+ finalData = out.toByteArray();
+ }
+
+ WritableRaster raster = colorModel.createCompatibleWritableRaster( params.getWidth(), params.getHeight() );
+ /* Raster.createPackedRaster(
+ buffer,
+ params.getWidth(),
+ params.getHeight(),
+ params.getBitsPerComponent(),
+ new Point(0,0) );
+ */
+ DataBuffer rasterBuffer = raster.getDataBuffer();
+ if( rasterBuffer instanceof DataBufferByte )
+ {
+ DataBufferByte byteBuffer = (DataBufferByte)rasterBuffer;
+ byte[] data = byteBuffer.getData();
+ System.arraycopy( finalData, 0, data, 0, data.length );
+ }
+ else if( rasterBuffer instanceof DataBufferInt )
+ {
+ DataBufferInt byteBuffer = (DataBufferInt)rasterBuffer;
+ int[] data = byteBuffer.getData();
+ for( int i=0; i<finalData.length; i++ )
+ {
+ data[i] = (finalData[i]+256)%256;
+ }
+ }
+ BufferedImage image = new BufferedImage(
+ colorModel, raster, false, null );
+ image.setData( raster );
+ return image;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDJpeg.java b/src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDJpeg.java
new file mode 100644
index 0000000..79ee8e8
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDJpeg.java
@@ -0,0 +1,156 @@
+/**
+ * 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.xobject;
+
+import java.awt.image.BufferedImage;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+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.PDDeviceRGB;
+
+/**
+ * An image class for JPegs.
+ *
+ * @author mathiak
+ * @version $Revision: 1.4 $
+ */
+public class PDJpeg extends PDXObjectImage
+{
+
+ private static final List DCT_FILTERS = new ArrayList();
+
+ static
+ {
+ DCT_FILTERS.add( COSName.DCT_DECODE.getName() );
+ DCT_FILTERS.add( COSName.DCT_DECODE_ABBREVIATION.getName() );
+ }
+
+ /**
+ * Standard constructor.
+ *
+ * @param jpeg The COSStream from which to extract the JPeg
+ */
+ public PDJpeg(PDStream jpeg)
+ {
+ super(jpeg, "jpg");
+ }
+
+ /**
+ * Construct from a stream.
+ *
+ * @param doc The document to create the image as part of.
+ * @param is The stream that contains the jpeg data.
+ * @throws IOException If there is an error reading the jpeg data.
+ */
+ public PDJpeg( PDDocument doc, InputStream is ) throws IOException
+ {
+ super( new PDStream( doc, is, true ), "jpg" );
+ COSDictionary dic = getCOSStream();
+ dic.setItem( COSName.FILTER, COSName.DCT_DECODE );
+ dic.setItem( COSName.SUBTYPE, COSName.IMAGE);
+ dic.setItem( COSName.TYPE, COSName.getPDFName( "XObject" ) );
+
+ BufferedImage image = getRGBImage();
+ setBitsPerComponent( 8 );
+ setColorSpace( PDDeviceRGB.INSTANCE );
+ setHeight( image.getHeight() );
+ setWidth( image.getWidth() );
+
+ }
+
+ /**
+ * Construct from a buffered image.
+ *
+ * @param doc The document to create the image as part of.
+ * @param bi The image to convert to a jpeg
+ * @throws IOException If there is an error processing the jpeg data.
+ */
+ public PDJpeg( PDDocument doc, BufferedImage bi ) throws IOException
+ {
+ super( new PDStream( doc ), "jpg" );
+
+ java.io.OutputStream os = getCOSStream().createFilteredStream();
+ try
+ {
+
+ ImageIO.write(bi,"jpeg",os);
+
+ COSDictionary dic = getCOSStream();
+ dic.setItem( COSName.FILTER, COSName.DCT_DECODE );
+ dic.setItem( COSName.SUBTYPE, COSName.IMAGE);
+ dic.setItem( COSName.TYPE, COSName.getPDFName( "XObject" ) );
+
+ setBitsPerComponent( 8 );
+ setColorSpace( PDDeviceRGB.INSTANCE );
+ setHeight( bi.getHeight() );
+ setWidth( bi.getWidth() );
+ }
+ finally
+ {
+ os.close();
+ }
+ }
+
+ /**
+ * Returns an image of the JPeg, or null if JPegs are not supported. (They should be. )
+ * @see org.pdfbox.pdmodel.graphics.xobject.PDXObjectImage#getRGBImage()
+ */
+ public BufferedImage getRGBImage() throws IOException
+ {
+ return ImageIO.read(getPDStream().getPartiallyFilteredStream( DCT_FILTERS ));
+ }
+
+ /**
+ * This writes the JPeg to out.
+ * @see org.pdfbox.pdmodel.graphics.xobject.PDXObjectImage#write2OutputStream(java.io.OutputStream)
+ */
+ public void write2OutputStream(OutputStream out) throws IOException
+ {
+ InputStream data = getPDStream().getPartiallyFilteredStream( DCT_FILTERS );
+ byte[] buf = new byte[1024];
+ int amountRead = -1;
+ while( (amountRead = data.read( buf )) != -1 )
+ {
+ out.write( buf, 0, amountRead );
+ }
+ }
+}
diff --git a/src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDPixelMap.java b/src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDPixelMap.java
new file mode 100644
index 0000000..96a1f29
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/graphics/xobject/PDPixelMap.java
@@ -0,0 +1,236 @@
+/**
+ * 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.DataBufferByte;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.WritableRaster;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.imageio.ImageIO;
+
+import org.pdfbox.cos.COSArray;
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSDictionary;
+import org.pdfbox.pdmodel.common.PDStream;
+
+import org.pdfbox.pdmodel.graphics.color.PDColorSpace;
+import org.pdfbox.pdmodel.graphics.predictor.PredictorAlgorithm;
+
+/**
+ * This class contains a PixelMap Image.
+ * @author Ben Litchfield (ben@benlitchfield.com)
+ * @author mathiak
+ * @version $Revision: 1.7 $
+ */
+public class PDPixelMap extends PDXObjectImage
+{
+ private BufferedImage image = null;
+
+ /**
+ * Standard constructor. Basically does nothing.
+ * @param pdStream The stream that holds the pixel map.
+ */
+ public PDPixelMap(PDStream pdStream)
+ {
+ super(pdStream, "png");
+ }
+
+ /**
+ * Construct a pixel map image from an AWT image.
+ *
+ * @param doc The PDF document to embed the image in.
+ * @param awtImage The image to read data from.
+ *
+ * @throws IOException If there is an error while embedding this image.
+ */
+ /*
+ * This method is broken and needs to be implemented, any takers?
+ public PDPixelMap(PDDocument doc, BufferedImage awtImage) throws IOException
+ {
+ super( doc, "png");
+ image = awtImage;
+ setWidth( image.getWidth() );
+ setHeight( image.getHeight() );
+
+ ColorModel cm = image.getColorModel();
+ ColorSpace cs = cm.getColorSpace();
+ PDColorSpace pdColorSpace = PDColorSpaceFactory.createColorSpace( doc, cs );
+ setColorSpace( pdColorSpace );
+ //setColorSpace( )
+
+ PDStream stream = getPDStream();
+ OutputStream output = null;
+ try
+ {
+ output = stream.createOutputStream();
+ DataBuffer buffer = awtImage.getRaster().getDataBuffer();
+ if( buffer instanceof DataBufferByte )
+ {
+ DataBufferByte byteBuffer = (DataBufferByte)buffer;
+ byte[] data = byteBuffer.getData();
+ output.write( data );
+ }
+ setBitsPerComponent( cm.getPixelSize() );
+ }
+ finally
+ {
+ if( output != null )
+ {
+ output.close();
+ }
+ }
+ }*/
+
+ /**
+ * Returns a {@link java.awt.image.BufferedImage} of the COSStream
+ * set in the constructor or null if the COSStream could not be encoded.
+ *
+ * @see org.pdfbox.pdmodel.graphics.xobject.PDXObjectImage#getRGBImage()
+ */
+ public BufferedImage getRGBImage() throws IOException
+ {
+ if( image != null )
+ {
+ return image;
+ }
+
+ //byte[] index =
+ //ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+ int width = getWidth();
+ int height = getHeight();
+ int bpc = getBitsPerComponent();
+ //COSInteger length =
+ // (COSInteger) stream.getStream().getDictionary().getDictionaryObject(COSName.LENGTH);
+ //byte[] array = new byte[stream.getFilteredStream().];
+ byte[] array = getPDStream().getByteArray();
+
+// Get the ColorModel right
+ PDColorSpace colorspace = getColorSpace();
+ ColorModel cm = colorspace.createColorModel( bpc );
+ WritableRaster raster = cm.createCompatibleWritableRaster( width, height );
+ //DataBufferByte buffer = (DataBufferByte)raster.getDataBuffer();
+ DataBufferByte buffer = (DataBufferByte)raster.getDataBuffer();
+ byte[] bufferData = buffer.getData();
+ //System.arraycopy( array, 0, bufferData, 0, array.length );
+ int predictor = getPredictor();
+
+ PredictorAlgorithm filter = PredictorAlgorithm.getFilter(predictor);
+ filter.setWidth(width);
+ filter.setHeight(height);
+ filter.setBpp((bpc * 3) / 8);
+ filter.decode(array, bufferData);
+ image = new BufferedImage(cm, raster, false, null);
+ return image;
+ }
+
+ /**
+ * Writes the image as .png.
+ *
+ * @see org.pdfbox.pdmodel.graphics.xobject.PDXObjectImage#write2OutputStream(java.io.OutputStream)
+ */
+ public void write2OutputStream(OutputStream out) throws IOException
+ {
+ getRGBImage();
+ if (image!=null)
+ {
+ ImageIO.write(image, "png", out);
+ }
+ }
+
+ /**
+ * DecodeParms is an optional parameter for filters.
+ *
+ * It is provided if any of the filters has nondefault parameters. If there
+ * is only one filter it is a dictionary, if there are multiple filters it
+ * is an array with an entry for each filter. An array entry can hold a null
+ * value if only the default values are used or a dictionary with
+ * parameters.
+ *
+ * @return The decoding parameters.
+ *
+ */
+ public COSDictionary getDecodeParams()
+ {
+ COSBase decodeParms = getCOSStream().getDictionaryObject("DecodeParms");
+ if (decodeParms != null)
+ {
+ if (decodeParms instanceof COSDictionary)
+ {
+ return (COSDictionary) decodeParms;
+ }
+ else if (decodeParms instanceof COSArray)
+ {
+ // not implemented yet, which index should we use?
+ return null;//(COSDictionary)((COSArray)decodeParms).get(0);
+ }
+ else
+ {
+ return null;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * A code that selects the predictor algorithm.
+ *
+ * <ul>
+ * <li>1 No prediction (the default value)
+ * <li>2 TIFF Predictor 2
+ * <li>10 PNG prediction (on encoding, PNG None on all rows)
+ * <li>11 PNG prediction (on encoding, PNG Sub on all rows)
+ * <li>12 PNG prediction (on encoding, PNG Up on all rows)
+ * <li>13 PNG prediction (on encoding, PNG Average on all rows)
+ * <li>14 PNG prediction (on encoding, PNG Paeth on all rows)
+ * <li>15 PNG prediction (on encoding, PNG optimum)
+ * </ul>
+ *
+ * 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 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+
+</head>
+<body>
+This package deals with images that are stored in a PDF document.
+</body>
+</html>