You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2018/02/09 17:06:24 UTC
[09/14] pdfbox-jbig2 git commit: PDFBOX-4098: reformat the source
code, introduce an eclipse formatter definition
http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/image/Bitmaps.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/pdfbox/jbig2/image/Bitmaps.java b/src/main/java/org/apache/pdfbox/jbig2/image/Bitmaps.java
index af4a26a..895741f 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/image/Bitmaps.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/image/Bitmaps.java
@@ -32,538 +32,645 @@ import org.apache.pdfbox.jbig2.Bitmap;
import org.apache.pdfbox.jbig2.JBIG2ReadParam;
import org.apache.pdfbox.jbig2.util.CombinationOperator;
-public class Bitmaps {
+public class Bitmaps
+{
/**
* Returns the given bitmap as writable raster.
- *
+ *
* @param bitmap the given bitmap
* @return the raster representation of the bitmap
*/
- public static WritableRaster asRaster(final Bitmap bitmap) {
- return asRaster(bitmap, FilterType.Gaussian);
- }
+ public static WritableRaster asRaster(final Bitmap bitmap)
+ {
+ return asRaster(bitmap, FilterType.Gaussian);
+ }
/**
* Returns the given bitmap as writable raster.
- *
+ *
* @param bitmap the given bitmap
* @param filterType type of filter which is used when creating the writable raster
* @return the raster representation of the bitmap
*/
- public static WritableRaster asRaster(final Bitmap bitmap, final FilterType filterType) {
+ public static WritableRaster asRaster(final Bitmap bitmap, final FilterType filterType)
+ {
if (bitmap == null)
- throw new IllegalArgumentException("bitmap must not be null");
-
- final JBIG2ReadParam param = new JBIG2ReadParam(1, 1, 0, 0, new Rectangle(0, 0, bitmap.getWidth(),
- bitmap.getHeight()), new Dimension(bitmap.getWidth(), bitmap.getHeight()));
-
+ throw new IllegalArgumentException("bitmap must not be null");
+
+ final JBIG2ReadParam param = new JBIG2ReadParam(1, 1, 0, 0,
+ new Rectangle(0, 0, bitmap.getWidth(), bitmap.getHeight()),
+ new Dimension(bitmap.getWidth(), bitmap.getHeight()));
+
return asRaster(bitmap, param, filterType);
}
/**
* Returns the given bitmap as writable raster.
- *
+ *
* @param bitmap the given bitmap
* @param param ImageReadParam to be used when creating the writable raster
* @param filterType type of filter which is used when creating the writable raster
* @return the raster representation of the bitmap
*/
- public static WritableRaster asRaster(Bitmap bitmap, final ImageReadParam param, final FilterType filterType) {
- if (bitmap == null)
- throw new IllegalArgumentException("bitmap must not be null");
-
- if (param == null)
- throw new IllegalArgumentException("param must not be null");
-
- final Dimension sourceRenderSize = param.getSourceRenderSize();
-
- double scaleX;
- double scaleY;
- if (sourceRenderSize != null) {
- scaleX = sourceRenderSize.getWidth() / bitmap.getWidth();
- scaleY = sourceRenderSize.getHeight() / bitmap.getHeight();
- } else {
- scaleX = scaleY = 1;
- }
-
- Rectangle sourceRegion = param.getSourceRegion();
- if (sourceRegion != null && !bitmap.getBounds().equals(sourceRegion)) {
- // make sure we don't request an area outside of the source bitmap
- sourceRegion = bitmap.getBounds().intersection(sourceRegion);
+ public static WritableRaster asRaster(Bitmap bitmap, final ImageReadParam param,
+ final FilterType filterType)
+ {
+ if (bitmap == null)
+ throw new IllegalArgumentException("bitmap must not be null");
- // get region of interest
- bitmap = Bitmaps.extract(sourceRegion, bitmap);
- }
+ if (param == null)
+ throw new IllegalArgumentException("param must not be null");
- /*
- * Subsampling is the advance of columns/rows for each pixel in the according direction. The
- * resulting image's quality will be bad because we loose information if we step over
- * columns/rows. For example, a thin line (1 pixel high) may disappear completely. To avoid this
- * we use resize filters if scaling will be performed anyway. The resize filters use scale
- * factors, one for horizontal and vertical direction. We care about the given subsampling steps
- * by adjusting the scale factors. If scaling is not performed, subsampling is performed in its
- * original manner.
- */
+ final Dimension sourceRenderSize = param.getSourceRenderSize();
- final boolean requiresScaling = scaleX != 1 || scaleY != 1;
-
- final boolean requiresXSubsampling = param.getSourceXSubsampling() != 1;
- final boolean requiresYSubsampling = param.getSourceYSubsampling() != 1;
-
- if (requiresXSubsampling && requiresYSubsampling) {
- // Apply vertical and horizontal subsampling
- if (requiresScaling) {
- scaleX /= (double) param.getSourceXSubsampling();
- scaleY /= (double) param.getSourceYSubsampling();
- } else {
- bitmap = subsample(bitmap, param);
- }
- } else {
- if (requiresXSubsampling) {
- // Apply horizontal subsampling only
- if (requiresScaling) {
- scaleX /= (double) param.getSourceXSubsampling();
- } else {
- bitmap = Bitmaps.subsampleX(bitmap, param.getSourceXSubsampling(), param.getSubsamplingXOffset());
+ double scaleX;
+ double scaleY;
+ if (sourceRenderSize != null)
+ {
+ scaleX = sourceRenderSize.getWidth() / bitmap.getWidth();
+ scaleY = sourceRenderSize.getHeight() / bitmap.getHeight();
}
- }
-
- if (requiresYSubsampling) {
- // Apply vertical subsampling only
- if (requiresScaling) {
- scaleY /= (double) param.getSourceYSubsampling();
- } else {
- bitmap = Bitmaps.subsampleY(bitmap, param.getSourceYSubsampling(), param.getSubsamplingYOffset());
+ else
+ {
+ scaleX = scaleY = 1;
}
- }
- }
- return buildRaster(bitmap, filterType, scaleX, scaleY);
- }
-
- private static WritableRaster buildRaster(final Bitmap bitmap, final FilterType filterType, final double scaleX,
- final double scaleY) {
- final Rectangle dstBounds = new Rectangle(0, 0, //
- (int) Math.round(bitmap.getWidth() * scaleX), //
- (int) Math.round(bitmap.getHeight() * scaleY));
-
- final WritableRaster dst = WritableRaster.createInterleavedRaster(DataBuffer.TYPE_BYTE, dstBounds.width,
- dstBounds.height, 1, new Point());
-
- if (scaleX != 1 || scaleY != 1) {
- // scaling required
- final Resizer resizer = new Resizer(scaleX, scaleY);
- final Filter filter = Filter.byType(filterType);
- resizer.resize(bitmap, bitmap.getBounds() /* sourceRegion */, dst, dstBounds, filter, filter);
- } else {
- // scaling not required, paste bitmap into raster pixel per pixel
- int byteIndex = 0;
- for (int y = 0; y < bitmap.getHeight(); y++) {
- for (int x = 0; x < bitmap.getWidth(); byteIndex++) {
- final int pixels = (~bitmap.getByte(byteIndex)) & 0xFF;
- final int relevantPixels = bitmap.getWidth() - x > 8 ? 8 : bitmap.getWidth() - x;
- final int endIdx = 7 - relevantPixels;
- for (int bytePosition = 7; bytePosition > endIdx; bytePosition--, x++) {
- dst.setSample(x, y, 0, (pixels >> bytePosition) & 0x1);
- }
+ Rectangle sourceRegion = param.getSourceRegion();
+ if (sourceRegion != null && !bitmap.getBounds().equals(sourceRegion))
+ {
+ // make sure we don't request an area outside of the source bitmap
+ sourceRegion = bitmap.getBounds().intersection(sourceRegion);
+
+ // get region of interest
+ bitmap = Bitmaps.extract(sourceRegion, bitmap);
}
- }
- }
- return dst;
- }
-
- /**
- * Returns the given bitmap as buffered image.
- *
- * @param bitmap the given bitmap
- * @return the image representation of the bitmap
- */
- public static BufferedImage asBufferedImage(Bitmap bitmap) {
- return asBufferedImage(bitmap, FilterType.Gaussian);
- }
-
- /**
- * Returns the given bitmap as buffered image.
- *
- * @param bitmap the given bitmap
- * @param filterType type of filter which is used when creating the buffered image
- * @return the image representation of the bitmap
- */
- public static BufferedImage asBufferedImage(Bitmap bitmap, FilterType filterType) {
- if (bitmap == null)
- throw new IllegalArgumentException("bitmap must not be null");
-
- final JBIG2ReadParam param = new JBIG2ReadParam(1, 1, 0, 0, new Rectangle(0, 0, bitmap.getWidth(),
- bitmap.getHeight()), new Dimension(bitmap.getWidth(), bitmap.getHeight()));
-
- return asBufferedImage(bitmap, param, filterType);
- }
-
- /**
- * Returns the given bitmap as buffered image.
- *
- * @param bitmap the given bitmap
- * @param param ImageReadParam to be used when creating the buffered image
- * @param filterType type of filter which is used when creating the buffered image
- * @return the image representation of the bitmap
- */
- public static BufferedImage asBufferedImage(Bitmap bitmap, ImageReadParam param, FilterType filterType) {
- if (bitmap == null)
- throw new IllegalArgumentException("bitmap must not be null");
-
- if (param == null)
- throw new IllegalArgumentException("param must not be null");
-
- final WritableRaster raster = asRaster(bitmap, param, filterType);
-
- final Dimension sourceRenderSize = param.getSourceRenderSize();
-
- final double scaleX;
- final double scaleY;
- if (sourceRenderSize != null) {
- scaleX = sourceRenderSize.getWidth() / bitmap.getWidth();
- scaleY = sourceRenderSize.getHeight() / bitmap.getHeight();
- } else {
- scaleX = scaleY = 1d;
- }
+ /*
+ * Subsampling is the advance of columns/rows for each pixel in the according direction. The resulting image's
+ * quality will be bad because we loose information if we step over columns/rows. For example, a thin line (1
+ * pixel high) may disappear completely. To avoid this we use resize filters if scaling will be performed
+ * anyway. The resize filters use scale factors, one for horizontal and vertical direction. We care about the
+ * given subsampling steps by adjusting the scale factors. If scaling is not performed, subsampling is performed
+ * in its original manner.
+ */
+
+ final boolean requiresScaling = scaleX != 1 || scaleY != 1;
+
+ final boolean requiresXSubsampling = param.getSourceXSubsampling() != 1;
+ final boolean requiresYSubsampling = param.getSourceYSubsampling() != 1;
+
+ if (requiresXSubsampling && requiresYSubsampling)
+ {
+ // Apply vertical and horizontal subsampling
+ if (requiresScaling)
+ {
+ scaleX /= (double) param.getSourceXSubsampling();
+ scaleY /= (double) param.getSourceYSubsampling();
+ }
+ else
+ {
+ bitmap = subsample(bitmap, param);
+ }
+ }
+ else
+ {
+ if (requiresXSubsampling)
+ {
+ // Apply horizontal subsampling only
+ if (requiresScaling)
+ {
+ scaleX /= (double) param.getSourceXSubsampling();
+ }
+ else
+ {
+ bitmap = Bitmaps.subsampleX(bitmap, param.getSourceXSubsampling(),
+ param.getSubsamplingXOffset());
+ }
+ }
+
+ if (requiresYSubsampling)
+ {
+ // Apply vertical subsampling only
+ if (requiresScaling)
+ {
+ scaleY /= (double) param.getSourceYSubsampling();
+ }
+ else
+ {
+ bitmap = Bitmaps.subsampleY(bitmap, param.getSourceYSubsampling(),
+ param.getSubsamplingYOffset());
+ }
+ }
+ }
- ColorModel cm = null;
- final boolean isScaled = scaleX != 1 || scaleY != 1;
- if (isScaled) {
- final int size = 256;
- final int divisor = size - 1;
-
- final byte[] gray = new byte[size];
- for (int i = size - 1, s = 0; i >= 0; i--, s++) {
- gray[i] = (byte) (255 - s * 255 / divisor);
- }
- cm = new IndexColorModel(8, size, gray, gray, gray);
- } else {
-
- cm = new IndexColorModel(8, 2, //
- new byte[]{
- 0x00, (byte) 0xff
- }, new byte[]{
- 0x00, (byte) 0xff
- }, new byte[]{
- 0x00, (byte) 0xff
- });
+ return buildRaster(bitmap, filterType, scaleX, scaleY);
}
- return new BufferedImage(cm, raster, false, null);
- }
-
- /**
- * Returns the specified rectangle area of the bitmap.
- *
- * @param roi - A {@link Rectangle} that specifies the requested image section.
- * @param src the given bitmap
- * @return A {@code Bitmap} that represents the requested image section.
- */
- public static Bitmap extract(final Rectangle roi, final Bitmap src) {
- final Bitmap dst = new Bitmap(roi.width, roi.height);
-
- final int upShift = roi.x & 0x07;
- final int downShift = 8 - upShift;
- int dstLineStartIdx = 0;
-
- final int padding = (8 - dst.getWidth() & 0x07);
- int srcLineStartIdx = src.getByteIndex(roi.x, roi.y);
- int srcLineEndIdx = src.getByteIndex(roi.x + roi.width - 1, roi.y);
- final boolean usePadding = dst.getRowStride() == srcLineEndIdx + 1 - srcLineStartIdx;
-
- for (int y = roi.y; y < roi.getMaxY(); y++) {
- int srcIdx = srcLineStartIdx;
- int dstIdx = dstLineStartIdx;
-
- if (srcLineStartIdx == srcLineEndIdx) {
- final byte pixels = (byte) (src.getByte(srcIdx) << upShift);
- dst.setByte(dstIdx, unpad(padding, pixels));
- } else if (upShift == 0) {
- for (int x = srcLineStartIdx; x <= srcLineEndIdx; x++) {
- byte value = src.getByte(srcIdx++);
-
- if (x == srcLineEndIdx && usePadding) {
- value = unpad(padding, value);
- }
-
- dst.setByte(dstIdx++, value);
+ private static WritableRaster buildRaster(final Bitmap bitmap, final FilterType filterType,
+ final double scaleX, final double scaleY)
+ {
+ final Rectangle dstBounds = new Rectangle(0, 0, //
+ (int) Math.round(bitmap.getWidth() * scaleX), //
+ (int) Math.round(bitmap.getHeight() * scaleY));
+
+ final WritableRaster dst = WritableRaster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
+ dstBounds.width, dstBounds.height, 1, new Point());
+
+ if (scaleX != 1 || scaleY != 1)
+ {
+ // scaling required
+ final Resizer resizer = new Resizer(scaleX, scaleY);
+ final Filter filter = Filter.byType(filterType);
+ resizer.resize(bitmap, bitmap.getBounds() /* sourceRegion */, dst, dstBounds, filter,
+ filter);
+ }
+ else
+ {
+ // scaling not required, paste bitmap into raster pixel per pixel
+ int byteIndex = 0;
+ for (int y = 0; y < bitmap.getHeight(); y++)
+ {
+ for (int x = 0; x < bitmap.getWidth(); byteIndex++)
+ {
+ final int pixels = (~bitmap.getByte(byteIndex)) & 0xFF;
+ final int relevantPixels = bitmap.getWidth() - x > 8 ? 8
+ : bitmap.getWidth() - x;
+ final int endIdx = 7 - relevantPixels;
+ for (int bytePosition = 7; bytePosition > endIdx; bytePosition--, x++)
+ {
+ dst.setSample(x, y, 0, (pixels >> bytePosition) & 0x1);
+ }
+ }
+ }
}
- } else {
- copyLine(src, dst, upShift, downShift, padding, srcLineStartIdx, srcLineEndIdx, usePadding, srcIdx, dstIdx);
- }
- srcLineStartIdx += src.getRowStride();
- srcLineEndIdx += src.getRowStride();
- dstLineStartIdx += dst.getRowStride();
+ return dst;
}
- return dst;
- }
-
- private static void copyLine(Bitmap src, Bitmap dst, int sourceUpShift, int sourceDownShift, int padding,
- int firstSourceByteOfLine, int lastSourceByteOfLine, boolean usePadding, int sourceOffset, int targetOffset) {
- for (int x = firstSourceByteOfLine; x < lastSourceByteOfLine; x++) {
-
- if (sourceOffset + 1 < src.getByteArray().length) {
- final boolean isLastByte = x + 1 == lastSourceByteOfLine;
- byte value = (byte) (src.getByte(sourceOffset++) << sourceUpShift | (src.getByte(sourceOffset) & 0xff) >>> sourceDownShift);
-
- if (isLastByte && !usePadding) {
- value = unpad(padding, value);
- }
+ /**
+ * Returns the given bitmap as buffered image.
+ *
+ * @param bitmap the given bitmap
+ * @return the image representation of the bitmap
+ */
+ public static BufferedImage asBufferedImage(Bitmap bitmap)
+ {
+ return asBufferedImage(bitmap, FilterType.Gaussian);
+ }
- dst.setByte(targetOffset++, value);
+ /**
+ * Returns the given bitmap as buffered image.
+ *
+ * @param bitmap the given bitmap
+ * @param filterType type of filter which is used when creating the buffered image
+ * @return the image representation of the bitmap
+ */
+ public static BufferedImage asBufferedImage(Bitmap bitmap, FilterType filterType)
+ {
+ if (bitmap == null)
+ throw new IllegalArgumentException("bitmap must not be null");
- if (isLastByte && usePadding) {
- value = unpad(padding, (byte) ((src.getByte(sourceOffset) & 0xff) << sourceUpShift));
- dst.setByte(targetOffset, value);
- }
+ final JBIG2ReadParam param = new JBIG2ReadParam(1, 1, 0, 0,
+ new Rectangle(0, 0, bitmap.getWidth(), bitmap.getHeight()),
+ new Dimension(bitmap.getWidth(), bitmap.getHeight()));
- } else {
- final byte value = (byte) (src.getByte(sourceOffset++) << sourceUpShift & 0xff);
- dst.setByte(targetOffset++, value);
- }
- }
- }
-
- /**
- * Removes unnecessary bits from a byte.
- *
- * @param padding - The amount of unnecessary bits.
- * @param value - The byte that should be cleaned up.
- * @return A cleaned byte.
- */
- private static byte unpad(int padding, byte value) {
- return (byte) (value >> padding << padding);
- }
-
- public static Bitmap subsample(Bitmap src, ImageReadParam param) {
- if (src == null)
- throw new IllegalArgumentException("src must not be null");
-
- if (param == null)
- throw new IllegalArgumentException("param must not be null");
-
- final int xSubsampling = param.getSourceXSubsampling();
- final int ySubsampling = param.getSourceYSubsampling();
- final int xSubsamplingOffset = param.getSubsamplingXOffset();
- final int ySubsamplingOffset = param.getSubsamplingYOffset();
-
- final int dstWidth = (src.getWidth() - xSubsamplingOffset) / xSubsampling;
- final int dstHeight = (src.getHeight() - ySubsamplingOffset) / ySubsampling;
-
- final Bitmap dst = new Bitmap(dstWidth, dstHeight);
-
- for (int yDst = 0, ySrc = ySubsamplingOffset; yDst < dst.getHeight(); yDst++, ySrc += ySubsampling) {
- for (int xDst = 0, xSrc = xSubsamplingOffset; xDst < dst.getWidth(); xDst++, xSrc += xSubsampling) {
- final byte pixel = src.getPixel(xSrc, ySrc);
- if (pixel != 0)
- dst.setPixel(xDst, yDst, pixel);
- }
+ return asBufferedImage(bitmap, param, filterType);
}
- return dst;
- }
+ /**
+ * Returns the given bitmap as buffered image.
+ *
+ * @param bitmap the given bitmap
+ * @param param ImageReadParam to be used when creating the buffered image
+ * @param filterType type of filter which is used when creating the buffered image
+ * @return the image representation of the bitmap
+ */
+ public static BufferedImage asBufferedImage(Bitmap bitmap, ImageReadParam param,
+ FilterType filterType)
+ {
+ if (bitmap == null)
+ throw new IllegalArgumentException("bitmap must not be null");
- public static Bitmap subsampleX(Bitmap src, final int xSubsampling, final int xSubsamplingOffset) {
- if (src == null)
- throw new IllegalArgumentException("src must not be null");
+ if (param == null)
+ throw new IllegalArgumentException("param must not be null");
- final int dstHeight = (src.getWidth() - xSubsamplingOffset) / xSubsampling;
- final Bitmap dst = new Bitmap(src.getWidth(), dstHeight);
+ final WritableRaster raster = asRaster(bitmap, param, filterType);
- for (int yDst = 0; yDst < dst.getHeight(); yDst++) {
- for (int xDst = 0, xSrc = xSubsamplingOffset; xDst < dst.getWidth(); xDst++, xSrc += xSubsampling) {
- final byte pixel = src.getPixel(xSrc, yDst);
- if (pixel != 0)
- dst.setPixel(xDst, yDst, pixel);
- }
- }
+ final Dimension sourceRenderSize = param.getSourceRenderSize();
- return dst;
- }
+ final double scaleX;
+ final double scaleY;
+ if (sourceRenderSize != null)
+ {
+ scaleX = sourceRenderSize.getWidth() / bitmap.getWidth();
+ scaleY = sourceRenderSize.getHeight() / bitmap.getHeight();
+ }
+ else
+ {
+ scaleX = scaleY = 1d;
+ }
- public static Bitmap subsampleY(Bitmap src, final int ySubsampling, final int ySubsamplingOffset) {
- if (src == null)
- throw new IllegalArgumentException("src must not be null");
+ ColorModel cm = null;
+ final boolean isScaled = scaleX != 1 || scaleY != 1;
+ if (isScaled)
+ {
+ final int size = 256;
+ final int divisor = size - 1;
+
+ final byte[] gray = new byte[size];
+ for (int i = size - 1, s = 0; i >= 0; i--, s++)
+ {
+ gray[i] = (byte) (255 - s * 255 / divisor);
+ }
+ cm = new IndexColorModel(8, size, gray, gray, gray);
+ }
+ else
+ {
- final int dstWidth = (src.getWidth() - ySubsamplingOffset) / ySubsampling;
- final Bitmap dst = new Bitmap(dstWidth, src.getHeight());
+ cm = new IndexColorModel(8, 2, //
+ new byte[] { 0x00, (byte) 0xff }, new byte[] { 0x00, (byte) 0xff },
+ new byte[] { 0x00, (byte) 0xff });
+ }
- for (int yDst = 0, ySrc = ySubsamplingOffset; yDst < dst.getHeight(); yDst++, ySrc += ySubsampling) {
- for (int xDst = 0; xDst < dst.getWidth(); xDst++) {
- final byte pixel = src.getPixel(xDst, ySrc);
- if (pixel != 0)
- dst.setPixel(xDst, yDst, pixel);
- }
+ return new BufferedImage(cm, raster, false, null);
}
- return dst;
- }
-
- /**
- * The method combines two given bytes with an logical operator.
- * <p>
- * The JBIG2 Standard specifies 5 possible combinations of bytes.<br>
- * <p>
- * <b>Hint:</b> Please take a look at ISO/IEC 14492:2001 (E) for detailed definition and
- * description of the operators.
- *
- * @param value1 - The value that should be combined with value2.
- * @param value2 - The value that should be combined with value1.
- * @param op - The specified combination operator.
- *
- * @return The combination result.
- */
- public static byte combineBytes(byte value1, byte value2, CombinationOperator op) {
-
- switch (op){
- case OR :
- return (byte) (value2 | value1);
- case AND :
- return (byte) (value2 & value1);
- case XOR :
- return (byte) (value2 ^ value1);
- case XNOR :
- return (byte) ~(value1 ^ value2);
- case REPLACE :
- default :
- // Old value is replaced by new value.
- return value2;
- }
- }
-
- /**
- * This method combines a given bitmap with the current instance.
- * <p>
- * Parts of the bitmap to blit that are outside of the target bitmap will be ignored.
- *
- * @param src - The bitmap that should be combined with the one of the current instance.
- * @param dst - The destination bitmap.
- * @param x - The x coordinate where the upper left corner of the bitmap to blit should be
- * positioned.
- * @param y - The y coordinate where the upper left corner of the bitmap to blit should be
- * positioned.
- * @param combinationOperator - The combination operator for combining two pixels.
- */
- public static void blit(Bitmap src, Bitmap dst, int x, int y, CombinationOperator combinationOperator) {
-
- int startLine = 0;
- int srcStartIdx = 0;
- int srcEndIdx = (src.getRowStride() - 1);
-
- // Ignore those parts of the source bitmap which would be placed outside the target bitmap.
- if (x < 0) {
- srcStartIdx = -x;
- x = 0;
- } else if (x + src.getWidth() > dst.getWidth()) {
- srcEndIdx -= (src.getWidth() + x - dst.getWidth());
- }
+ /**
+ * Returns the specified rectangle area of the bitmap.
+ *
+ * @param roi - A {@link Rectangle} that specifies the requested image section.
+ * @param src the given bitmap
+ * @return A {@code Bitmap} that represents the requested image section.
+ */
+ public static Bitmap extract(final Rectangle roi, final Bitmap src)
+ {
+ final Bitmap dst = new Bitmap(roi.width, roi.height);
+
+ final int upShift = roi.x & 0x07;
+ final int downShift = 8 - upShift;
+ int dstLineStartIdx = 0;
+
+ final int padding = (8 - dst.getWidth() & 0x07);
+ int srcLineStartIdx = src.getByteIndex(roi.x, roi.y);
+ int srcLineEndIdx = src.getByteIndex(roi.x + roi.width - 1, roi.y);
+ final boolean usePadding = dst.getRowStride() == srcLineEndIdx + 1 - srcLineStartIdx;
+
+ for (int y = roi.y; y < roi.getMaxY(); y++)
+ {
+ int srcIdx = srcLineStartIdx;
+ int dstIdx = dstLineStartIdx;
+
+ if (srcLineStartIdx == srcLineEndIdx)
+ {
+ final byte pixels = (byte) (src.getByte(srcIdx) << upShift);
+ dst.setByte(dstIdx, unpad(padding, pixels));
+ }
+ else if (upShift == 0)
+ {
+ for (int x = srcLineStartIdx; x <= srcLineEndIdx; x++)
+ {
+ byte value = src.getByte(srcIdx++);
+
+ if (x == srcLineEndIdx && usePadding)
+ {
+ value = unpad(padding, value);
+ }
+
+ dst.setByte(dstIdx++, value);
+ }
+ }
+ else
+ {
+ copyLine(src, dst, upShift, downShift, padding, srcLineStartIdx, srcLineEndIdx,
+ usePadding, srcIdx, dstIdx);
+ }
+
+ srcLineStartIdx += src.getRowStride();
+ srcLineEndIdx += src.getRowStride();
+ dstLineStartIdx += dst.getRowStride();
+ }
- if (y < 0) {
- startLine = -y;
- y = 0;
- srcStartIdx += src.getRowStride();
- srcEndIdx += src.getRowStride();
- } else if (y + src.getHeight() > dst.getHeight()) {
- startLine = src.getHeight() + y - dst.getHeight();
+ return dst;
}
- final int shiftVal1 = x & 0x07;
- final int shiftVal2 = 8 - shiftVal1;
-
- final int padding = src.getWidth() & 0x07;
- final int toShift = shiftVal2 - padding;
-
- final boolean useShift = (shiftVal2 & 0x07) != 0;
- final boolean specialCase = src.getWidth() <= ((srcEndIdx - srcStartIdx) << 3) + shiftVal2;
+ private static void copyLine(Bitmap src, Bitmap dst, int sourceUpShift, int sourceDownShift,
+ int padding, int firstSourceByteOfLine, int lastSourceByteOfLine, boolean usePadding,
+ int sourceOffset, int targetOffset)
+ {
+ for (int x = firstSourceByteOfLine; x < lastSourceByteOfLine; x++)
+ {
+
+ if (sourceOffset + 1 < src.getByteArray().length)
+ {
+ final boolean isLastByte = x + 1 == lastSourceByteOfLine;
+ byte value = (byte) (src.getByte(sourceOffset++) << sourceUpShift
+ | (src.getByte(sourceOffset) & 0xff) >>> sourceDownShift);
+
+ if (isLastByte && !usePadding)
+ {
+ value = unpad(padding, value);
+ }
+
+ dst.setByte(targetOffset++, value);
+
+ if (isLastByte && usePadding)
+ {
+ value = unpad(padding,
+ (byte) ((src.getByte(sourceOffset) & 0xff) << sourceUpShift));
+ dst.setByte(targetOffset, value);
+ }
+
+ }
+ else
+ {
+ final byte value = (byte) (src.getByte(sourceOffset++) << sourceUpShift & 0xff);
+ dst.setByte(targetOffset++, value);
+ }
+ }
+ }
- final int dstStartIdx = dst.getByteIndex(x, y);
+ /**
+ * Removes unnecessary bits from a byte.
+ *
+ * @param padding - The amount of unnecessary bits.
+ * @param value - The byte that should be cleaned up.
+ * @return A cleaned byte.
+ */
+ private static byte unpad(int padding, byte value)
+ {
+ return (byte) (value >> padding << padding);
+ }
- final int lastLine = Math.min(src.getHeight(), startLine + dst.getHeight());
+ public static Bitmap subsample(Bitmap src, ImageReadParam param)
+ {
+ if (src == null)
+ throw new IllegalArgumentException("src must not be null");
+
+ if (param == null)
+ throw new IllegalArgumentException("param must not be null");
+
+ final int xSubsampling = param.getSourceXSubsampling();
+ final int ySubsampling = param.getSourceYSubsampling();
+ final int xSubsamplingOffset = param.getSubsamplingXOffset();
+ final int ySubsamplingOffset = param.getSubsamplingYOffset();
+
+ final int dstWidth = (src.getWidth() - xSubsamplingOffset) / xSubsampling;
+ final int dstHeight = (src.getHeight() - ySubsamplingOffset) / ySubsampling;
+
+ final Bitmap dst = new Bitmap(dstWidth, dstHeight);
+
+ for (int yDst = 0, ySrc = ySubsamplingOffset; yDst < dst
+ .getHeight(); yDst++, ySrc += ySubsampling)
+ {
+ for (int xDst = 0, xSrc = xSubsamplingOffset; xDst < dst
+ .getWidth(); xDst++, xSrc += xSubsampling)
+ {
+ final byte pixel = src.getPixel(xSrc, ySrc);
+ if (pixel != 0)
+ dst.setPixel(xDst, yDst, pixel);
+ }
+ }
- if (!useShift) {
- blitUnshifted(src, dst, startLine, lastLine, dstStartIdx, srcStartIdx, srcEndIdx, combinationOperator);
- } else if (specialCase) {
- blitSpecialShifted(src, dst, startLine, lastLine, dstStartIdx, srcStartIdx, srcEndIdx, toShift, shiftVal1,
- shiftVal2, combinationOperator);
- } else {
- blitShifted(src, dst, startLine, lastLine, dstStartIdx, srcStartIdx, srcEndIdx, toShift, shiftVal1, shiftVal2,
- combinationOperator, padding);
+ return dst;
}
- }
- private static void blitUnshifted(Bitmap src, Bitmap dst, int startLine, int lastLine, int dstStartIdx,
- int srcStartIdx, int srcEndIdx, CombinationOperator op) {
-
- for (int dstLine = startLine; dstLine < lastLine; dstLine++, dstStartIdx += dst.getRowStride(), srcStartIdx += src.getRowStride(), srcEndIdx += src.getRowStride()) {
- int dstIdx = dstStartIdx;
+ public static Bitmap subsampleX(Bitmap src, final int xSubsampling,
+ final int xSubsamplingOffset)
+ {
+ if (src == null)
+ throw new IllegalArgumentException("src must not be null");
+
+ final int dstHeight = (src.getWidth() - xSubsamplingOffset) / xSubsampling;
+ final Bitmap dst = new Bitmap(src.getWidth(), dstHeight);
+
+ for (int yDst = 0; yDst < dst.getHeight(); yDst++)
+ {
+ for (int xDst = 0, xSrc = xSubsamplingOffset; xDst < dst
+ .getWidth(); xDst++, xSrc += xSubsampling)
+ {
+ final byte pixel = src.getPixel(xSrc, yDst);
+ if (pixel != 0)
+ dst.setPixel(xDst, yDst, pixel);
+ }
+ }
- // Go through the bytes in a line of the Symbol
- for (int srcIdx = srcStartIdx; srcIdx <= srcEndIdx; srcIdx++) {
- byte oldByte = dst.getByte(dstIdx);
- byte newByte = src.getByte(srcIdx);
- dst.setByte(dstIdx++, Bitmaps.combineBytes(oldByte, newByte, op));
- }
+ return dst;
}
- }
- private static void blitSpecialShifted(Bitmap src, Bitmap dst, int startLine, int lastLine, int dstStartIdx,
- int srcStartIdx, int srcEndIdx, int toShift, int shiftVal1, int shiftVal2, CombinationOperator op) {
+ public static Bitmap subsampleY(Bitmap src, final int ySubsampling,
+ final int ySubsamplingOffset)
+ {
+ if (src == null)
+ throw new IllegalArgumentException("src must not be null");
+
+ final int dstWidth = (src.getWidth() - ySubsamplingOffset) / ySubsampling;
+ final Bitmap dst = new Bitmap(dstWidth, src.getHeight());
+
+ for (int yDst = 0, ySrc = ySubsamplingOffset; yDst < dst
+ .getHeight(); yDst++, ySrc += ySubsampling)
+ {
+ for (int xDst = 0; xDst < dst.getWidth(); xDst++)
+ {
+ final byte pixel = src.getPixel(xDst, ySrc);
+ if (pixel != 0)
+ dst.setPixel(xDst, yDst, pixel);
+ }
+ }
- for (int dstLine = startLine; dstLine < lastLine; dstLine++, dstStartIdx += dst.getRowStride(), srcStartIdx += src.getRowStride(), srcEndIdx += src.getRowStride()) {
- short register = 0;
- int dstIdx = dstStartIdx;
+ return dst;
+ }
- // Go through the bytes in a line of the Symbol
- for (int srcIdx = srcStartIdx; srcIdx <= srcEndIdx; srcIdx++) {
- byte oldByte = dst.getByte(dstIdx);
- register = (short) ((register | src.getByte(srcIdx) & 0xff) << shiftVal2);
- byte newByte = (byte) (register >> 8);
+ /**
+ * The method combines two given bytes with an logical operator.
+ * <p>
+ * The JBIG2 Standard specifies 5 possible combinations of bytes.<br>
+ * <p>
+ * <b>Hint:</b> Please take a look at ISO/IEC 14492:2001 (E) for detailed definition and description of the
+ * operators.
+ *
+ * @param value1 - The value that should be combined with value2.
+ * @param value2 - The value that should be combined with value1.
+ * @param op - The specified combination operator.
+ *
+ * @return The combination result.
+ */
+ public static byte combineBytes(byte value1, byte value2, CombinationOperator op)
+ {
+
+ switch (op)
+ {
+ case OR:
+ return (byte) (value2 | value1);
+ case AND:
+ return (byte) (value2 & value1);
+ case XOR:
+ return (byte) (value2 ^ value1);
+ case XNOR:
+ return (byte) ~(value1 ^ value2);
+ case REPLACE:
+ default:
+ // Old value is replaced by new value.
+ return value2;
+ }
+ }
- if (srcIdx == srcEndIdx) {
- newByte = unpad(toShift, newByte);
+ /**
+ * This method combines a given bitmap with the current instance.
+ * <p>
+ * Parts of the bitmap to blit that are outside of the target bitmap will be ignored.
+ *
+ * @param src - The bitmap that should be combined with the one of the current instance.
+ * @param dst - The destination bitmap.
+ * @param x - The x coordinate where the upper left corner of the bitmap to blit should be positioned.
+ * @param y - The y coordinate where the upper left corner of the bitmap to blit should be positioned.
+ * @param combinationOperator - The combination operator for combining two pixels.
+ */
+ public static void blit(Bitmap src, Bitmap dst, int x, int y,
+ CombinationOperator combinationOperator)
+ {
+
+ int startLine = 0;
+ int srcStartIdx = 0;
+ int srcEndIdx = (src.getRowStride() - 1);
+
+ // Ignore those parts of the source bitmap which would be placed outside the target bitmap.
+ if (x < 0)
+ {
+ srcStartIdx = -x;
+ x = 0;
+ }
+ else if (x + src.getWidth() > dst.getWidth())
+ {
+ srcEndIdx -= (src.getWidth() + x - dst.getWidth());
}
- dst.setByte(dstIdx++, Bitmaps.combineBytes(oldByte, newByte, op));
- register <<= shiftVal1;
- }
- }
- }
+ if (y < 0)
+ {
+ startLine = -y;
+ y = 0;
+ srcStartIdx += src.getRowStride();
+ srcEndIdx += src.getRowStride();
+ }
+ else if (y + src.getHeight() > dst.getHeight())
+ {
+ startLine = src.getHeight() + y - dst.getHeight();
+ }
- private static void blitShifted(Bitmap src, Bitmap dst, int startLine, int lastLine, int dstStartIdx,
- int srcStartIdx, int srcEndIdx, int toShift, int shiftVal1, int shiftVal2, CombinationOperator op, int padding) {
+ final int shiftVal1 = x & 0x07;
+ final int shiftVal2 = 8 - shiftVal1;
- for (int dstLine = startLine; dstLine < lastLine; dstLine++, dstStartIdx += dst.getRowStride(), srcStartIdx += src.getRowStride(), srcEndIdx += src.getRowStride()) {
- short register = 0;
- int dstIdx = dstStartIdx;
+ final int padding = src.getWidth() & 0x07;
+ final int toShift = shiftVal2 - padding;
- // Go through the bytes in a line of the symbol
- for (int srcIdx = srcStartIdx; srcIdx <= srcEndIdx; srcIdx++) {
- byte oldByte = dst.getByte(dstIdx);
- register = (short) ((register | src.getByte(srcIdx) & 0xff) << shiftVal2);
+ final boolean useShift = (shiftVal2 & 0x07) != 0;
+ final boolean specialCase = src.getWidth() <= ((srcEndIdx - srcStartIdx) << 3) + shiftVal2;
- byte newByte = (byte) (register >> 8);
- dst.setByte(dstIdx++, Bitmaps.combineBytes(oldByte, newByte, op));
+ final int dstStartIdx = dst.getByteIndex(x, y);
- register <<= shiftVal1;
+ final int lastLine = Math.min(src.getHeight(), startLine + dst.getHeight());
- if (srcIdx == srcEndIdx) {
- newByte = (byte) (register >> (8 - shiftVal2));
+ if (!useShift)
+ {
+ blitUnshifted(src, dst, startLine, lastLine, dstStartIdx, srcStartIdx, srcEndIdx,
+ combinationOperator);
+ }
+ else if (specialCase)
+ {
+ blitSpecialShifted(src, dst, startLine, lastLine, dstStartIdx, srcStartIdx, srcEndIdx,
+ toShift, shiftVal1, shiftVal2, combinationOperator);
+ }
+ else
+ {
+ blitShifted(src, dst, startLine, lastLine, dstStartIdx, srcStartIdx, srcEndIdx, toShift,
+ shiftVal1, shiftVal2, combinationOperator, padding);
+ }
+ }
- if (padding != 0) {
- newByte = unpad(8 + toShift, newByte);
- }
+ private static void blitUnshifted(Bitmap src, Bitmap dst, int startLine, int lastLine,
+ int dstStartIdx, int srcStartIdx, int srcEndIdx, CombinationOperator op)
+ {
+
+ for (int dstLine = startLine; dstLine < lastLine; dstLine++, dstStartIdx += dst
+ .getRowStride(), srcStartIdx += src.getRowStride(), srcEndIdx += src.getRowStride())
+ {
+ int dstIdx = dstStartIdx;
+
+ // Go through the bytes in a line of the Symbol
+ for (int srcIdx = srcStartIdx; srcIdx <= srcEndIdx; srcIdx++)
+ {
+ byte oldByte = dst.getByte(dstIdx);
+ byte newByte = src.getByte(srcIdx);
+ dst.setByte(dstIdx++, Bitmaps.combineBytes(oldByte, newByte, op));
+ }
+ }
+ }
- oldByte = dst.getByte(dstIdx);
- dst.setByte(dstIdx, Bitmaps.combineBytes(oldByte, newByte, op));
+ private static void blitSpecialShifted(Bitmap src, Bitmap dst, int startLine, int lastLine,
+ int dstStartIdx, int srcStartIdx, int srcEndIdx, int toShift, int shiftVal1,
+ int shiftVal2, CombinationOperator op)
+ {
+
+ for (int dstLine = startLine; dstLine < lastLine; dstLine++, dstStartIdx += dst
+ .getRowStride(), srcStartIdx += src.getRowStride(), srcEndIdx += src.getRowStride())
+ {
+ short register = 0;
+ int dstIdx = dstStartIdx;
+
+ // Go through the bytes in a line of the Symbol
+ for (int srcIdx = srcStartIdx; srcIdx <= srcEndIdx; srcIdx++)
+ {
+ byte oldByte = dst.getByte(dstIdx);
+ register = (short) ((register | src.getByte(srcIdx) & 0xff) << shiftVal2);
+ byte newByte = (byte) (register >> 8);
+
+ if (srcIdx == srcEndIdx)
+ {
+ newByte = unpad(toShift, newByte);
+ }
+
+ dst.setByte(dstIdx++, Bitmaps.combineBytes(oldByte, newByte, op));
+ register <<= shiftVal1;
+ }
}
- }
}
- }
+ private static void blitShifted(Bitmap src, Bitmap dst, int startLine, int lastLine,
+ int dstStartIdx, int srcStartIdx, int srcEndIdx, int toShift, int shiftVal1,
+ int shiftVal2, CombinationOperator op, int padding)
+ {
+
+ for (int dstLine = startLine; dstLine < lastLine; dstLine++, dstStartIdx += dst
+ .getRowStride(), srcStartIdx += src.getRowStride(), srcEndIdx += src.getRowStride())
+ {
+ short register = 0;
+ int dstIdx = dstStartIdx;
+
+ // Go through the bytes in a line of the symbol
+ for (int srcIdx = srcStartIdx; srcIdx <= srcEndIdx; srcIdx++)
+ {
+ byte oldByte = dst.getByte(dstIdx);
+ register = (short) ((register | src.getByte(srcIdx) & 0xff) << shiftVal2);
+
+ byte newByte = (byte) (register >> 8);
+ dst.setByte(dstIdx++, Bitmaps.combineBytes(oldByte, newByte, op));
+
+ register <<= shiftVal1;
+
+ if (srcIdx == srcEndIdx)
+ {
+ newByte = (byte) (register >> (8 - shiftVal2));
+
+ if (padding != 0)
+ {
+ newByte = unpad(8 + toShift, newByte);
+ }
+
+ oldByte = dst.getByte(dstIdx);
+ dst.setByte(dstIdx, Bitmaps.combineBytes(oldByte, newByte, op));
+ }
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/image/Filter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/pdfbox/jbig2/image/Filter.java b/src/main/java/org/apache/pdfbox/jbig2/image/Filter.java
index 2b81957..bdcdad6 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/image/Filter.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/image/Filter.java
@@ -17,441 +17,512 @@
package org.apache.pdfbox.jbig2.image;
-
-abstract class Filter {
-
- /**
- * Find a filter name by its type.
- *
- * @param type the filter type
- * @return filter name
- */
- public static String nameByType(final FilterType type) {
- if (type == null)
- throw new IllegalArgumentException("type must not be null");
- return type.name();
- }
-
- /**
- * Find a filter type by its name.
- *
- * @param name the filter name
- * @return filter type
- */
- public static FilterType typeByName(final String name) {
- if (name == null)
- throw new IllegalArgumentException("name must not be null");
- return FilterType.valueOf(name);
- }
-
- /**
- * Find a filter by its type.
- *
- * @param type the filter type
- * @return the Filter
- */
- public static Filter byType(final FilterType type) {
- switch (type){
- case Bessel :
- return new Bessel();
- case Blackman :
- return new Blackman();
- case Box :
- return new Box();
- case Catrom :
- return new Catrom();
- case Cubic :
- return new Cubic();
- case Gaussian :
- return new Gaussian();
- case Hamming :
- return new Hamming();
- case Hanning :
- return new Hanning();
- case Hermite :
- return new Hermite();
- case Lanczos :
- return new Lanczos();
- case Mitchell :
- return new Mitchell();
- case Point :
- return new Point();
- case Quadratic :
- return new Quadratic();
- case Sinc :
- return new Sinc();
- case Triangle :
- return new Triangle();
- }
- throw new IllegalArgumentException("No filter for given type.");
- }
-
- public static final class Bessel extends Filter {
- public Bessel() {
- super(false, 3.2383, 1.0);
- }
-
- private double J1(final double x) {
- double p, q;
-
- int i;
-
- final double Pone[] = {
- 0.581199354001606143928050809e+21, -0.6672106568924916298020941484e+20, 0.2316433580634002297931815435e+19,
- -0.3588817569910106050743641413e+17, 0.2908795263834775409737601689e+15, -0.1322983480332126453125473247e+13,
- 0.3413234182301700539091292655e+10, -0.4695753530642995859767162166e+7, 0.270112271089232341485679099e+4
- }, Qone[] = {
- 0.11623987080032122878585294e+22, 0.1185770712190320999837113348e+20, 0.6092061398917521746105196863e+17,
- 0.2081661221307607351240184229e+15, 0.5243710262167649715406728642e+12, 0.1013863514358673989967045588e+10,
- 0.1501793594998585505921097578e+7, 0.1606931573481487801970916749e+4, 0.1e+1
- };
-
- p = Pone[8];
- q = Qone[8];
- for (i = 7; i >= 0; i--) {
- p = p * x * x + Pone[i];
- q = q * x * x + Qone[i];
- }
- return p / q;
- }
-
- private double P1(final double x) {
- double p, q;
-
- int i;
-
- final double Pone[] = {
- 0.352246649133679798341724373e+5, 0.62758845247161281269005675e+5, 0.313539631109159574238669888e+5,
- 0.49854832060594338434500455e+4, 0.2111529182853962382105718e+3, 0.12571716929145341558495e+1
- }, Qone[] = {
- 0.352246649133679798068390431e+5, 0.626943469593560511888833731e+5, 0.312404063819041039923015703e+5,
- 0.4930396490181088979386097e+4, 0.2030775189134759322293574e+3, 0.1e+1
- };
-
- p = Pone[5];
- q = Qone[5];
- for (i = 4; i >= 0; i--) {
- p = p * (8.0 / x) * (8.0 / x) + Pone[i];
- q = q * (8.0 / x) * (8.0 / x) + Qone[i];
- }
- return p / q;
- }
-
- private double Q1(final double x) {
- double p, q;
-
- int i;
-
- final double Pone[] = {
- 0.3511751914303552822533318e+3, 0.7210391804904475039280863e+3, 0.4259873011654442389886993e+3,
- 0.831898957673850827325226e+2, 0.45681716295512267064405e+1, 0.3532840052740123642735e-1
- }, Qone[] = {
- 0.74917374171809127714519505e+4, 0.154141773392650970499848051e+5, 0.91522317015169922705904727e+4,
- 0.18111867005523513506724158e+4, 0.1038187585462133728776636e+3, 0.1e+1
- };
-
- p = Pone[5];
- q = Qone[5];
- for (i = 4; i >= 0; i--) {
- p = p * (8.0 / x) * (8.0 / x) + Pone[i];
- q = q * (8.0 / x) * (8.0 / x) + Qone[i];
- }
- return p / q;
- }
-
- private double BesselOrderOne(double x) {
- double p, q;
-
- if (x == 0.0)
- return 0.0;
- p = x;
- if (x < 0.0)
- x = -x;
- if (x < 8.0)
- return p * J1(x);
- q = Math.sqrt(2.0 / (Math.PI * x))
- * (P1(x) * (1.0 / Math.sqrt(2.0) * (Math.sin(x) - Math.cos(x))) - 8.0 / x * Q1(x)
- * (-1.0 / Math.sqrt(2.0) * (Math.sin(x) + Math.cos(x))));
- if (p < 0.0)
- q = -q;
- return q;
- }
-
- @Override
- public double f(final double x) {
- if (x == 0.0)
- return Math.PI / 4.0;
- return BesselOrderOne(Math.PI * x) / (2.0 * x);
- }
- }
-
- public static final class Blackman extends Filter {
- @Override
- public double f(final double x) {
- return 0.42 + 0.50 * Math.cos(Math.PI * x) + 0.08 * Math.cos(2.0 * Math.PI * x);
- }
- }
-
- public static class Box extends Filter {
- public Box() {
- super(true, .5, 1.0);
- }
-
- public Box(final double supp) {
- super(true, supp, 1.0);
- }
-
- @Override
- public double f(final double x) {
- if (x >= -0.5 && x < 0.5)
- return 1.0;
- return 0.0;
- }
- }
-
- public static final class Point extends Box {
- public Point() {
- super(0);
- }
-
- @Override
- public double fWindowed(double x) {
- // don't apply windowing as we have a radius of zero.
- return super.f(x);
- }
- }
-
- public static final class Catrom extends Filter {
- public Catrom() {
- super(true, 2.0, 1.0);
- }
-
- @Override
- public double f(double x) {
- if (x < 0)
- x = -x;
- if (x < 1.0)
- return 0.5 * (2.0 + x * x * (-5.0 + x * 3.0));
- if (x < 2.0)
- return 0.5 * (4.0 + x * (-8.0 + x * (5.0 - x)));
- return 0.0;
- }
- }
-
- public static final class Cubic extends Filter {
- public Cubic() {
- super(false, 2.0, 1.0);
- }
-
- @Override
- public double f(double x) {
- if (x < 0)
- x = -x;
- if (x < 1.0)
- return 0.5 * x * x * x - x * x + 2.0 / 3.0;
- if (x < 2.0) {
- x = 2.0 - x;
- return 1.0 / 6.0 * x * x * x;
- }
- return 0.0;
- }
- }
-
- public static final class Gaussian extends Filter {
- public Gaussian() {
- super(false, 1.25, 1.0);
- }
-
- @Override
- public double f(final double x) {
- return Math.exp(-2.0 * x * x) * Math.sqrt(2.0 / Math.PI);
- }
- }
-
- public static final class Hamming extends Filter {
- @Override
- public double f(final double x) {
- return 0.54 + 0.46 * Math.cos(Math.PI * x);
- }
- }
-
- public static final class Hanning extends Filter {
- @Override
- public double f(final double x) {
- return 0.5 + 0.5 * Math.cos(Math.PI * x);
- }
- }
-
- public static final class Hermite extends Filter {
- @Override
- public double f(double x) {
- if (x < 0) {
- x = -x;
- }
-
- if (x < 1.0) {
- return (2.0 * x - 3.0) * x * x + 1.0;
- }
- return 0.0;
- }
- }
-
- public static final class Lanczos extends Filter {
- public Lanczos() {
- super(true, 3.0, 1.0);
- }
-
- @Override
- public double f(double x) {
- if (x < 0)
- x = -x;
- if (x < 3.0)
- return (float) (sinc(x) * sinc(x / 3.0));
- return 0.0;
- }
-
- private double sinc(double value) {
- if (value != 0.0f) {
- value = value * Math.PI;
- return Math.sin(value) / value;
- } else {
- return 1.0;
- }
- }
-
- }
-
- public static final class Mitchell extends Filter {
- public Mitchell() {
- super(false, 2.0, 1.0);
- }
-
- @Override
- public double f(double x) {
- double b, c;
-
- b = 1.0 / 3.0;
- c = 1.0 / 3.0;
- if (x < 0)
- x = -x;
- if (x < 1.0) {
- x = (12.0 - 9.0 * b - 6.0 * c) * (x * x * x) + (-18.0 + 12.0 * b + 6.0 * c) * x * x + (6.0 - 2.0 * b);
- return x / 6.0;
- }
- if (x < 2.0) {
- x = (-1.0 * b - 6.0 * c) * (x * x * x) + (6.0 * b + 30.0 * c) * x * x + (-12.0 * b - 48.0 * c) * x
- + (8.0 * b + 24.0 * c);
- return x / 6.0;
- }
- return 0.0;
- }
- }
-
- public static final class Quadratic extends Filter {
- public Quadratic() {
- super(false, 1.5, 1.0);
- }
-
- @Override
- public double f(double x) {
- if (x < 0)
- x = -x;
- if (x < 0.5)
- return 0.75 - x * x;
- if (x < 1.5) {
- x -= 1.5;
- return 0.5 * x * x;
- }
- return 0.0;
- }
- }
-
- public static final class Sinc extends Filter {
- public Sinc() {
- super(true, 4.0, 1.0);
- }
-
- @Override
- public double f(double x) {
- x *= Math.PI;
- if (x != 0.0)
- return Math.sin(x) / x;
- return 1.0;
- }
- }
-
- public static final class Triangle extends Filter {
- @Override
- public double f(double x) {
- if (x < 0.0)
- x = -x;
- if (x < 1.0)
- return 1.0 - x;
- return 0.0;
+abstract class Filter
+{
+
+ /**
+ * Find a filter name by its type.
+ *
+ * @param type the filter type
+ * @return filter name
+ */
+ public static String nameByType(final FilterType type)
+ {
+ if (type == null)
+ throw new IllegalArgumentException("type must not be null");
+ return type.name();
+ }
+
+ /**
+ * Find a filter type by its name.
+ *
+ * @param name the filter name
+ * @return filter type
+ */
+ public static FilterType typeByName(final String name)
+ {
+ if (name == null)
+ throw new IllegalArgumentException("name must not be null");
+ return FilterType.valueOf(name);
+ }
+
+ /**
+ * Find a filter by its type.
+ *
+ * @param type the filter type
+ * @return the Filter
+ */
+ public static Filter byType(final FilterType type)
+ {
+ switch (type)
+ {
+ case Bessel:
+ return new Bessel();
+ case Blackman:
+ return new Blackman();
+ case Box:
+ return new Box();
+ case Catrom:
+ return new Catrom();
+ case Cubic:
+ return new Cubic();
+ case Gaussian:
+ return new Gaussian();
+ case Hamming:
+ return new Hamming();
+ case Hanning:
+ return new Hanning();
+ case Hermite:
+ return new Hermite();
+ case Lanczos:
+ return new Lanczos();
+ case Mitchell:
+ return new Mitchell();
+ case Point:
+ return new Point();
+ case Quadratic:
+ return new Quadratic();
+ case Sinc:
+ return new Sinc();
+ case Triangle:
+ return new Triangle();
+ }
+ throw new IllegalArgumentException("No filter for given type.");
+ }
+
+ public static final class Bessel extends Filter
+ {
+ public Bessel()
+ {
+ super(false, 3.2383, 1.0);
+ }
+
+ private double J1(final double x)
+ {
+ double p, q;
+
+ int i;
+
+ final double Pone[] = { 0.581199354001606143928050809e+21,
+ -0.6672106568924916298020941484e+20, 0.2316433580634002297931815435e+19,
+ -0.3588817569910106050743641413e+17, 0.2908795263834775409737601689e+15,
+ -0.1322983480332126453125473247e+13, 0.3413234182301700539091292655e+10,
+ -0.4695753530642995859767162166e+7, 0.270112271089232341485679099e+4 },
+ Qone[] = { 0.11623987080032122878585294e+22, 0.1185770712190320999837113348e+20,
+ 0.6092061398917521746105196863e+17, 0.2081661221307607351240184229e+15,
+ 0.5243710262167649715406728642e+12, 0.1013863514358673989967045588e+10,
+ 0.1501793594998585505921097578e+7, 0.1606931573481487801970916749e+4,
+ 0.1e+1 };
+
+ p = Pone[8];
+ q = Qone[8];
+ for (i = 7; i >= 0; i--)
+ {
+ p = p * x * x + Pone[i];
+ q = q * x * x + Qone[i];
+ }
+ return p / q;
+ }
+
+ private double P1(final double x)
+ {
+ double p, q;
+
+ int i;
+
+ final double Pone[] = { 0.352246649133679798341724373e+5,
+ 0.62758845247161281269005675e+5, 0.313539631109159574238669888e+5,
+ 0.49854832060594338434500455e+4, 0.2111529182853962382105718e+3,
+ 0.12571716929145341558495e+1 },
+ Qone[] = { 0.352246649133679798068390431e+5, 0.626943469593560511888833731e+5,
+ 0.312404063819041039923015703e+5, 0.4930396490181088979386097e+4,
+ 0.2030775189134759322293574e+3, 0.1e+1 };
+
+ p = Pone[5];
+ q = Qone[5];
+ for (i = 4; i >= 0; i--)
+ {
+ p = p * (8.0 / x) * (8.0 / x) + Pone[i];
+ q = q * (8.0 / x) * (8.0 / x) + Qone[i];
+ }
+ return p / q;
+ }
+
+ private double Q1(final double x)
+ {
+ double p, q;
+
+ int i;
+
+ final double Pone[] = { 0.3511751914303552822533318e+3, 0.7210391804904475039280863e+3,
+ 0.4259873011654442389886993e+3, 0.831898957673850827325226e+2,
+ 0.45681716295512267064405e+1, 0.3532840052740123642735e-1 },
+ Qone[] = { 0.74917374171809127714519505e+4, 0.154141773392650970499848051e+5,
+ 0.91522317015169922705904727e+4, 0.18111867005523513506724158e+4,
+ 0.1038187585462133728776636e+3, 0.1e+1 };
+
+ p = Pone[5];
+ q = Qone[5];
+ for (i = 4; i >= 0; i--)
+ {
+ p = p * (8.0 / x) * (8.0 / x) + Pone[i];
+ q = q * (8.0 / x) * (8.0 / x) + Qone[i];
+ }
+ return p / q;
+ }
+
+ private double BesselOrderOne(double x)
+ {
+ double p, q;
+
+ if (x == 0.0)
+ return 0.0;
+ p = x;
+ if (x < 0.0)
+ x = -x;
+ if (x < 8.0)
+ return p * J1(x);
+ q = Math.sqrt(2.0 / (Math.PI * x))
+ * (P1(x) * (1.0 / Math.sqrt(2.0) * (Math.sin(x) - Math.cos(x))) - 8.0 / x
+ * Q1(x) * (-1.0 / Math.sqrt(2.0) * (Math.sin(x) + Math.cos(x))));
+ if (p < 0.0)
+ q = -q;
+ return q;
+ }
+
+ @Override
+ public double f(final double x)
+ {
+ if (x == 0.0)
+ return Math.PI / 4.0;
+ return BesselOrderOne(Math.PI * x) / (2.0 * x);
+ }
+ }
+
+ public static final class Blackman extends Filter
+ {
+ @Override
+ public double f(final double x)
+ {
+ return 0.42 + 0.50 * Math.cos(Math.PI * x) + 0.08 * Math.cos(2.0 * Math.PI * x);
+ }
+ }
+
+ public static class Box extends Filter
+ {
+ public Box()
+ {
+ super(true, .5, 1.0);
+ }
+
+ public Box(final double supp)
+ {
+ super(true, supp, 1.0);
+ }
+
+ @Override
+ public double f(final double x)
+ {
+ if (x >= -0.5 && x < 0.5)
+ return 1.0;
+ return 0.0;
+ }
+ }
+
+ public static final class Point extends Box
+ {
+ public Point()
+ {
+ super(0);
+ }
+
+ @Override
+ public double fWindowed(double x)
+ {
+ // don't apply windowing as we have a radius of zero.
+ return super.f(x);
+ }
+ }
+
+ public static final class Catrom extends Filter
+ {
+ public Catrom()
+ {
+ super(true, 2.0, 1.0);
+ }
+
+ @Override
+ public double f(double x)
+ {
+ if (x < 0)
+ x = -x;
+ if (x < 1.0)
+ return 0.5 * (2.0 + x * x * (-5.0 + x * 3.0));
+ if (x < 2.0)
+ return 0.5 * (4.0 + x * (-8.0 + x * (5.0 - x)));
+ return 0.0;
+ }
+ }
+
+ public static final class Cubic extends Filter
+ {
+ public Cubic()
+ {
+ super(false, 2.0, 1.0);
+ }
+
+ @Override
+ public double f(double x)
+ {
+ if (x < 0)
+ x = -x;
+ if (x < 1.0)
+ return 0.5 * x * x * x - x * x + 2.0 / 3.0;
+ if (x < 2.0)
+ {
+ x = 2.0 - x;
+ return 1.0 / 6.0 * x * x * x;
+ }
+ return 0.0;
+ }
+ }
+
+ public static final class Gaussian extends Filter
+ {
+ public Gaussian()
+ {
+ super(false, 1.25, 1.0);
+ }
+
+ @Override
+ public double f(final double x)
+ {
+ return Math.exp(-2.0 * x * x) * Math.sqrt(2.0 / Math.PI);
+ }
+ }
+
+ public static final class Hamming extends Filter
+ {
+ @Override
+ public double f(final double x)
+ {
+ return 0.54 + 0.46 * Math.cos(Math.PI * x);
+ }
+ }
+
+ public static final class Hanning extends Filter
+ {
+ @Override
+ public double f(final double x)
+ {
+ return 0.5 + 0.5 * Math.cos(Math.PI * x);
+ }
+ }
+
+ public static final class Hermite extends Filter
+ {
+ @Override
+ public double f(double x)
+ {
+ if (x < 0)
+ {
+ x = -x;
+ }
+
+ if (x < 1.0)
+ {
+ return (2.0 * x - 3.0) * x * x + 1.0;
+ }
+ return 0.0;
+ }
+ }
+
+ public static final class Lanczos extends Filter
+ {
+ public Lanczos()
+ {
+ super(true, 3.0, 1.0);
+ }
+
+ @Override
+ public double f(double x)
+ {
+ if (x < 0)
+ x = -x;
+ if (x < 3.0)
+ return (float) (sinc(x) * sinc(x / 3.0));
+ return 0.0;
+ }
+
+ private double sinc(double value)
+ {
+ if (value != 0.0f)
+ {
+ value = value * Math.PI;
+ return Math.sin(value) / value;
+ }
+ else
+ {
+ return 1.0;
+ }
+ }
+
+ }
+
+ public static final class Mitchell extends Filter
+ {
+ public Mitchell()
+ {
+ super(false, 2.0, 1.0);
+ }
+
+ @Override
+ public double f(double x)
+ {
+ double b, c;
+
+ b = 1.0 / 3.0;
+ c = 1.0 / 3.0;
+ if (x < 0)
+ x = -x;
+ if (x < 1.0)
+ {
+ x = (12.0 - 9.0 * b - 6.0 * c) * (x * x * x) + (-18.0 + 12.0 * b + 6.0 * c) * x * x
+ + (6.0 - 2.0 * b);
+ return x / 6.0;
+ }
+ if (x < 2.0)
+ {
+ x = (-1.0 * b - 6.0 * c) * (x * x * x) + (6.0 * b + 30.0 * c) * x * x
+ + (-12.0 * b - 48.0 * c) * x + (8.0 * b + 24.0 * c);
+ return x / 6.0;
+ }
+ return 0.0;
+ }
+ }
+
+ public static final class Quadratic extends Filter
+ {
+ public Quadratic()
+ {
+ super(false, 1.5, 1.0);
+ }
+
+ @Override
+ public double f(double x)
+ {
+ if (x < 0)
+ x = -x;
+ if (x < 0.5)
+ return 0.75 - x * x;
+ if (x < 1.5)
+ {
+ x -= 1.5;
+ return 0.5 * x * x;
+ }
+ return 0.0;
+ }
+ }
+
+ public static final class Sinc extends Filter
+ {
+ public Sinc()
+ {
+ super(true, 4.0, 1.0);
+ }
+
+ @Override
+ public double f(double x)
+ {
+ x *= Math.PI;
+ if (x != 0.0)
+ return Math.sin(x) / x;
+ return 1.0;
+ }
+ }
+
+ public static final class Triangle extends Filter
+ {
+ @Override
+ public double f(double x)
+ {
+ if (x < 0.0)
+ x = -x;
+ if (x < 1.0)
+ return 1.0 - x;
+ return 0.0;
+ }
+ }
+
+ /**
+ * is this filter cardinal? ie, does func(x) = (x==0) for integer x?
+ */
+ final boolean cardinal;
+
+ /** radius of nonzero portion */
+ double support;
+
+ /** blur factor (1=normal) */
+ double blur;
+
+ protected Filter()
+ {
+ this(true, 1.0, 1.0);
+ }
+
+ protected Filter(final boolean cardinal, final double support, final double blur)
+ {
+ this.cardinal = cardinal;
+ this.support = support;
+ this.blur = blur;
+ }
+
+ public double fWindowed(double x)
+ {
+ return x < -support || x > support ? 0 : f(x);
+ }
+
+ public abstract double f(double x);
+
+ /**
+ * Return the filter name.
+ *
+ * @return the filter's name
+ */
+ public String getName()
+ {
+ return getClass().getSimpleName();
+ }
+
+ /**
+ * @return the support
+ */
+ public double getSupport()
+ {
+ return support;
+ }
+
+ /**
+ * @param support the support to set
+ */
+ public void setSupport(final double support)
+ {
+ this.support = support;
+ }
+
+ /**
+ * @return the blur
+ */
+ public double getBlur()
+ {
+ return blur;
+ }
+
+ /**
+ * @param blur the blur to set
+ */
+ public void setBlur(final double blur)
+ {
+ this.blur = blur;
}
- }
-
- /**
- * is this filter cardinal? ie, does func(x) = (x==0) for integer x?
- */
- final boolean cardinal;
-
- /** radius of nonzero portion */
- double support;
-
- /** blur factor (1=normal) */
- double blur;
-
- protected Filter() {
- this(true, 1.0, 1.0);
- }
-
- protected Filter(final boolean cardinal, final double support, final double blur) {
- this.cardinal = cardinal;
- this.support = support;
- this.blur = blur;
- }
-
- public double fWindowed(double x) {
- return x < -support || x > support ? 0 : f(x);
- }
-
- public abstract double f(double x);
-
- /**
- * Return the filter name.
- *
- * @return the filter's name
- */
- public String getName() {
- return getClass().getSimpleName();
- }
-
- /**
- * @return the support
- */
- public double getSupport() {
- return support;
- }
-
- /**
- * @param support the support to set
- */
- public void setSupport(final double support) {
- this.support = support;
- }
-
- /**
- * @return the blur
- */
- public double getBlur() {
- return blur;
- }
-
- /**
- * @param blur the blur to set
- */
- public void setBlur(final double blur) {
- this.blur = blur;
- }
}
http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/image/FilterType.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/pdfbox/jbig2/image/FilterType.java b/src/main/java/org/apache/pdfbox/jbig2/image/FilterType.java
index 1420726..6d3e0e2 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/image/FilterType.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/image/FilterType.java
@@ -17,34 +17,22 @@
package org.apache.pdfbox.jbig2.image;
-
/**
* A FilterType enum for defining certain downscale filters to apply.
*/
-public enum FilterType {
- Bessel,
- Blackman,
- Box,
- Catrom,
- Cubic,
- Gaussian,
- Hamming,
- Hanning,
- Hermite,
- Lanczos,
- Mitchell,
- Point,
- Quadratic,
- Sinc,
- Triangle;
+public enum FilterType
+{
+ Bessel, Blackman, Box, Catrom, Cubic, Gaussian, Hamming, Hanning, Hermite, Lanczos, Mitchell, Point, Quadratic, Sinc, Triangle;
- private static FilterType defaultFilter = Triangle;
+ private static FilterType defaultFilter = Triangle;
- public static void setDefaultFilterType(FilterType defaultFilter) {
- FilterType.defaultFilter = defaultFilter;
- }
+ public static void setDefaultFilterType(FilterType defaultFilter)
+ {
+ FilterType.defaultFilter = defaultFilter;
+ }
- public static FilterType getDefaultFilterType() {
- return defaultFilter;
- }
-}
\ No newline at end of file
+ public static FilterType getDefaultFilterType()
+ {
+ return defaultFilter;
+ }
+}
http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/image/ParameterizedFilter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/pdfbox/jbig2/image/ParameterizedFilter.java b/src/main/java/org/apache/pdfbox/jbig2/image/ParameterizedFilter.java
index bc32755..e801296 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/image/ParameterizedFilter.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/image/ParameterizedFilter.java
@@ -19,51 +19,56 @@ package org.apache.pdfbox.jbig2.image;
import org.apache.pdfbox.jbig2.util.Utils;
-class ParameterizedFilter {
- public ParameterizedFilter(final Filter f, final double scale) {
- filter = f;
- /*
- * find scale of filter in a space (source space) when minifying, ascale=1/scale, but when
- * magnifying, ascale=1
- */
- this.scale = f.blur * Math.max(1., 1. / scale);
+class ParameterizedFilter
+{
+ public ParameterizedFilter(final Filter f, final double scale)
+ {
+ filter = f;
+ /*
+ * find scale of filter in a space (source space) when minifying, ascale=1/scale, but when magnifying, ascale=1
+ */
+ this.scale = f.blur * Math.max(1., 1. / scale);
- /*
- * find support radius of scaled filter if ax.supp and ay.supp are both <=.5 then we've got
- * point sampling. Point sampling is essentially a special filter whose width is fixed at one
- * source pixel.
- */
- support = Math.max(.5, this.scale * f.support);
- width = (int) Math.ceil(2. * support);
- }
+ /*
+ * find support radius of scaled filter if ax.supp and ay.supp are both <=.5 then we've got point sampling.
+ * Point sampling is essentially a special filter whose width is fixed at one source pixel.
+ */
+ support = Math.max(.5, this.scale * f.support);
+ width = (int) Math.ceil(2. * support);
+ }
- public ParameterizedFilter(final Filter f, final double scale, final double support, final int width) {
- filter = f;
- this.scale = scale;
- this.support = support;
- this.width = width;
- }
+ public ParameterizedFilter(final Filter f, final double scale, final double support,
+ final int width)
+ {
+ filter = f;
+ this.scale = scale;
+ this.support = support;
+ this.width = width;
+ }
- final Filter filter;
+ final Filter filter;
- /* filter scale (spacing between centers in a space) */
- final double scale;
+ /* filter scale (spacing between centers in a space) */
+ final double scale;
- /* scaled filter support radius */
- final double support;
+ /* scaled filter support radius */
+ final double support;
- /* filter width: max number of nonzero samples */
- final int width;
+ /* filter width: max number of nonzero samples */
+ final int width;
- public double eval(double center, int i) {
- return filter.fWindowed((i + .5 - center) / scale);
- }
+ public double eval(double center, int i)
+ {
+ return filter.fWindowed((i + .5 - center) / scale);
+ }
- public int minIndex(double center) {
- return Utils.floor(center - support);
- }
+ public int minIndex(double center)
+ {
+ return Utils.floor(center - support);
+ }
- public int maxIndex(double center) {
- return Utils.ceil(center + support);
- }
-}
\ No newline at end of file
+ public int maxIndex(double center)
+ {
+ return Utils.ceil(center + support);
+ }
+}