aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/pdfbox/pdmodel/graphics/predictor/PredictorAlgorithm.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/pdfbox/pdmodel/graphics/predictor/PredictorAlgorithm.java')
-rw-r--r--src/main/java/org/pdfbox/pdmodel/graphics/predictor/PredictorAlgorithm.java336
1 files changed, 336 insertions, 0 deletions
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;
+ }
+}