Author: lehmi
Date: Sat Nov 2 13:43:59 2013
New Revision: 1538191
URL: http://svn.apache.org/r1538191
Log:
PDFBOX-1764: optimize the calculation of function values/shading values to
speed up rendering
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/PDFunction.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/PDFunctionType0.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/AxialShadingContext.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/RadialShadingContext.java
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/PDFunction.java
URL:
http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/PDFunction.java?rev=1538191&r1=1538190&r2=1538191&view=diff
==============================================================================
---
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/PDFunction.java
(original)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/PDFunction.java
Sat Nov 2 13:43:59 2013
@@ -18,11 +18,11 @@ package org.apache.pdfbox.pdmodel.common
import java.io.IOException;
+import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSObject;
-import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSStream;
import org.apache.pdfbox.pdmodel.common.COSObjectable;
import org.apache.pdfbox.pdmodel.common.PDRange;
@@ -32,7 +32,7 @@ import org.apache.pdfbox.pdmodel.common.
* This class represents a function in a PDF document.
*
* @author <a href="mailto:[email protected]">Ben Litchfield</a>
- * @version $Revision: 1.3 $
+ *
*/
public abstract class PDFunction implements COSObjectable
{
@@ -41,6 +41,8 @@ public abstract class PDFunction impleme
private COSDictionary functionDictionary = null;
private COSArray domain = null;
private COSArray range = null;
+ private int numberOfInputValues = -1;
+ private int numberOfOutputValues = -1;
/**
* Constructor.
@@ -53,7 +55,7 @@ public abstract class PDFunction impleme
if (function instanceof COSStream)
{
functionStream = new PDStream( (COSStream)function );
- functionStream.getStream().setName( COSName.TYPE, "Function" );
+ functionStream.getStream().setItem( COSName.TYPE, COSName.FUNCTION
);
}
else if (function instanceof COSDictionary)
{
@@ -169,8 +171,12 @@ public abstract class PDFunction impleme
*/
public int getNumberOfOutputParameters()
{
- COSArray rangeValues = getRangeValues();
- return rangeValues.size() / 2;
+ if (numberOfOutputValues == -1)
+ {
+ COSArray rangeValues = getRangeValues();
+ numberOfOutputValues = rangeValues.size() / 2;
+ }
+ return numberOfOutputValues;
}
/**
@@ -208,8 +214,12 @@ public abstract class PDFunction impleme
*/
public int getNumberOfInputParameters()
{
- COSArray array = getDomainValues();
- return array.size() / 2;
+ if (numberOfInputValues == -1)
+ {
+ COSArray array = getDomainValues();
+ numberOfInputValues = array.size() / 2;
+ }
+ return numberOfInputValues;
}
/**
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/PDFunctionType0.java
URL:
http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/PDFunctionType0.java?rev=1538191&r1=1538190&r2=1538191&view=diff
==============================================================================
---
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/PDFunctionType0.java
(original)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/PDFunctionType0.java
Sat Nov 2 13:43:59 2013
@@ -30,7 +30,7 @@ import org.apache.pdfbox.pdmodel.common.
* This class represents a type 0 function in a PDF document.
*
* @author <a href="mailto:[email protected]">Ben Litchfield</a>
- * @version $Revision: 1.2 $
+ *
*/
public class PDFunctionType0 extends PDFunction
{
@@ -41,14 +41,14 @@ public class PDFunctionType0 extends PDF
private static final Log log = LogFactory.getLog(PDFunctionType0.class);
/**
- * An array of 2 Ã m numbers specifying the linear mapping of input
values
- * into the domain of the functionâs sample table.
- * Default value: [ 0 (Size0 â 1) 0 (Size1 â 1) ⦠].
+ * An array of 2 x m numbers specifying the linear mapping of input values
+ * into the domain of the function's sample table.
+ * Default value: [ 0 (Size0 - 1) 0 (Size1 - 1) ...].
*/
private COSArray encode = null;
/**
- * An array of 2 Ã n numbers specifying the linear mapping of sample
values
- * into the range appropriate for the functionâs output values.
+ * An array of 2 x n numbers specifying the linear mapping of sample
values
+ * into the range appropriate for the function's output values.
* Default value: same as the value of Range
*/
private COSArray decode = null;
@@ -298,16 +298,16 @@ public class PDFunctionType0 extends PDF
int bitsPerSample = getBitsPerSample();
int numberOfInputValues = input.length;
int numberOfOutputValues = getNumberOfOutputParameters();
- int[] intInputValuesPrevious = new int[numberOfInputValues];
- int[] intInputValuesNext = new int[numberOfInputValues];
+ int intInputValuesPrevious = 0;
+ int intInputValuesNext = 0;
for (int i=0; i<numberOfInputValues; i++) {
PDRange domain = getDomainForInput(i);
PDRange encode = getEncodeForParameter(i);
input[i] = clipToRange(input[i], domain.getMin(), domain.getMax());
input[i] = interpolate(input[i], domain.getMin(), domain.getMax(),
encode.getMin(), encode.getMax());
input[i] = clipToRange(input[i], 0, sizeValues[i]-1);
- intInputValuesPrevious[i] = (int)Math.floor(input[i]);
- intInputValuesNext[i] = (int)Math.ceil(input[i]);
+ intInputValuesPrevious += (int)Math.floor(input[i]);
+ intInputValuesNext += (int)Math.ceil(input[i]);
}
float[] outputValuesPrevious = null;
float[] outputValuesNext = null;
@@ -331,26 +331,17 @@ public class PDFunctionType0 extends PDF
/**
* Get the samples for the given input values.
*
- * @param inputValues an array containing the input values
+ * @param indexValue the index into the sample values array
* @return an array with the corresponding samples
*/
- private float[] getSample(int[] inputValues)
+ private float[] getSample(int indexValue)
{
- int[][] sampleValues = getSamples();
- COSArray sizes = getSize();
- int numberOfInputValues = getNumberOfInputParameters();
- int index = 0;
- int previousSize = 1;
- for (int i=0;i<numberOfInputValues;i++)
+ int[] sampleValues = getSamples()[indexValue];
+ int numberOfValues = sampleValues.length;
+ float[] result = new float[numberOfValues];
+ for (int i=0;i<numberOfValues;i++)
{
- index += inputValues[i];
- previousSize *= sizes.getInt(i);
- }
- int numberOfOutputValues = getNumberOfOutputParameters();
- float[] result = new float[numberOfOutputValues];
- for (int i=0;i<numberOfOutputValues;i++)
- {
- result[i] = sampleValues[index][i];
+ result[i] = sampleValues[i];
}
return result;
}
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/AxialShadingContext.java
URL:
http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/AxialShadingContext.java?rev=1538191&r1=1538190&r2=1538191&view=diff
==============================================================================
---
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/AxialShadingContext.java
(original)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/AxialShadingContext.java
Sat Nov 2 13:43:59 2013
@@ -39,7 +39,6 @@ import org.apache.pdfbox.util.Matrix;
* This class represents the PaintContext of an axial shading.
*
* @author lehmi
- * @version $Revision: $
*
*/
public class AxialShadingContext implements PaintContext
@@ -52,6 +51,8 @@ public class AxialShadingContext impleme
private float[] coords;
private float[] domain;
+ private int[] extend0Values;
+ private int[] extend1Values;
private boolean[] extend;
private double x1x0;
private double y1y0;
@@ -196,10 +197,13 @@ public class AxialShadingContext impleme
// create writable raster
WritableRaster raster =
getColorModel().createCompatibleWritableRaster(w, h);
int[] data = new int[w * h * 3];
+ boolean saveExtend0 = false;
+ boolean saveExtend1 = false;
for (int j = 0; j < h; j++)
{
for (int i = 0; i < w; i++)
{
+ int index = (j * w + i) * 3;
double inputValue = x1x0 * (x + i - coords[0]);
inputValue += y1y0 * (y + j - coords[1]);
inputValue /= denom;
@@ -209,7 +213,17 @@ public class AxialShadingContext impleme
// the shading has to be extended if extend[0] == true
if (extend[0])
{
- inputValue = domain[0];
+ if (extend0Values == null)
+ {
+ inputValue = domain[0];
+ saveExtend0 = true;
+ }
+ else
+ {
+ // use the chached values
+ System.arraycopy(extend0Values, 0, data, index, 3);
+ continue;
+ }
}
else
{
@@ -222,7 +236,17 @@ public class AxialShadingContext impleme
// the shading has to be extended if extend[1] == true
if (extend[1])
{
- inputValue = domain[1];
+ if (extend1Values == null)
+ {
+ inputValue = domain[1];
+ saveExtend1 = true;
+ }
+ else
+ {
+ // use the chached values
+ System.arraycopy(extend1Values, 0, data, index, 3);
+ continue;
+ }
}
else
{
@@ -231,7 +255,6 @@ public class AxialShadingContext impleme
}
float input = (float)(domain[0] + (d1d0*inputValue));
float[] values = null;
- int index = (j * w + i) * 3;
try
{
values = shadingType.evalFunction(input);
@@ -252,6 +275,18 @@ public class AxialShadingContext impleme
data[index] = (int)(values[0]*255);
data[index+1] = (int)(values[1]*255);
data[index+2] = (int)(values[2]*255);
+ if (saveExtend0)
+ {
+ // chache values
+ extend0Values = new int[3];
+ System.arraycopy(data, index, extend0Values, 0, 3);
+ }
+ if (saveExtend1)
+ {
+ // chache values
+ extend1Values = new int[3];
+ System.arraycopy(data, index, extend1Values, 0, 3);
+ }
}
}
raster.setPixels(0, 0, w, h, data);
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/RadialShadingContext.java
URL:
http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/RadialShadingContext.java?rev=1538191&r1=1538190&r2=1538191&view=diff
==============================================================================
---
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/RadialShadingContext.java
(original)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/RadialShadingContext.java
Sat Nov 2 13:43:59 2013
@@ -39,7 +39,6 @@ import org.apache.pdfbox.util.Matrix;
* This class represents the PaintContext of an radial shading.
*
* @author lehmi
- * @version $Revision: $
*
*/
public class RadialShadingContext implements PaintContext
@@ -52,6 +51,8 @@ public class RadialShadingContext implem
private float[] coords;
private float[] domain;
+ private int[] extend0Values;
+ private int[] extend1Values;
private boolean[] extend;
private double x1x0;
private double y1y0;
@@ -207,11 +208,14 @@ public class RadialShadingContext implem
// create writable raster
WritableRaster raster =
getColorModel().createCompatibleWritableRaster(w, h);
float inputValue;
+ boolean saveExtend0 = false;
+ boolean saveExtend1 = false;
int[] data = new int[w * h * 3];
for (int j = 0; j < h; j++)
{
for (int i = 0; i < w; i++)
{
+ int index = (j * w + i) * 3;
float[] inputValues = calculateInputValues(x + i, y + j);
// choose 1 of the 2 values
if (inputValues[0] >= domain[0] && inputValues[0] <= domain[1])
@@ -247,7 +251,17 @@ public class RadialShadingContext implem
// the shading has to be extended if extend[0] == true
if (extend[0])
{
- inputValue = domain[0];
+ if (extend0Values == null)
+ {
+ inputValue = domain[0];
+ saveExtend0 = true;
+ }
+ else
+ {
+ // use the chached values
+ System.arraycopy(extend0Values, 0, data, index, 3);
+ continue;
+ }
}
else
{
@@ -260,7 +274,17 @@ public class RadialShadingContext implem
// the shading has to be extended if extend[1] == true
if (extend[1])
{
- inputValue = domain[1];
+ if (extend1Values == null)
+ {
+ inputValue = domain[1];
+ saveExtend1 = true;
+ }
+ else
+ {
+ // use the chached values
+ System.arraycopy(extend1Values, 0, data, index, 3);
+ continue;
+ }
}
else
{
@@ -269,7 +293,6 @@ public class RadialShadingContext implem
}
float input = (float)(domain[0] + (d1d0*inputValue));
float[] values = null;
- int index = (j * w + i) * 3;
try
{
values = shadingType.evalFunction(input);
@@ -290,6 +313,18 @@ public class RadialShadingContext implem
data[index] = (int)(values[0]*255);
data[index+1] = (int)(values[1]*255);
data[index+2] = (int)(values[2]*255);
+ if (saveExtend0)
+ {
+ // chache values
+ extend0Values = new int[3];
+ System.arraycopy(data, index, extend0Values, 0, 3);
+ }
+ if (saveExtend1)
+ {
+ // chache values
+ extend1Values = new int[3];
+ System.arraycopy(data, index, extend1Values, 0, 3);
+ }
}
}
raster.setPixels(0, 0, w, h, data);