You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ti...@apache.org on 2018/08/18 13:56:43 UTC
svn commit: r1838328 - in
/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox:
cos/COSName.java pdmodel/graphics/image/PDImageXObject.java
Author: tilman
Date: Sat Aug 18 13:56:43 2018
New Revision: 1838328
URL: http://svn.apache.org/viewvc?rev=1838328&view=rev
Log:
PDFBOX-4267: consider /Matte entry when applying soft masks, as suggested by Jani Pehkonen
Modified:
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/PDImageXObject.java
Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java?rev=1838328&r1=1838327&r2=1838328&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java Sat Aug 18 13:56:43 2018
@@ -343,6 +343,7 @@ public final class COSName extends COSBa
public static final COSName MARK_INFO = new COSName("MarkInfo");
public static final COSName MASK = new COSName("Mask");
public static final COSName MATRIX = new COSName("Matrix");
+ public static final COSName MATTE = new COSName("Matte");
public static final COSName MAX_LEN = new COSName("MaxLen");
public static final COSName MAX_WIDTH = new COSName("MaxWidth");
public static final COSName MCID = new COSName("MCID");
Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/PDImageXObject.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/PDImageXObject.java?rev=1838328&r1=1838327&r2=1838328&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/PDImageXObject.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/PDImageXObject.java Sat Aug 18 13:56:43 2018
@@ -30,6 +30,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.SoftReference;
+import java.util.Arrays;
import java.util.List;
import javax.imageio.ImageIO;
import org.apache.commons.logging.Log;
@@ -446,7 +447,29 @@ public final class PDImageXObject extend
PDImageXObject softMask = getSoftMask();
if (softMask != null)
{
- image = applyMask(image, softMask.getOpaqueImage(), true);
+ COSBase base = softMask.getCOSObject().getItem(COSName.MATTE);
+ float[] matte = null;
+ if (base instanceof COSArray)
+ {
+ // PDFBOX-4267: process /Matte
+ // see PDF specification 1.7, 11.6.5.3 Soft-Mask Images
+ matte = ((COSArray) base).toFloatArray();
+ if (getColorSpace().getNumberOfComponents() == 1 &&
+ matte.length >= 1)
+ {
+ // /DeviceGray has only one element in Matte
+ // See file from PDFBOX-1359, page 14
+ // Root/Pages/Kids/[2]/Kids/[2]/Resources/XObject/Im1/Resources/XObject/Im0
+ matte = new float[] { matte[0], matte[0], matte[0] };
+ }
+ if (matte.length != 3)
+ {
+ LOG.warn("/Matte entry " + Arrays.toString(matte) +
+ " for Soft-Mask may not work properly");
+ matte = Arrays.copyOf(matte, 3);
+ }
+ }
+ image = applyMask(image, softMask.getOpaqueImage(), true, matte);
}
else
{
@@ -454,7 +477,7 @@ public final class PDImageXObject extend
PDImageXObject mask = getMask();
if (mask != null && mask.isStencil())
{
- image = applyMask(image, mask.getOpaqueImage(), false);
+ image = applyMask(image, mask.getOpaqueImage(), false, null);
}
}
@@ -496,7 +519,8 @@ public final class PDImageXObject extend
// explicit mask: RGB + Binary -> ARGB
// soft mask: RGB + Gray -> ARGB
- private BufferedImage applyMask(BufferedImage image, BufferedImage mask, boolean isSoft)
+ private BufferedImage applyMask(BufferedImage image, BufferedImage mask,
+ boolean isSoft, float[] matte)
throws IOException
{
if (mask == null)
@@ -542,6 +566,12 @@ public final class PDImageXObject extend
if (isSoft)
{
rgba[3] = alphaPixel[0];
+ if (matte != null && alphaPixel[0] != 0)
+ {
+ rgba[0] = clampColor(((rgba[0] / 255 - matte[0]) / (alphaPixel[0] / 255) + matte[0]) * 255);
+ rgba[1] = clampColor(((rgba[1] / 255 - matte[1]) / (alphaPixel[0] / 255) + matte[1]) * 255);
+ rgba[2] = clampColor(((rgba[2] / 255 - matte[2]) / (alphaPixel[0] / 255) + matte[2]) * 255);
+ }
}
else
{
@@ -555,6 +585,11 @@ public final class PDImageXObject extend
return masked;
}
+ private float clampColor(float color)
+ {
+ return color < 0 ? 0 : (color > 255 ? 255 : color);
+ }
+
/**
* High-quality image scaling.
*/