Author: tilman
Date: Sat Apr 26 12:27:52 2014
New Revision: 1590229
URL: http://svn.apache.org/r1590229
Log:
PDFBOX-2047: A read operation must not alter the pdf; optimize toRGB(); created
a test
Added:
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/color/
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/color/PDLabTest.java
(with props)
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDLab.java
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDLab.java
URL:
http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDLab.java?rev=1590229&r1=1590228&r2=1590229&view=diff
==============================================================================
---
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDLab.java
(original)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDLab.java
Sat Apr 26 12:27:52 2014
@@ -21,11 +21,8 @@ import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSFloat;
import org.apache.pdfbox.cos.COSName;
-
import org.apache.pdfbox.pdmodel.common.PDRange;
-
import java.awt.color.ColorSpace;
-import java.io.IOException;
/**
* A Lab colour space is a CIE-based ABC colour space with two transformation
stages.
@@ -40,6 +37,13 @@ public final class PDLab extends PDCIEBa
private COSArray array;
private COSDictionary dictionary;
private PDColor initialColor;
+
+ // we need to cache whitepoint values, because using getWhitePoint()
+ // would create a new default object for each pixel conversion if the
original
+ // PDF didn't have a whitepoint array
+ private float wpX = 1;
+ private float wpY = 1;
+ private float wpZ = 1;
/**
* Creates a new Lab color space.
@@ -60,6 +64,12 @@ public final class PDLab extends PDCIEBa
{
array = lab;
dictionary = (COSDictionary)array.getObject(1);
+
+ // init whitepoint cache
+ PDTristimulus whitepoint = getWhitepoint();
+ wpX = whitepoint.getX();
+ wpY = whitepoint.getY();
+ wpZ = whitepoint.getZ();
}
@Override
@@ -87,22 +97,11 @@ public final class PDLab extends PDCIEBa
float a = minA + (value[1] * (maxA - minA));
float b = minB + (value[2] * (maxB - minB));
- return labToRGB(l, a, b, getWhitepoint(), getBlackPoint());
- }
+ // CIE LAB to RGB, see http://en.wikipedia.org/wiki/Lab_color_space
- // CIE LAB to RGB, see http://en.wikipedia.org/wiki/Lab_color_space
- private float[] labToRGB(float l, float a, float b,
- PDTristimulus whitepoint,
- PDTristimulus blackpoint)
- {
// L*
float lstar = (l + 16f) * (1f / 116f);
- // white point
- float wpX = whitepoint.getX();
- float wpY = whitepoint.getY();
- float wpZ = whitepoint.getZ();
-
// TODO: how to use the blackpoint? scale linearly between black &
white?
// XYZ
@@ -144,7 +143,7 @@ public final class PDLab extends PDCIEBa
@Override
public PDColor getInitialColor()
{
- if (initialColor != null)
+ if (initialColor == null)
{
initialColor = new PDColor(new float[] {
0,
@@ -169,7 +168,6 @@ public final class PDLab extends PDCIEBa
wp.add(new COSFloat(1.0f));
wp.add(new COSFloat(1.0f));
wp.add(new COSFloat(1.0f));
- dictionary.setItem(COSName.WHITE_POINT, wp);
}
return new PDTristimulus(wp);
}
@@ -189,46 +187,52 @@ public final class PDLab extends PDCIEBa
bp.add(new COSFloat(0.0f));
bp.add(new COSFloat(0.0f));
bp.add(new COSFloat(0.0f));
- dictionary.setItem(COSName.BLACK_POINT, bp);
}
return new PDTristimulus(bp);
}
- private COSArray getRangeArray()
+ /**
+ * creates a range array with default values (-100..100 -100..100).
+ * @return the new range array.
+ */
+ private COSArray getDefaultRangeArray()
{
- COSArray range =
(COSArray)dictionary.getDictionaryObject(COSName.RANGE);
- if(range == null)
- {
- range = new COSArray();
- dictionary.setItem(COSName.RANGE, array);
- range.add(new COSFloat(-100));
- range.add(new COSFloat(100));
- range.add(new COSFloat(-100));
- range.add(new COSFloat(100));
- }
+ COSArray range = new COSArray();
+ 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
+ * If none is found then the default will be returned, which is -100..100.
+ * @return the "a" range.
*/
public PDRange getARange()
{
- COSArray range = getRangeArray();
- return new PDRange(range, 0);
+ COSArray rangeArray = (COSArray)
dictionary.getDictionaryObject(COSName.RANGE);
+ if (rangeArray == null)
+ {
+ rangeArray = getDefaultRangeArray();
+ }
+ return new PDRange(rangeArray, 0);
}
/**
* 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
+ * If none is found then the default will be returned, which is -100..100.
+ * @return the "b" range.
*/
public PDRange getBRange()
{
- COSArray range = getRangeArray();
- return new PDRange(range, 1);
+ COSArray rangeArray = (COSArray)
dictionary.getDictionaryObject(COSName.RANGE);
+ if (rangeArray == null)
+ {
+ rangeArray = getDefaultRangeArray();
+ }
+ return new PDRange(rangeArray, 1);
}
/**
@@ -236,13 +240,18 @@ public final class PDLab extends PDCIEBa
* As this is a required field this null should not be passed into this
function.
* @param whitepoint the whitepoint tristimulus
*/
- public void setWhitepoint(PDTristimulus whitepoint)
+ public void setWhitePoint(PDTristimulus whitepoint)
{
COSBase wpArray = whitepoint.getCOSObject();
if(wpArray != null)
{
dictionary.setItem(COSName.WHITE_POINT, wpArray);
}
+
+ // update cached values
+ wpX = whitepoint.getX();
+ wpY = whitepoint.getY();
+ wpZ = whitepoint.getZ();
}
/**
@@ -262,21 +271,26 @@ public final class PDLab extends PDCIEBa
/**
* This will set the a range for the "a" component.
- * @param range the new range for the "a" component
+ * @param range the new range for the "a" component,
+ * or null if defaults (-100..100) are to be set.
*/
public void setARange(PDRange range)
{
- COSArray rangeArray = null;
+ COSArray rangeArray = (COSArray)
dictionary.getDictionaryObject(COSName.RANGE);
+ if (rangeArray == null)
+ {
+ rangeArray = getDefaultRangeArray();
+ }
//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();
+ rangeArray.set(0, new COSFloat(range.getMin()));
+ rangeArray.set(1, new COSFloat(range.getMax()));
}
dictionary.setItem(COSName.RANGE, rangeArray);
initialColor = null;
@@ -284,21 +298,26 @@ public final class PDLab extends PDCIEBa
/**
* This will set the "b" range for this color space.
- * @param range the new range for the "b" component
+ * @param range the new range for the "b" component,
+ * or null if defaults (-100..100) are to be set.
*/
public void setBRange(PDRange range)
{
- COSArray rangeArray = null;
+ COSArray rangeArray = (COSArray)
dictionary.getDictionaryObject(COSName.RANGE);
+ if (rangeArray == null)
+ {
+ rangeArray = getDefaultRangeArray();
+ }
//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();
+ rangeArray.set(2, new COSFloat(range.getMin()));
+ rangeArray.set(3, new COSFloat(range.getMax()));
}
dictionary.setItem(COSName.RANGE, rangeArray);
initialColor = null;
Added:
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/color/PDLabTest.java
URL:
http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/color/PDLabTest.java?rev=1590229&view=auto
==============================================================================
---
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/color/PDLabTest.java
(added)
+++
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/color/PDLabTest.java
Sat Apr 26 12:27:52 2014
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2014 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pdfbox.pdmodel.graphics.color;
+
+import java.util.Arrays;
+import junit.framework.TestCase;
+import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.pdmodel.common.PDRange;
+
+/**
+ *
+ * @author Tilman Hausherr
+ */
+public class PDLabTest extends TestCase
+{
+
+ /**
+ * This test checks that getting default values do not alter the object,
+ * and checks getters and setters.
+ */
+ public void testLAB()
+ {
+ PDLab pdLab = new PDLab();
+ COSArray cosArray = (COSArray) pdLab.getCOSObject();
+ COSDictionary dict = (COSDictionary) cosArray.getObject(1);
+
+ // test with default values
+ assertEquals("Lab", pdLab.getName());
+ assertEquals(3, pdLab.getNumberOfComponents());
+ assertNotNull(pdLab.getInitialColor());
+ assertTrue(Arrays.equals(new float[]{0,0,0},
pdLab.getInitialColor().getComponents()));
+ assertEquals(0f, pdLab.getBlackPoint().getX());
+ assertEquals(0f, pdLab.getBlackPoint().getY());
+ assertEquals(0f, pdLab.getBlackPoint().getZ());
+ assertEquals(1f, pdLab.getWhitepoint().getX());
+ assertEquals(1f, pdLab.getWhitepoint().getX());
+ assertEquals(1f, pdLab.getWhitepoint().getX());
+ assertEquals(-100f, pdLab.getARange().getMin());
+ assertEquals(100f, pdLab.getARange().getMax());
+ assertEquals(-100f, pdLab.getBRange().getMin());
+ assertEquals(100f, pdLab.getBRange().getMax());
+ assertEquals("read operations should not change the size of /Lab
objects", 0, dict.size());
+ dict.toString(); // rev 1571125 did a stack overflow here
+
+ // test setting specific values
+ PDRange pdRange = new PDRange();
+ pdRange.setMin(-1);
+ pdRange.setMax(2);
+ pdLab.setARange(pdRange);
+ pdRange = new PDRange();
+ pdRange.setMin(3);
+ pdRange.setMax(4);
+ pdLab.setBRange(pdRange);
+ assertEquals(-1f, pdLab.getARange().getMin());
+ assertEquals(2f, pdLab.getARange().getMax());
+ assertEquals(3f, pdLab.getBRange().getMin());
+ assertEquals(4f, pdLab.getBRange().getMax());
+ PDTristimulus pdTristimulus = new PDTristimulus();
+ pdTristimulus.setX(5);
+ pdTristimulus.setY(6);
+ pdTristimulus.setZ(7);
+ pdLab.setWhitePoint(pdTristimulus);
+ pdTristimulus = new PDTristimulus();
+ pdTristimulus.setX(8);
+ pdTristimulus.setY(9);
+ pdTristimulus.setZ(10);
+ pdLab.setBlackPoint(pdTristimulus);
+ assertEquals(5f, pdLab.getWhitepoint().getX());
+ assertEquals(6f, pdLab.getWhitepoint().getY());
+ assertEquals(7f, pdLab.getWhitepoint().getZ());
+ assertEquals(8f, pdLab.getBlackPoint().getX());
+ assertEquals(9f, pdLab.getBlackPoint().getY());
+ assertEquals(10f, pdLab.getBlackPoint().getZ());
+ assertTrue(Arrays.equals(new float[]{0,0,3},
pdLab.getInitialColor().getComponents()));
+ }
+
+}
Propchange:
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/color/PDLabTest.java
------------------------------------------------------------------------------
svn:eol-style = native