aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache
diff options
context:
space:
mode:
authorAndreas Beeker <kiwiwings@apache.org>2020-02-03 00:25:52 +0000
committerAndreas Beeker <kiwiwings@apache.org>2020-02-03 00:25:52 +0000
commit88039893213febe05da53379c2c39e9f58450bc7 (patch)
treef172ebaf0e749c2dc9b0f2d3d3d2366da12b25f3 /src/java/org/apache
parent33fd0b22d6515bd9ec3a1ad6bf738089a0bc86b7 (diff)
downloadpoi-88039893213febe05da53379c2c39e9f58450bc7.tar.gz
poi-88039893213febe05da53379c2c39e9f58450bc7.zip
Use indexed palette for duo tone pattern
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1873516 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache')
-rw-r--r--src/java/org/apache/poi/sl/draw/DrawPaint.java43
1 files changed, 29 insertions, 14 deletions
diff --git a/src/java/org/apache/poi/sl/draw/DrawPaint.java b/src/java/org/apache/poi/sl/draw/DrawPaint.java
index d8a11a956e..eb18e10a4b 100644
--- a/src/java/org/apache/poi/sl/draw/DrawPaint.java
+++ b/src/java/org/apache/poi/sl/draw/DrawPaint.java
@@ -25,7 +25,6 @@ import java.awt.LinearGradientPaint;
import java.awt.MultipleGradientPaint.ColorSpaceType;
import java.awt.MultipleGradientPaint.CycleMethod;
import java.awt.Paint;
-import java.awt.Point;
import java.awt.RadialGradientPaint;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
@@ -33,9 +32,8 @@ import java.awt.geom.Dimension2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
-import java.awt.image.DataBufferInt;
-import java.awt.image.DirectColorModel;
-import java.awt.image.Raster;
+import java.awt.image.DataBuffer;
+import java.awt.image.IndexColorModel;
import java.awt.image.WritableRaster;
import java.io.IOException;
import java.io.InputStream;
@@ -350,25 +348,42 @@ public class DrawPaint {
* @return the original image if no duotone was found, otherwise the colorized pattern
*/
private static BufferedImage colorizePattern(TexturePaint fill, BufferedImage pattern) {
- List<ColorStyle> duoTone = fill.getDuoTone();
+ final List<ColorStyle> duoTone = fill.getDuoTone();
if (duoTone == null || duoTone.size() != 2) {
return pattern;
}
// the pattern image is actually a gray scale image, so we simply take the first color component
// as an index into our gradient samples
- int blendShades = 1 << pattern.getSampleModel().getSampleSize(0);
- int[] gradSample = linearBlendedColors(duoTone, blendShades);
- int[] redSample = pattern.getRaster().getSamples(0, 0, pattern.getWidth(), pattern.getHeight(), 0, (int[])null);
+ final int redBits = pattern.getSampleModel().getSampleSize(0);
+ final int blendBits = Math.max(Math.min(redBits, 8), 1);
+ final int blendShades = 1 << blendBits;
+ // Currently ImageIO converts 16-bit images to 8-bit internally, so it's unlikely to get a blendRatio != 1
+ final double blendRatio = blendShades / (double)(1 << Math.max(redBits,1));
+ final int[] gradSample = linearBlendedColors(duoTone, blendShades);
- for (int i=0; i<redSample.length; i++) {
- redSample[i] = gradSample[redSample[i] & 0xFF];
+ final IndexColorModel icm = new IndexColorModel(blendBits, blendShades, gradSample, 0, true, -1, DataBuffer.TYPE_BYTE);
+ final BufferedImage patIdx = new BufferedImage(pattern.getWidth(), pattern.getHeight(), BufferedImage.TYPE_BYTE_INDEXED, icm);
+
+ final WritableRaster rasterRGBA = pattern.getRaster();
+ final WritableRaster rasterIdx = patIdx.getRaster();
+
+ final int[] redSample = new int[pattern.getWidth()];
+ for (int y=0; y<pattern.getHeight(); y++) {
+ rasterRGBA.getSamples(0, y, redSample.length, 1, 0, redSample);
+ scaleShades(redSample, blendRatio);
+ rasterIdx.setSamples(0, y, redSample.length, 1, 0, redSample);
}
- DirectColorModel dcm = new DirectColorModel(32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
- DataBufferInt dbi = new DataBufferInt(redSample, redSample.length);
- WritableRaster raster = Raster.createPackedRaster(dbi, pattern.getWidth(), pattern.getHeight(), pattern.getWidth(), new int[]{0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000}, new Point());
- return new BufferedImage(dcm, raster, true, null);
+ return patIdx;
+ }
+
+ private static void scaleShades(int[] samples, double ratio) {
+ if (ratio != 1) {
+ for (int x=0; x<samples.length; x++) {
+ samples[x] = (int)Math.rint(samples[x] * ratio);
+ }
+ }
}
private static int[] linearBlendedColors(List<ColorStyle> duoTone, final int blendShades) {